Brackeys Tutorials: Terrain Generation and Vertex Colors

September 11, 2019

Graphics Tutorials

Mesh Generation/Alteration and Vertex Colors

Youtube – MESH GENERATION in Unity – Basics

Tutorial #1

By: Brackeys


Youtube – PROCEDURAL TERRAIN in Unity! – Mesh Generation

Tutorial #2

By: Brackeys


Youtube – MESH COLOR in Unity – Terrain Generation

Tutorial #3

By: Brackeys


Tutorial #1

This tutorial just covers the basics of creating meshes in Unity. This covers the basics of vertices and tris in Unity, as well as the back-face culling done. This just means when creating tris for the triangle array that they must be input in a clockwise manner to display in the proper direction.

Tutorial #2

This tutorial gets into using the basics of Tutorial #1 to create an entire terrain. This process simply starts by creating a grid of a bunch of vertices, filling them in with tris, and then modifying the positions of some of those vertices.

This started with a process I have used before in mesh generation, where you use several for loops to generate all the vertices in an array of some given size, then fill the gaps between those vertices with tris using more for loops and some basic math. They did add a nice twist where they made the CreateShape method into a coroutine, so we could use WaitForSeconds and see the mesh be filled out. While this was done for a neat aesthetic purpose, this could possibly help in debugging meshes to see where the tris start to be created incorrectly.

The very simple for loop setup for going through all the vertices and filling in the tris did have one flaw that was addressed in the tutorial. When going from the end of a row to the next row, we were creating an extra tri which extended from the end of the row all the way back to the beginning of the next row. Weird errors like this have gotten me before in mesh generation, so I just wanted to point it out.

The setup in this tutorial did the whole quad for each vert, so basically each point was given its own square to cover as we went through the for loops. To avoid the issue of creating extra tris between rows, they simply “skipped” the final vert in each row by adding 1 to the vert index an extra time once a row was completed.

Example of tri generation snippet: for (int z = 0; z < zSize; z++) { for (int x = 0; x < xSize; x++) { triangles[tris + 0] = vert + 0; triangles[tris + 1] = vert + xSize + 1; triangles[tris + 2] = vert + 1; triangles[tris + 3] = vert + 1; triangles[tris + 4] = vert + xSize + 1; triangles[tris + 5] = vert + xSize + 2; vert++; tris += 6; yield return new WaitForSeconds(0.1f); } vert++; // This is the extra vert index added to ensure proper transition from one row to next }

Finally, to make it seem more like the terrain we wanted, we added some noise to the y position of our verts when creating them. Perlin noise was the choice used in the tutorial. Perlin noise is Unity takes in two coordinate parameters, then outputs a noise value between 0 and 1. You can further multiply this by another factor to create more significant noise effects.

There was an interesting issue with using perlin noise. They multiplied the input parameters by 0.3f, which looked very arbitrary. They mentioned that there was a reason for this covered in another video on perlin noise so I checked that and apparently perlin noise repeats on whole numbers. Since we were fedding in parameters based on our vertex indices, these were all whole numbers. Sure enough, when I removed the 0.3f multiplier, the entire terrain was flat again. Something about being “not whole numbers” allows the noise to work.

Tutorial #3

I logged this tutorial earlier, and just wanted to include it here since it went with the other tutorials. I’ll be looking to use this as my Next Step for this post, and hopefully get some more vertex color tutorials to go along with it. I would like to look into some more shader code focused ones if I can since it should be pretty straight forward/simple shader language to get some more practice.

NEXT STEP

Do Tutorial #3 and find more vertex color tutorials (preferably with focus on using shader language).

General Graphics in Unity – Vertex Colors, Shaders, Meshes, UVs

September 11, 2019

General Graphics Information

Meshes, Shaders, Vertices, UVs

Youtube – MESH COLOR in Unity – Terrain Generation

Tutorial #1

Youtube – Learning Shaders in Unity – Everything about Meshes in under 5 Minutes

Info #1

Youtube – Pico Tanks: Vertex shader in Unity

Info #2

Tutorial #1

I was interested at looking into using vertex colors for objects, which led me to a few interesting videos on various aspects of 3D modeling in general. Tutorial #1 was a nice example of using vertex colors in Unity, as well as giving me a simple tutorial to look into on mesh deformation as well. It uses Unity’s shader graph to apply vertex colors, and just simply sets colors with a gradient onto the vertices themselves based on their height (y position).

Info #1

Info #1 was a very brief but general overview of topics on meshes.

  • UVs: It explained how UVs are used to map textures onto faces of objects, which was the biggest topic I had not really covered up to this point. UVs also belong directly to a vertex.
  • Vertices: It also went into how their can be more vertices on an object than you’d expect (since they have a normal that goes with individual faces).

This video was specifically aimed at Unity, so some of the information was most likely Unity specific. For instance, the fact that the Mesh class contains Vertices, Normals, UVs, Tangents, Triangles, and Colors. It finally got into vertex colors at the end, which also showed an example of it being used that just made a very cool colored cube I thought.

From: Info #1

Info #2

Finally, Info #2 was just a very quick video of a game project showcasing their use of vertex shaders to actually move trees in their environment when objects are moving through them. Moving objects affect the colors of an underlying texture map, which use this “color information” to apply affects, such as rotating the trees.

HFFWS – Instantiating Conveyor Belt

September 10, 2019

Human Fall Flat Workshop

Conveyor Instantiation

Today we are finally going to try setting the parameters of a conveyor object on instantiation and seeing which we can and cannot, and trying to fix as many that we cannot as possible. We will also use this as a comparison point for the vertical moving platform generator to start designing the foundation of a tool that can instantiate many different types of objects. At the very least, it could potentially lead to the start of an interface or an abstract class that can be used as the base for classes that instantiate objects.

Parameters to Set on Instantiation

  • Item Prefab
  • Segment Count
  • Length
  • Radius
  • Speed

TESTING

Test #1:

ISSUE: Want to properly set some conveyor prefab parameters on instantiation.

Using a similar start to creating the platform prefabs, my first attempt to instantiate these conveyors began with instantiating the conveyor prefab and casting that as a gameObject. As most of the parameters are found in the Conveyor script in one of the children objects of this prefab, I simply created a Conveyor variable reference that used a GetComponent. I then set all the parameters of this conveyor reference with public variables available in the inspector: segmentCount, lenght, radius, speed.

FAILED: The script was returning an error as soon as it tried to set the first parameter (segment count). This made me think that maybe just using GetComponent to get the Conveyor reference was not working. I thought GetComponent looked through children objects if it didn’t find anything in the initial object, but that may not be the case.

Test #2:

ISSUE: Get prefab reference to actually set conveyor parameters on instantion.

I am changing the GetComponent to GetComponentInChildren to see if specifying that initially helps properly grab the Conveyor reference I need. I am also adding a debug.log to check the name of the reference I am getting in hopes that this will help me check what it is getting (if anything).

SOLUTION: This did fix the problem of getting the reference and actually setting the values, however, this was not creating a conveyor with the proper initialized conditions. The values were being set, but the parameters that need to be set at instantiation to work (like Lenght and Segment Count) were not being received in time.

Test #3:

ISSUE: Parameters being set, but instantiated prefab is not using those set parameters. It is using the default prefab values.

With some very quick checking, I decided to look into issues with changing prefabs and instantiating them and it very simply led me to find that I can just change the prefab parameters itself before instantiating an object. This seemed like a very obvious solution that I hadn’t tried yet apparently, so I simply did just that: I simply had my Conveyor reference variable grab that of the input prefab itself, set all the parameters, and then just instantiate that prefab (without the casting to gameObject addition).

SOLUTION: This immediately worked. The length, radius, and segment count were all set to the inspector values and actually reflected in the instantiated conveyor. It should be noted however that this effect of altering the prefab carries over into the editor AFTER EXITING PLAY MODE.

Images of Prefab Default versus Parameter Altered Instantiation (Conveyor)

Conveyor – Default Prefab
Conveyor – Parameter Set Instantiation

NOTES:

It is very important to note the final effect of editing and instantiating prefabs this way. You are directly modifying the prefab itself, which can have some undesirable effects. At one point, I had an example conveyor in the scene to compare with, and it took on the same parameters of my conveyor spawner after running, ending, and running again, since it must have been using a default prefab reference of some kind. That prefab itself had its values changed (which again, carries over into the editor even when LEAVING PLAY MODE), and my other scene reference to that prefab just took them on as normal prefab changes.

To further test this, I edited the values in the existing prefab instance in the scene slightly, and further play tests did NOT reset this existing prefab reference. I played, closed, played again, and it stayed with the same set values. So it appears any alterations are making it into its own object, where as if you simply drag/drop in a prefab, altering the prefab this way can change how those objects will start up in the future.

Further testing showed that any values directly set to the existing prefab reference in the scene will always stay that set value, but running the game will still cause other parameters that haven’t been altered to change to those dictated by the script. This impact can “lag a play behind” as well. For example, I set the segment count in the existing prefab object to a different value, so playing kept all the parameters the same (even those I had not altered), however, upon playing a second time, those other parameters WERE altered to the values dictated by the script (where the editor set parameter still remained as it was set).

Video of Issue

Vimeo – Video Link

By: Me

The two main ways around using the system this way that I can see are:

  • 1: Always setting the parameters of existing prefabs in the editor that will be affected by scripts
  • 2: Create two seperate prefabs: One for using pre-made instances in the editor and one that can be taken by a random spawner and altered

All of this shows that editing the prefab before instantiation may not be the best solution, and it may be worth looking into other techniques if available.

NEXT STEP

I want to randomly instantiate a few conveyors to make sure the system of setting up random ranges for values works just as well with this as it did for the moving platforms. I would also like to experiment with replacing the meshes with various other mesh objects (for example, instantiating the conveyor segments randomly from a predetermined list of mesh options).

Hex Based 4X Game Tutorial

September 9, 2019

Unity 4X Game Tutorial

Part Based

Mostly Civilized: A Hex-Based 4x Game Engine for Unity – Part 1

Youtube – Link

By: quill18creates

I was looking to add another Unity game genre tutorial that I could follow along with, and happened to come across one for a fairly complex genre I enjoy so this seemed like a nice more advanced tutorial program to go through. I have checked out some of quill18creates content before and it usually serves as some good practice for more advanced topics, while also helping teach you some fundamentals about optimization and general project architecture.

This immediately caught my attention with the hex tile map math shown at the beginning of the video. There they show how to use various coordinate systems, such as cube coordinates, in a hex tile system in a very efficient and sensible way. The link to this information can be found here:

Hexagonal Grids from Red Blob Games

Red Blob Games – Link

Unity – Latest Prefab System 2019 – Nested and Variants

September 5, 2019

Unity Prefabs

Nested Prefabs and Prefab Variants

Youtube – NEW Unity Prefab Workflow – How to use Nested Prefabs

Video #1

Youtube – NEW Prefab Workflow – How to use Unity3D Prefab Variants

Video #2

I have been meaning to learn more about Unity’s latest prefab system updates they put out in Unity 2019, and Unity3D College is a really good place to learn good practices for working in Unity so this seemed like a good place to get some information on the topic. These videos cover both nested prefabs and prefab variants in an in depth manner using some real game object examples to help explain their uses and benefits.

Unity – Accessing All Children Objects Throughout Entire Various Sized Hierarchies

September 4, 2019

Accessing Full Gameobject Hierarchy

Unity

StackOverflow – Get All children, children of children in Unity3d

Link #1

Unity Answers – Find children of object and store in an array

Link #2

For a project we were looking into applying a material color change to some more complex Unity objects/models which are made up of many children objects with many materials. To do this, I needed a way to be able to grab all the materials all throughout a gameobject’s hierarchy and change them simultaneously. This led me to think of a recursive approach, and sure enough there was already one explored that I could reference online in Link #1.

Link #1 also showed me a useful feature that I did not know about Unity. You can use a foreach loop on a transform and it will go through all of the children transforms automatically. This helped make the recursive solution much easier to read, and is just a good feature to know about in the future.

Highlighting a Selected 3D Object in Unity

September 3, 2019

Highlight and Selection

Materials and Color Change

REFERENCES:

Unity – Color.Lerp

By: Unity


Unity – Mathf.PingPong

By: Unity


Youtube – Mini Unity Tutorial – How To Select And Highlight Objects In Game Realtime With C#

Tutorial #1

By: Jimmy Vegas


Youtube – Color.Lerp Unity Once using Coroutines | No Update Function Beginner Tutorial

Tutorial #2

By: iUnity3Dtutorials


Unity Answers – Change color to multiple Materials in one gameObject?

By: Unity (lachesis)


I wanted to create a generic object highlight/selection feature for a project, so I turned to a method I found searching for highligting techniques online where you just change the material color of the currently selected object over time. This is a very simple (conceptually) and often used feature for showing a user what object is currently in focus. It would turn out that it’s a bit more complicated when you are working with models that have many different materials on separate children objects throughout them.

I started with the “Mini Unity Tutorial – How To Select And Highlight Objects In Game Realtime With C#” tutorial as the basis for this system. This was a good inspiration point, but not much more than that. Our project immediately had several major differences so the setup was quite a bit different. To start, we already had a reference to the Interface of the object to highlight, so we wanted to work with this same setup to determine which object is being selected. Our objects are also much more detailed models which are made up of many individual gameobjects which can have several materials each themselves.

Using this as a base, I decided I would setup a basic system that would change the color of an object from its original color to pure white, and then back to its original color. This would then loop until the object was deselected. Conceptually, this is exactly like the tutorial referenced above, but implementing it would take a lot more steps with our current setup.

Casting Interface as Monobehaviour for Gameobject Reference

I first looked into how to reference a gameobject with an existing reference to one of its used interfaces. I found that as long as the script implementing the interface inherits from Monobehaviour on some level, you can cast that interface reference as a Monobehaviour. You can then use this Monobehaviour reference to access that specific gameobject. I could then use this gameobject reference to access the Renderer component to alter the material color.

Looping Color Change for a Single Material

To test the base line of this feature, I wanted to get it working on one object with a single material. I did not like the way Tutorial #1 approached this, so I looked into some other ways to alter the color of a material and came across a Lerp interpretation. I have used Lerp a lot for positional systems, but I had not thought to use it with color, so this seemed perfect. This also makes it very easy to set a final color for the selected object to turn to which can be changed in the design process.

The standard Unity documentation for Lerp with Color also showed me a new Mathf method, which was PingPong. This lets you take a value and constrain it to a specific range between 0 and [length], where [length] is another input parameter. Once that value goes past the input [length], it begins to come back to 0 (as opposed to continuing to increase past [length]). This creates the “ping pong” effect where the input value goes back and forth between 0 and the given length. This works perfectly when lerping back and forth between two colors with an overall range of 0 to 1, where 0 is completely the first color and 1 is completely the second color.

Here is Unity’s basic color Lerp example:
using UnityEngine;

public class Example : MonoBehaviour
{
Color lerpedColor = Color.white;

void Update()
{
lerpedColor = Color.Lerp(Color.white, Color.black, Mathf.PingPong(Time.time, 1));
}
}

Accessing Multiple Materials on a Single Gameobject

So now that I could change the color of a single material, I found that I would actually need to change the color of many materials at once, given the types of models we were working with. I have normally used Renderer.material in Unity to grab the single material on an object, but I found that there is also Renderer.materials, which returns all the instantiated materials of a single object in a single Material array. This is what I would need to get started on accessing all the materials I needed to control.

Since there are many children objects within these models, which can each have several materials of their own, I figured I would need to create some conglomerated Material array that could take on all of the materials while going through a large loop. This loop would need to be able to go through all of the children objects, and grab all the materials from each of those objects as it went through. Then finally, once all of the material references were obtained, we could Lerp all of the materials within this single combined array. Theoretically, it should give the intended result of becoming all white even with all of these materials because they should all be lerping with the same time input and the same final material color.

FINAL NOTES

  • Try Color.Lerp for changing an object’s color
  • Use Mathf.PingPong to have a value go back and forth within a range of 0 to some value
  • Renderer.Materials returns a Material array of all the materials on an object
  • An interface can be cast as a MonoBehaviour to access its gameobject if the interface inherits from MonoBehaviour
  • Complex models can use many different materials, so some basic Unity material techniques can be much more complicated to apply in these cases

Tower Defense Project – Fixing UI Text

September 2, 2019

Tower Defense Tutorial Project

UI Text

GOAL:

Fix game over UI text and look into round text references to see why they update strangely.

NOTES:

For the GameOver screen producing weird text results, my first thought was to the check the inspector references. I know tying the stats into text UI elements uses inspector references, so making sure those were correct was the first check. Sure enough, it looked like the wrong text was dragged into the GameOver UI inspector field. I must have grabbed the wrong one initially, as the generic text was dragged in there as opposed to the text that should be holding the round number.

As for the issue with the round text timing being off, I figured that had to do with the way the coroutine to animate the text was setup. It should count up from 0 to the final round number the player ended on (whether they won or lost), but it was starting on that final round number, THEN going to 0 and counting back up again. This just looks really bad, so it needed fixed. From checking the RoundsSurvived script (which is the same for both the Rounds object in GameOver and LevelCompleted), it looked like the animation coroutine was being set to start, and the next line was setting the roundsText to the playerStats.rounds. This is most likely the issue, as the coroutine starts, the text is immediately set to the rounds value as dictated by the very next line, then the coroutine continues running updating the value until it hits the rounds value again. This fits inline with the incorrect behavior we are getting.

PROBLEM 1

The incorrect text being displayed on the GameOver UI.

TEST 1

Move the Rounds (Text) into the RoundsSurvived inspector field as opposed to the Text (text) for the GameOver screen.

SOLUTION: This was all it was, updating this fixed the issue and the text was all in the proper place on the GameOver UI.

PROBLEM 2

Round counting animation starts at the max value, then immediately goes to 0, THEN counts up to max value again.

TEST 1

I removed the line right after the one initializing the AnimateText coroutine that was setting the rounds text to the rounds value.

SOLUTION: This appeared to solve the issue with some testing. Both the GameOver and CompletedLevel UI would start the round counter at 0, then count up to the correct number of rounds survived.

NEXT STEP:

Make 5 uniquely distinct levels to test the overall system. This includes testing generic gameplay as well as the general level progression and level selection system. As I am using a basic built in Unity way to handle saving progression right now, I have had all the levels unlocked for recent testing. I need to reset that and test that that is tracked properly, especially over several levels to make sure the system holds that many as well as giving more data points for any possible issues.

HFFWS – Working with Conveyor Belt

August 29, 2019

Human Fall Flat Workshop

Conveyor Parameters

Conveyor Parameters

Name: DarkGreyMetalMechMediumDebrisMovingConveyorBeltBody

  • Parent
    • Mesh
      • the mesh of the overall body of the conveyor belt; the central element
      • Default: DarkGreyMetalMechMediumDebrisMovingConveyorBeltBody
    • Conveyor (script)
    • Item Prefab: objects that the belt is made up of
    • Segment Count: creates the designated number of segments; spread out accordingly
      • Initialized
    • Length: Changes the overall length of the conveyor
      • Changes during Runtime, but only properly works in setup
    • Radius: this is the radius of the curved ends; controls overall thickness of belt system
      • Initialized
    • Speed: Direction and how fast the belt moves around
      • Runtime
    • Node Graph (script)
    • Signal Math Comparte (script)
  • BeltM_RollEnd
    • Just seems to be model for cylinder at a belt end
  • BeltM_RollStart
    • Just seems to be model for cylinder at a belt end
  • ConveyorSegment.001
    • This just seems to be the default prefab reference for the object that makes up an individual conveyor segment
    • This does not need to be a child of the overall object, so it can be removed
    • Just the reference to this object is needed in Conveyor script’s Item Prefab
    • Make sure to have a reference to this if removed to use still
  • LoopingSFXStart
    • Controls starting the audio
  • LoopingSFXStop
    • Controls stopping the audio
  • ConveyorLoop
    • Another audio source for the general audio produced by the conveyor
  • top
    • Instantiated at runtime, holds segments making up the top part of the conveyor
  • bottom
    • Instantiated at runtime, holds segments making up the bottom part of the conveyor
  • start
    • Instantiated at runtime, holds segments making up the curving side of the conveyor
  • end
    • Instantiated at runtime, holds segments making up the other curving side of the conveyor

NEXT STEP

I have worked out a lot of what the parameters do, now I just need to test setting them and instantiating conveyors at run time to make sure that works as I expect.

Tower Defense Project – Testing Losing States

August 28, 2019

Tower Defense Tutorial Project

Testing Losing States

I believe all the moving parts for my scene management system are finally starting to come together and work properly for this project. The losing conditions are the last state I really need to check with. I just need to make sure it properly ends the game when the player loses, does not allow them to progress, displays the proper UI elements, and moves between scenes from the losing state correctly.

GENERAL TESTING

Test #1:

The first test was going to Level 1 from the level select menu and immediately losing.

This seemed to work fine. The game stops when the player loses, and the game over UI comes up. The UI text does not seem to be working properly, so I will have to adjust that. It says the player survived 25 rounds, which is just the default value. I need to tie this into the script controlling the round count.

I think tried Retry and Menu from this losing state and both seemed to work properly. Retry started the level again (and actually reset all the values and waves as well) and Menu took me back to the level select menu.

Test #2:

Open level 2 from the level select menu and immediately lose.

This ended up having the player immediately lose and show the gameover screen as soon as the level loaded. I believe this has to do with how I arrived at the level. I was at the level select menu from the Menu button on the game over (losing screen) of the previous level (Level 1). I think going from losing, directly the the level menu, directly into another level, is missing a reset somewhere.

I did try Retry as soon as I lost level 2 and this reset the level just fine. I also tried selecting Menu and going back to the level, and this only worked properly sometimes. I believe it may have had to do with the timing of the wave.

The issue is that lives in PlayerStats gets set to <=0 to meet the losing condition, but does not get set to a proper value on level start in time. The Base scene loads in, then the Level scene. The Base scene has a check on player lives to see if they have <= 0 for a game over, and the Level scene has LevelInformation which is responsible for setting values like lives. So lives is being checked before being set. This was worked around initially by starting lives at 1 instead of 0, and then anytime the player won they had more than 0 lives so checking a value greater than 0 gave no issue.

POSSIBLE SOLUTIONS: Test #2

My idea to fix this timing issue of the gameIsOver check among other values (like the number of lives) was to move the gameIsOver bool to the GameManager. The GameManager is in the Logic scene, which always persists. This is also where PlayerStats resides, which holds the player lives. My thought with this was that I could have both the gameIsOver bool and the lives be set from the same place at the same time, and with them being in the same exact script, checking against them should be more consistent. Basically, since the game has to be started (gameIsOver == false) as well as having your lives <= 0, if any way of ending the game sets gameIsOver == true, we can make sure gameIsOver is not false until we also set lives first.

SOLUTION: This approach worked (for the most part). I reworked the LevelInitializer script in the Level scene to call StartGame in the GameManager, which just sets the gameIsOver bool to false. LevelInformation is also in the level scene, and this is responsible for setting the lives. This ensures the same scene is setting both the lives and the gameIsOver to false (starting the game). Now the LevelManager checks with the GameManager to see if the gameIsOver is true/false, as well as PlayerStats to see how many lives there are. This basically passes all the value setting and value checking to objects in the Logic scene, which makes sense since it is the omnipresent scene for the project.

This did lead to one issue where losing and retrying the level was not turning the CameraController back on.

PROBLEM: CameraController Bug

The CameraController was not coming back on when losing a level and attempting to retry it.

It turns out that going into a new level was fixing it since the CameraController works by default when loading a new scene, but when the game enters an end state (when we turn off the controller) and we keep the same scene (it’s in the Base scene) like when you call Retry, then it does not come back on.

Test #1:

SOLUTION: Since activating the camera controller was another thing that should happen on level start, I wanted to tie it into the LevelInitializer script. This already had a reference to the LevelManager from my previous attempts at creating Start/End game methods, and the LevelManager had a reference to the camera controller since it was initially solely responsible for controlling the game camera. Using this existing setup, I had the LevelInitializer script go through the LevelManager to enable the CameraController script on the camera object. The LevelManager simply acted as a holder for the camera object and the method for enabling it for this purpose (disabling the camera controller was still handled by the LevelManager when it determined the game had ended).

This ended up working well and gave no errors as far as I could tell.

FINAL NOTES:

With fixing up this last issue, all states and scene transitions should basically be accounted for. Continue, Retry, and Menu all work during gameplay (paused); Continue, and Menu work after beating a level; Retry, and Menu work after losing a level. This should finally be the end of the majority of the scene management work.

NEXT STEP:

The game over UI text is still weird, so I need to fix those references. Also along those lines, it’s only a minor issue, but the game winning text starts at the final round number and THEN counts up again from 0 to the final round number. It isn’t game breaking, but it looks silly.