One of the key things my lecturer has mentioned is making sure to have code modular, this means that a part of my code can work without requiring every other script that was made initially. It also helps as it means should I visit procedural generation again, I have some code already available to use. One of the ways to make my code modular was to create separate demos that break down the different algorithms.
Poisson Disc Demo
The first demo was the population algorithm Poisson disc sampling. For this I decided I wanted to a top down view and show all the trees spawning in so I used a Coroutine to spawn a tree or rock every second. The generation of the points was already in a static class that could be called at any point so it made it easy to implement.
After initially creating it, I decided to allow the user to be able to swap between using Poisson sampling and using Unity's built-in random method to show the difference between using the two ways to generate object placements. I also decided to change the colour of the plane to just white as it was easier to see the trees and rocks.
As mentioned in a previous blog, there are two main factors that impact how much objects can spawn in, the radius that says how close objects can be to each other and the number of attempts. With this in mind I decided to add sliders to allow the user to see how much these factors can impact the algorithm alongside a switch to change between using the algorithm and just randomly placing objects.
Terrain Demo
The initial script for the terrain mesh generator was made early on and isn't very reusable. This wasn't apparent to me until trying to create the demos, so before I could continue with creating the demo I had to break down the script and put reusable methods in scripts by themselves.
The main method was the fractal noise loop and so I created a separate static class called 'PerlinNoiseGenerator.cs' that ran the Perlin noise loop depending on the number of octaves with all the variables required passed through as parameters. Having the variables as parameters allowed the different scripts that called the Perlin noise to change properties of the new terrain. After the completion of the loop, the method returns the newly created noise map as a 2D float array.
I decided to create only one chunk and to have settings to allow a user to alter the shape and size of the noise map, I first created sliders that can be moved up and down to change the values. Through thorough testing I found the bounds for the different properties and made sure that the sliders are limited to those values:
Scale: 1-5 (floats)
Height: 25-100 (floats)
Offsets: 0-100,000 (whole numbers)
Octaves: 1-10 (whole numbers)
Persistence: 0-1 (floats)
Lacunarity: 0-2.5 (floats)
Code for altering the colour of terrain already existed from the menu scene so I reused it to allow the each separate section to be able to be changed and then update the terrain to use the new properties. I was originally telling it to call the UpdateMesh method in Update which was able to work fine however would cause there to be unnecessary work and show I changed it to only call the method when the player changes one of the sliders, this greatly helped framerate as the stats section on the Unity Editor went from saying 90FPS to over 300FPS.
In both demos, I added the pause button from the main game (now saved as a prefab) and added the scenes into the build index so that a user can travel between the main game and the demos through the main menu with ease.
The creation of the demos were really beneficial as they outlined what I needed to alter to make my code modular and I am happy with the results as I now have two algorithms I could reuse in the future. This has encouraged me for future projects to try to create demos that isolate a game mechanic to help me break it down into separate methods.
コメント