Visual Scripting – Sorting things out

Before I am able to place vegetation on the terrain I need to know the slope angle at each point so I can determine whether it is too steep or what kind of plants i want to appear in those circumstances. I could get the tangent/normal data from the FRawMesh from last week however i that would require removing duplicates again which would be both slow and I could become a pain if they don’t match up after the sorting process. I decided to go the easier route and calculate them by sampling the adjacent points.

The first issue is that blueprints only support 1D arrays but i need to address elements with 2D Coordinates, To help with this i wrote a macro that uses the formula i = y * width + x which will do just that.


To test that it worked I set the cube at that index to a red material, sadly I do not have a screenshot of this but there were red cubes.


In the testing, the cubes at (0, 0) and (width, height) were in the correct positions in the array; however, due to the way I was removing the duplicate vertices, they were not all sorted causing some rows to be jumbled with the next. I changed the debug cube to also have a Text Renderer that I show the position in the array on.


My original instinct was to implement my own sorting algorithm in blueprint or C++, in theory i would be able to use the same indexing formula as my comparison for checking, however this would be very time consuming. Instead i found that TArray already has the function TArray::Sort() so I wrote a C++ function that would use it and return the sorted array.

TArray UMyFunctionLibrary::Sort(TArray points)
    // use TArray::Sort using my predicate to sort the array
    return points;

// Function that TArray::Sort can use to compare FVectors
bool UMyFunctionLibrary::SortPredicate(const FVector & a, const FVector & b)
    if (a.Y < b.Y)
        // if a's y is less we know it has to be before b
        return true;
    else if (a.Y == b.Y && a.X < b.X)
        // if they're at equal y, if a's x is less than b's x, true
        return true;
        // else b is before a
        return false;

It’s worth noting that for simplicity’s sake I used multiple if statements in my predicate function and not the more elegant formula. It is possible that using the formula could be faster but it was quicker to write and is more easily read when using this solution.


Here you can see the successfully sorted array, ready for me to start calculating the slope data.

Group Project Dev Log – 09/02/2018

This week has been productive; all tasks have been completed on time and effective sprint planning and daily scrums have kept the project on track. Some tasks had underestimated story points assigned to them, an example would be Issue #26 as it took longer to complete than expected as i had wasted time attacking the problem from the wrong angle.

Feedback from the art doc was good, I am confident that my vision is well defined in the Style Guide and that the asset list is concise. No art has been completed this week due to time constraints on the artist however it is scheduled to be completed over the weekend.

I worked on fixing/completing the Loop Detection code, Previously it was inconsistent and unfair however now it works better and allows for a the grace period to be after the song too, allowing the player to be slightly late and still register the tap as looping.

Next week I will be continuing the daily scrums with my course leader (producer), I will be adding in the new artwork as it rolls in. Top priority is starting the process of attaining the rights to use the music in the game. Finally I will be adding the analytics functionality into the project as well as implementing Ads.

Sprint 3


Group Project Dev Log – 06/02/2018

This week I found an artist interested in working on the game so I started both a Visual Design Document and Asset list for her to work on.

Now I have a better idea of what I would like the game together I have created a new scene with placeholder artwork ready to replace with the final artwork when it rolls in.

Next Week I am continuing to work on the Visual Design Document / Asset List and finishing the User Stories on the Core Game Loop.

Sprint 2


Optimising The Debug Cubes

As I mentioned in the last post, Spawning cubes using the Vertex list was very slow at the higher detail levels due to there being multiple vertices overlapping, such is the nature of meshes. I Will likely not be using the raw vertices for very long however as a small exercise I wrote a small function to remove duplicate vectors from the array, and the results were very successful.

The function runs through all of the vectors in the input array, Checks whether the new array already contains it, if not it gets added to the new list. The new list is then returned.


I also tidied up the level blueprint when adding in the new function by using a sequence, this serves no purpose other than to make the code look nicer and easier to read. I also added a “Print Text” node to write the number of vectors in the list to the screen.


Firstly I ran the level with the optimisation node disconnected so that I could see both how long it took to run and note down the number of vectors, Then I reconnected the node and ran again, taking note of the number of vectors.

The results were really impressive, Without the optimisation it took ages to start the level and it was incredibly laggy, this was down to the 55,296 cubes that were spawned in, many of which were overlapping each other. With the optimisation it started almost immediately with only a little frame lag and an impressive 9,409 cubes spawned. I will also make it clear that there were the same number of cubes visible so I had only removed duplicate cubes.

Unreal 4 Custom Terrain Node

A Brief Introduction

This week I started work on creating the custom nodes I need in Unreal Engine 4 to create my procedural vegetation tool.
UE4’s documentation is well none for being lacking however when it comes to creating custom blueprint nodes it is exceptionally more difficult to find useful information on the subject and I spent many hours banging my head against a brick wall getting nowhere.

My goal for this week was somehow getting access to the data contained within the Landscape class, as this is not possible to do with blueprints I had to look into custom node creation, which in Unreal engine is called a Blueprint Function Library.

Writing a custom node in C++

You can create a Blueprint Function Library by right clicking in the content browser, selecting “New C++ Class…” and selecting “Blueprint Function Library”.

When Writing a custom node you must put UFUNCTION() before your function, in this you can define how the blueprint editor will see your node, name it and define various keywords for searching. Blueprint functions must all be public and static.


What I have gathered so far is that pins are assigned as the parameters in the function signature; Pointers and Variables are inputs, References and the return type are outputs (if not void). I want to take in the Landscape object, an int to use as the level of detail for exporting the mesh and to return an array of vectors for the vertices, the function parameters are as follows:
ALandscape * landscape, int sampleLod, TArray &amp; points

The documentation shows that the parent class of a landscape actor(ALandscape) is ALandscapeProxy which has the functionality to export the mesh data to an FRawMesh struct so I added an include for “Developer/RawMesh/Public/RawMesh.h”. The RawMesh struct is not available in Blueprints so I use the points referance, I set it to the vertex array in the raw mesh.


An important point that is missing from the documentation is that you have to manually add modules to the .build.cs file for the linker to actually link the various libraries that the RawMesh and Landscape classes are in. This is done by adding the module names to this line in the build file:
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "RawMesh", "Landscape" });
I assume that the module names are the same as the header files that you include like they were in my case however I do not know as the documentation surrounding the build system is very complicated.

Finished Code

Here’s my finished code:

// in Header
UFUNCTION(BlueprintPure, DisplayName = "Get Landscape Stuff", Category = "Landscape Helpers")
static void GetMesh(ALandscape * landscape, int sampleLod, TArray & points);

// in Cpp
void UMyFunctionLibrary::GetMesh(ALandscape * landscape, int sampleLod, TArray & points)
// Raw mesh structure we'll export to
FRawMesh rawMesh;
// Export the landscape to the Raw Mesh using the supplied LOD
// Higher number means lower detail, less points (faster to demo with cubes)
landscape->ExportToRawMesh(sampleLod, rawMesh);
// Finally put the vertex positions in the raw mesh to the points array referance
points = rawMesh.VertexPositions;

It is important to note that the Editor must be restarted after compiling a custom node for it to show up in the blueprint editor, this can be time consuming and the docs do not mention it but if you are unable to fund your nodes or they are not showing the right pins, try restarting the editor.

Here’s my node in the blueprint editor:

To check that I was getting the correct data I spawned a cube at each point in the array, This is very slow when using the lower LOD value, this is because the vertices are per face, in theory meaning that all vertices are duplicated 8 times (not including on the edges of the terrain, however here’s the node setup:


This gave the following render, a successful result.