Assignment Goals

The primary goals of this assignment are:

  1. Create a UE4 Plugin.
  2. Extend the Blueprint system.
  3. Create and use a blue noise point distribution

For this assignment, you'll be creating a new Blueprint node in a UE4 plugin. The UE4 plugin system is a flexible way to do a fairly wide range of engine extensions without editing the core engine code. The kinds of things you can do include adding new asset types, creating asset importers for new file formats, adding editor modes or functionality, supporting new input devices or displays, and, of course, creating new Blueprint nodes.

In this case, we'll create a new Blueprint type to hold data about a blue noise point distribution generated using Mitchell's best candidate algorithm. You'll also create a Blueprint node to generate an object of this new type, and one to return a point location from it. You'll also create a simple Blueprint script to place some objects using this blue noise point distribution.

To summarize Mitchell's algorithm, you first place one point at a random x/y location. At each step, select several candidate points and keep the one furthest from any already placed points. The linked page suggests choosing a set of candidate points at each iteration proportional to the number of points placed so far. If you naively loop through all of the already placed points to find the distances for each candidate, the resulting algorithm to generate N points will run in O(N3) time

Details

For this assignment, I've gone a bit more general with the steps, though I have given some pointers for where to find examples of code similar to what you will need to write.

Create a project

  1. Create a Basic Code C++ project (with no starter content) called assn3, and a level called "assn3".
    • As usual, put it at the top level of your git repository

Create a Blueprint test case

  1. Create a Blueprint actor with three variables, an integer random seed, a number of elements to spawn, and a hidden RandomStream variable.
    • When you create a variable, you can change its type (and allowable range and other attributes) in the panel on the right
    • Click the closed eye icon next to the variable name in the variable list to have it show as a changeable parameter in the editor details window. Otherwise, it is considered a hidden local variable.
  2. In the Construction script
    1. Initialize the RandomStream given the seed.
    2. Add an InstancedStaticMeshComponent
      • This is a more efficient way to draw many of the same thing than individual StaticMeshComponents
      • The AddInstancedStaticMeshComponent Blueprint node will let you choose a static mesh and material to use
      • You can choose any static mesh and material you want, either one already available or by making something new
    3. Loop for the number of elements
    4. On each iteration, create a transform from a random X/Y from the RandomStream, and use AddInstance to add a copy at that location
      • Random numbers can be clumpy and pack objects too closely. This is why it is common to use something like a blue noise distribution for placement of things like trees or vegetation.
Randomly placed trees Blue-noise-distributed trees
Randomly distributed objects Blue-noise distributed objects

Create a Blueprint plugin

  1. In Settings > Plugins, create a new Blueprint plugin
  2. Restart UE4 to load the plugin for the first time
  3. Once loaded, you can recompile and hot-reload from Windows > Developer > Modules > (find your plugin in the list) > Recompile
    • The editor toolbar "Compile" button only does "game" code (actors and components), not plugins

Create Blueprint nodes and data

  1. Make a Blueprint type to hold a set of generated 2D point locations
    • Look for things tagged USTRUCT(BlueprintType) for examples of Blueprint-accessible types
    • KismetMathLibrary has some of the simpler examples.
  2. Make Blueprint node to initialize that type, taking a random seed.
    • Look for things tagged BlueprintPure for functions that access data and return results, but do not change any existing state, or BlueprintCallable for functions that do affect state. These will have the arrow-shaped sequence pins to let the Blueprint script give an order of execution.
    • Once again, KismentMathLibrary has some relatively simple examples. Other files in the same directory have some more complex examples.
  3. Make another Blueprint node to return a single point
    • This could be BlueprintCallable if it changes any state, or a BlueprintPure if you do it as a pure function that just accesses data but doesn't change it.

Blueprint test case

  1. Make a copy of your Blueprint test class
  2. Modify it to use your new blue noise type instead of RandomStream

Grad Students

Grad students should use some data structure to make the point distance queries faster (undergrads can just do a linear search through all existing points)

Submission

For full credit, you must commit multiple times during your development.

Add an assn3.txt. Tell us what works and what doesn't, and anything else you think we should know for grading. Include a link to video demonstrating your project.

Push to your repository, and tag your final commit with an assn3 tag.