Using the Generator - frasergeorgeking/UE4_BP_MazeGen_MIT GitHub Wiki

Mazes can be generated either directly within the editor using the provided Editor Utility Widget or, alternatively, at runtime. This section has been divided into two main sections to reflect these separate approaches.

The following guide presumes you have followed the prerequisites of the Getting Started page and have imported and set-up any custom tile geometry that you wish to use. This guide is using the default tiles provided with the project - please follow Custom Extensions to see how to import custom tiles. The guide also presumes that a single BP_MazeController is present within the Unreal Engine level you are working in (see below).

images/using-the-gen/maze_controller_scene.png

A breakdown of individual generation properties and specific variables/events implemented by the generator is available here.

Table of Contents

In-Editor Generation

Whilst it is possible to implement in-editor generation using alternative methods (such as enabling Call in Editor for the required generator events), it is recommended that the provided Editor Utility Widget interface is used. This interface has been custom designed to make the in-editor generation process as streamlined as possible. A guide on how to render the Widget and dock it amongst the Unreal Engine interface is found here.

Using the Editor Utility Widget

The Editor Utility Widget has been designed with a hierarchy of relevance in mind. Functions that are frequently used (such as Generate Maze) are placed at the top of the interface, with less frequently used functions (such as Save Maze as CSV) appearing at the bottom.

images/using-the-gen/uwbp.png

Frequently Used Functions

Generate Maze

images/using-the-gen/button_gen_maze.png

Procedurally generates a maze with the characteristics defined by the Maze Properties section (the options here are explored in greater detail below). If a maze has already been generated and the Generate Maze button is clicked again, the existing maze will be destroyed and a new maze will be procedurally generated.

Destroy Spawned Tiles

images/using-the-gen/button_destroy_tiles.png

Destroys the tiles associated with a previously spawned maze.

Import Maze from CSV

images/using-the-gen/button_import_csv.png

Opens an Asset Picker interface, upon which the user can select a data table from a previously exported and re-imported CSV file (see Asset Picker interface below). Data tables must be placed in the Content/Blueprints/ImportedCSVs directory to appear in list. Upon double clicking the desired data table, spawns the associated maze. If a maze already exists in the scene before importing, it will be destroyed.

Please see here for instructions on creating a compatible data table from an exported CSV file.

images/using-the-gen/import_csv_asset_picker.png

Select Data Table

images/using-the-gen/button_select_data_table.png

Opens an Asset Picker interface, upon which the user can select the Tile Data Table to Spawn. Data tables must be placed in the Content/Blueprints/TileDataTables directory to appear in list.

Editing Generator Characteristics

The characteristics of the output of the maze can be configured by editing the variables found directly underneath the Maze Properties header. For example, the position of the starting cell of the maze in world space can be directly effected by editing the value of Maze Spawn Loc, as shown below. When a user is happy with the assigned properties, a maze can be generated by clicking the Generate Maze button.

images/using-the-gen/maze_spawn_loc_example_01.png

A Generated Maze with a 'MazeSpawnLoc' value of X: 0.0, Y: 0.0, Z: 0.0.

images/using-the-gen/maze_spawn_loc_example_02.png

A Generated Maze with a 'MazeSpawnLoc' value of X: 3000.0, Y: -4500.0, Z: 0.0.

The dimensions of the maze can be directly edited by updating the Maze Height and Maze Width values. Please find examples of this below.

images/using-the-gen/5x5_example.png

images/using-the-gen/5x5_example_values.png

A Generated Maze with values of Maze Width = 5 and Maze Height = 5.

images/using-the-gen/10x5_example.png

images/using-the-gen/10x5_example_values.png

A Generated Maze with values of Maze Width = 10 and Maze Height = 5.

images/using-the-gen/5x10_example.png

images/using-the-gen/5x10_example_values.png

A Generated Maze with values of Maze Width = 10 and Maze Height = 5.

Changing the Generator Seed

By default the generator is configured to create and use a new random seed with every generation. This behaviour can be overridden by enabling Use Custom Seed? and entering the desired seed. Overriding the seed ensures that the output of the generator is constant whenever the same seed is used. For example, using the seed 1159641216 with dimension values of Maze Width = 5 and Maze Height = 5 would create the following maze every single time it was generated:

images/using-the-gen/seed_example_uwbp.png

images/using-the-gen/seed_example_01.png

Saving to CSV

If you wish to save a generated maze to file, fill out the parameters of the CSV Options section and click the Save Maze as CSV button (see below). If no CSV File Name is provided, a name is automatically created based on the current date and time. Allow File Overwriting? is set to false by default, setting it to true will allow the overwriting of files with identical names.

images/using-the-gen/csv_options_example_01.png

Exported CSVs are saved to a custom MazeCSVExports folder in the root of the project (see below).

images/using-the-gen/mazecsvexports_directory.png

Importing a CSV as Compatible Data Table

In order to regenerate the maze (either within the same project or another instance), a previously exported CSV must be added back into the project as a data table. We'll use the table exported in the previous Saving to CSV section as an example.

First, navigate to the directory where you wish to import the CSV within the Unreal Engine Editor. A folder has been pre-configured for this in the Content/Blueprints/ImportedCSVs directory, however you can also import to custom locations (please note that if you intend to use the Editor Utility Widget, you'll need to update the Asset Registry Filter to your custom location - see below).

images/using-the-gen/imported_csv_asset_picker_details.png

The Asset Registry Filter properties of ImportedCSVDataTableAssetPicker - the PackagePaths array determines which directories are included in the asset picker window.

Once you've navigated to the directory you'd like to use, click the Import button - this will open the traditional UE4 Import window where you can then navigate to and select the CSV file you wish to use.

images/using-the-gen/imported_csvs_directory.png

images/using-the-gen/import_window.png

Once you've selected the CSV file, a DataTable Options window will open. Please ensure that you configure the settings as per the screenshot below, paying special attention to ensure that the Data Table Row Type has been set to TileCSVDataStructure. This ensures that the contents of the CSV file is parsed correctly by Unreal Engine.

images/using-the-gen/data_table_import_options.png

The CSV file has now been parsed into a UDataTable asset. As with any newly imported asset, please remember to save your changes.

images/using-the-gen/imported_csvs_directory_imported.png

To respawn the maze, simply click Import Maze from CSV and select the Data Table that was just imported.

images/using-the-gen/import_maze_from_csv_highlighted.png

images/using-the-gen/import_csv_asset_picker_imported.png

Once you've double clicked the data table asset, the maze will immediately spawn (be careful, this process will delete any pre-existing maze in the scene)!

images/using-the-gen/imported_maze_spawned.png

Runtime Generation

To implement the generator in any dynamic capacity, understanding how runtime generation works is very important. This section provides a demonstration of how to utilise key generator events in the context of an example application (a program that auto-generates mazes every 1.5 seconds to showcase a 3D artist's assets). For the sake of simplicity, this application will be written inside of the Level Blueprint.

For more specific information about each key variable and event of the BP_MazeController class, please see the 'Events' section of the Generation Properties documentation here.

Demo Application Tutorial

Create and save a new level in the project. The image below uses the 'Default' new level preset and, as such, contains a pre-configured sky-sphere and lighting setup. With a new level craeted, add a single BP_MazeController object into the scene.

images/using-the-gen/new_level.png

Next, open the Level Blueprint (see below).

images/using-the-gen/open_level_blueprint.png

With the BP_MazeController object selected in the main scene, right click in the Level Blueprint and select 'Create a Reference to BP_MazeController'. This will create a reference to the object in our level which we can then use to call the necessary generator functions.

images/using-the-gen/create_ref.png

With a reference to the BP_MazeController in the scene, we can create a Single Cast Delegate in the form of the Create Event node. This delegate will let us execute the delegate functions of the BP_MazeController class, including the custom GenerateMaze event. This functionality can then be paired with the Set Timer by Event node to loop the function repeatedly (see below).

images/using-the-gen/set_timer_by_event_example.png

The Set Timer by Event Settings - Remember to add a negative Initial Start Delay, otherwise there will be a 1.5 second initial delay with no maze spawned!

Clicking 'Play' in Unreal Engine will produce the the following effect (the gif has been sped up for demonstration purposes).

images/using-the-gen/autogen_example.gif

This result is fine for a basic application, however what if we want to change the properties of the maze at runtime? For this, we'll need some form of User Interface where a user can input their desired dimensions. As per below, create a Widget Blueprint with a Spin Box for Width values and a Spin Box for Height values.

images/using-the-gen/new_widget_bp.png

images/using-the-gen/widget_spinboxes.png

Remember to update the min & max slider values to clamp the range of Width and Height. You can also force the Spin Box to update in integers by lowering Min Fractional Digits and Max Fractional Digits to 0.

Next, implement the On Value Committed events for each Spin Box - these events will fire when the spin box values are updated.

images/using-the-gen/spinbox_events.png

images/using-the-gen/spinbox_events_bp.png

After these events are implemented, create a new function called GetMazeController using the logic below. In the same way that we needed to reference the BP_MazeController in the Level Blueprint, we also need to reference the controller in our Widget Blueprint.

images/using-the-gen/get_maze_controller.png

Note: Get All Actors of Class isn't the most efficient method of directly referencing an Actor, however it is used here for the purpose of brevity (it won't make a real difference for a project of this scope, either).

Next, when the value of one of the spin boxes is updated, we need to use our new GetMazeController function to pull a reference to the maze controller and update the respective Width or Height value.

images/using-the-gen/set_width_height_bp.png

Lastly, we need to update our Level Blueprint with some basic logic to render the new Widget Blueprint - simply add the following nodes to our existing Begin Play logic.

images/using-the-gen/render_widget.png

The final result should look something like the following:

images/using-the-gen/demo_5x5.png

images/using-the-gen/demo_10x10.png

images/using-the-gen/demo_25x10.png