UnityLearn – Intermediate Programming – Pt. 01

September 30, 2019

Intermediate Programming: Unity Game Dev Courses

Swords and Shovels: Game Managers, Loaders, and the Game Loop

Intermediate Programming: Unity Game Dev Courses

Unity Learn Course – Intermediate Programming

What is a GameManager?

Game Systems

Many parts of your game will need to communicate with one another. You can directly makes these connections between different objects as needed as a way to accomplish this. This method however does not scale well, and becomes very complicated and hard to debug.

This is where the concept of having a GameManager comes in. This provides a central location where systems can communicate through. They can also hold important central data.

The tutorial’s basic definition of a GameManager was “A central location for data” which can serve one of the following purposes or both:

  • Determines who can change what
  • Informs other systems of changes

This Swords and Shovels tutorial will specifically use their GameManager for rule management and some informing.

Persistent Systems

The GameManager needs to be accessible to all the systems that need it. The GameManager should be globally accessible for the life of the game.

Unity Containers

They reference Scenes and Prefabs as Unity Containers. They represent collections of assets and use particular scripts to connect them. In Unity, Scenes are generally large collections of assets, while Prefabs are for smaller collections.

One technique is to have a persistent scene which contains all of your managers, since it will most likely even have responsibilities for loading and unloading other scenes. This is the technique that will be used in this tutorial. This also happens to be the technique I was using on my personal tower defense scene management project.

Preparing to Build a GameManager

You most likely will not be able to design and construct the perfect GameManager for your game immediately. Games are organic objects and you will need to change and adapt your systems as you build in most cases. With this in mind, it is important to build in a way that supports growth (but without over designing).

When starting to make your GameManager then, you want to layout the basic requirements you know it must have. The requirements for this tutorial are:

  • Tracks What Level Is Being Played
  • Can Create Other Global Managers (i.e. Audio manager, Game Save manager)
  • Knows the Current State of the Game
  • Can Cleanup Game Systems (i.e. Save game on quit, send message to server indicating how game ended)

Setting Up Your Scenes

This part finally gets into working with the Unity project. There was a package to download that contained all the necessary objects to get you up to speed to start working at this point.

When you create a script named GameManager in Unity now, it gets a unique icon that looks like a gear. This does not particularly do anything special, it is just a visual to help you identify the GameManager since it is normally a more important class.

This step mostly just wanted to have you get the package loaded in, create the GameManager script, and make a new Boot scene that will handle starting everything (as well as put that scene in the build settings). It also mentions how it is important to put all your scenes in the build settings to make sure they are accessible with your system.

FINAL NOTES

There is a actually a lot going on with the package I obtained for this tutorial, so it may be worth looking into the beginner part of this tutorial before progressing with this part. Even though it will most likely cover a lot that I already know, I think there is still a good bit of valuable information for me to gain from going through it.

Unity Learn Premium – First Look Tutorials

September 28, 2019

Unity Learn

Tutorials and Courses

Unity Learn

Link – Unity Learn

The Humble Bundle had a sale on a lot of interesting Unity content, including a year subscription to some learning tools such as Unity Learn Premium so I decided to finally grab it and look into it. There are definitely a lot of courses and videos I am interested in checking out, so I just wanted to quickly go through and list a few to do as soon as I can.

I am not sure how well these links will work since they will mostly be through this paid service of Unity Learn Premium, but I am hoping they at least work to get me back there when I want to use them.

Intermediate Programming: Unity Game Dev Courses

Unity Learn Course – Intermediate Programming

Advanced Programming: Unity Game Dev Course

Unity Learn Course – Advanced Programming

Introduction to ScriptableObjects

Unity Learn Tutorial – ScriptableObjects

These three stood out to me very quickly as useful tutorials and courses to look into. The courses will be very helpful at just covering general programming in Unity. Even if they cover some topics I have already done, it is always useful to find new and different ways to build systems or implement certain programming techniques. And finally, the ScriptableObjects tutorial just covers a topic that I still need to look into more and just have not yet.

AI State Machine Tutorials: Tutorial #2

September 25, 2019

Tutorial #2

From Blog Post: Unity Basic AI State Machine Tutorials

Youtube – Unity 3D – Make a Basic AI State Machine

Tutorial #2

By: Joey The Lantern


General Structure

There is a general state machine class, a class for each individual state, and then the class for whatever will be using these states. This format is very similar to the first AI state machine tutorial I followed by UnityCollege3D.

State Machine

They created a new namespace, StateStuff. This was because they did not want anything to be a monobehaviour. This namespace then holds the StateMachine class as well as a public abstract class State. They mention that could be used in place of to allow you to specify what types can use this class, but they went with because it’s more ambiguous and works with more things. This is something I will need to look into, but I am guessing at this point T just means any type. So basically anything can use the StateMachine.

The state machine class was given two variables, State currentState and T Owner. These are both set in a constructor for StateMachine. Owner is what will be using the state machine, and currentState is obviously what state it is currently in.

State Class (within StateMachine script)

There were several abstract methods created for this class. These were: EnterState, ExitState, and UpdateState. EnterState allows you to perform actions immediately upon entering a new state, ExitState performs actions necessary when leaving a state for another, and UpdateState performs the various update actions for that state on that object.

FirstState

This class inherits the State class in the StateStuff namespace. The State here takes in an AI reference (again, I need to look into this more to see what this is actually doing). I see what this is doing better after implementing the abstract class. The type that is passed into State is then the type required by all of the methods that take in a parameter of type T. So since we declared State, now all of the methods require an input of AI _owner (translated from T _owner).

Their general idea is that there is only one instance of each independent state class, and every object that wants to use this state will just reference this same single instance. Following that, they use a bit more of an involved singleton-looking pattern to create this. The setup is the following:
public class FirstState : State
{
private static FirstState _instance;

private FirstState()
{
if (_instance != null)
return;

_instance = this;
}

public static FirstState Instance
{
get
{
if(_instance == null)
{
new FirstState();
}

return _instance;
}
}
}

The second state is exactly the same as the first, it just changes some of the text around so that it matches the new class name.

AI Class

This class represents the main script that would be running on your object that you would like to be using AI. To show the state machine working with it, it simply has a timer in the Update method that changes a bool.

GENERAL FLOW

There is one StateMachine instance and one instance of each individual state class. Each state has an UpdateState method, which generally corresponds with what an object in that state should be doing with an Update method. This is actually called through the StateMachine’s Update method though for every object.

The class which you want to use with the StateMachine and various States (AI in this example) must first reference the StateMachine and pass itself in as a paramter. Then it just needs to make sure to call stateMachine.Update within its own Update method. This is what allows everything to communicate what an object using this state machine should actually do in that state.

Finally, each individual state class is responsible for determing when to change to a new state, and what that new state should be. This is however performed by using the ChangeState method found within the StateMachine class. This method is responsible for calling the ExitState method from the old class, and the EnterState method from the new class.

FINAL NOTES

This setup uses a single instance of a state machine and a single instance for each state, which can be a nice avenue to take since it can really keep things scaled down that way. It also seems nice that the classes simply using this StateMachine setup mostly just need to call the StateMachine’s Update method to really interact with it. It helps keeps them from getting messy with state machine code. It does seem like it could be a bit tricky making sure the individual states themselves have proper references to check within the AI classes to figure out when they should change states with this approach.

AI State Machine Tutorials: Tutorial #3

September 25, 2019

Tutorial #3

From Blog Post: Unity Basic AI State Machine Tutorials

Youtube – ADVANCED AI IN UNITY (Made EASY) – STATE MACHINE BEHAVIORS

Tutorial #3

By: Blackthornprod


NOTES

This tutorial actually dealt with using the Unity Animator to create a sort of state machine setup. You can add behaviours to animation states, which are already setup in a very similar way to the last AI State Machine tutorial I did from Joey the Lantern (Tutorial #2 in this recent tutorial list).

These behaviours already have methods such as OnStateEnter, OnStateExit and OnStateUpdate (as well as several other more animation focused methods). This tutorial uses these to setup the logic for their state machine.

While this seems nice for getting something running very quickly, especially from an animation focused perspective, I think I would rather use the setups from the other tutorials that start more from scratch and allow you to develop the full system yourself. I would much rather follow Tutorial #1 and Tutorial #2 than this one.

Unity AI with Basic State Machine

September 24, 2019

Basic State Machine Setup

Unity Tutorial

Youtube – Unity3D AI with State Machine (FSM), Drones, and Lasers!

Tutorial #1

By: Unity3d College


Tutorial #1

This tutorial goes over a “good” version and a “bad” version of setting up state machines. The bad version will work, and is ok for very small scale projects and objects, but it does lack scalability and has some poor design choices going on.

The real state machine covered in this tutorial is not a monobehaviour, but is still able to access components of objects. This was a point they wanted to make sure they covered with the laser object reference.

To start going over the state machine, they go through the Drone class and its variables. Target is a public Transform but has a private setter. The Team variable Team uses an expression body property to allow the setting of team from the inspector without letting anything else change it.

The next class they go over is the StateMachine class. This starts with a dictionary that contains all of the possible states. It takes in a Type and a BaseState value. The Type is just type of the state class, and the BaseState is a new object of that specific state.

The Update method of StateMachine first checks if there’s a current state. If there is none, it sets a default state. It then performs a method called Tick to determine what the next state is (if it is either the same state again, or a new state). It then checks if the nextState is a different state, and if so, switches to the new state.

Each state has had its own class created, each of which inherits from a public abstract class called BaseState. None of these are monobehaviours, but you can still pass in a GameObject object through any state which gets set to a GameObject variable in the BaseState so the states know which object to control. This BaseState also uses protected variables so that classes that inherit from it may use them, without allowing anything else to access them. And finally, BaseState has a public abstract Type Tick method just to make sure every state class has a Tick method (actions to have an object perform in this state).

While checking through the individual state classes, they mentioned the use of nullables. You can add a “?” to the end of a variable declaration to make it nullable. This allows you to set that variable to null when you normally cannot. They like to do this just as a consistent way to help them check if something actually has had a value assigned to it or not.
Example:
private Vector3? _destination;

They also setup a GameSettings class to help them change general variables that go along with their state machine. This uses a simple singleton pattern setup like the following example:

public static GameSettings Instance { get; private set; }

private void Awake() {
if (Instance != null}
Destroy(gameObject);
else
Instance = this;
}

Unity Basic AI State Machine Tutorials

September 23, 2019

Basic AI State Machines

Unity Tutorials

Youtube – Unity3D AI with State Machine (FSM), Drones, and Lasers!

Tutorial #1

By: Unity3d College


Youtube – Unity 3D – Make a Basic AI State Machine

Tutorial #2

By: Joey The Lantern


Youtube – ADVANCED AI IN UNITY (Made EASY) – STATE MACHINE BEHAVIORS

Tutorial #3

By: Blackthornprod


State machine is just a term I have come across when researching and working with AI projects, so I wanted to delve into it a bit more to understand it better. It is my hope that this will be useful as both game design experience as well as general programming experience. These tutorials I grabbed are mostly from well know Unity devolepers that put out generally good learning content, especially when it comes to the programming side.

I am also looking to take a general AI course and do some more advanced AI work in my thesis, so it makese sense to start finding some more interesting or well defined AI systems and learn how they are made. These tutorials are relatively all on the shorter end as well, so should be easy to knock them all out in a single session.

HFFWS Modify Prototype to Handle Building Multiple Scenarios

September 20, 2019

Furthering Prototype

Level Generator

Prototype Enhancement

Allowing for Multiple Scenarios to Be Created at Once

This started as a thought for just generally helping with testing the classes to see if they were working properly, but then it seemed like it could just be a powerful addition to the system in general so I decided to implement it more properly into the system. The basic idea was simply adding a “Test Counter” which I could adjust to create a number of instances of the generic scenario I was generating.

The idea was that this would let me see more instances of the variance the system has at once, so I could more quickly test if it seemed like the system was working or not. This also helps give me a better picture of the overall variance the system has as well, so it was actually more helpful than I first realized.

I have also dabbled in machine learning (ML) and a key portion of using that is creating several test environments to more quickly train your system or agents. This gave me more motivation to look into changing my variables into array sets to deal with the idea of multiple puzzle scenarios (which could potentially later feed into how to get this setup for multiple testing environments for ML).

At the root of everything, the system is doing very similar work to what it was doing previously. I have just added several for loops and changed some variables instances into arrays to allow the overall system to deal with several puzzle instances at once. Holding all of this information in arrays could also be beneficial for printing out the data somewhere to keep better track of what works and doesn’t work with the system at any given time.

Example Image and Video

Example View of 5 Generated Puzzle Scenarios – By: me

Vimeo – Example Iterations of Scenario with a Test Run with a Character

Link – Test Example with Gameplay

GENERAL NOTES

I just wanted to make sure to note some other factors I ran into with some more testing. The mass of the TestCubes that needed carried around to reach the ledges ended up settling on 120. That was a value I found to be fairly easy to move around, but not so light that the cubes would topple over often (especially the smaller ones).

Currently the GenerationSystem has an array that holds all of the ledge height values passed in from every generation of a ledge, so that can be fed to each properly indexed cube for scaling purposes. However, because I am passing that information on Awake, I was unable to set the size of that array equal to the number of tests (as it should be), because even doing so in Awake was not being done in time. I tried setting the size of the array directly on variable declaration, but I want to be able to control the number of tests to create from the inspector so the array size comes from a serializeable field in Unity. I could not use this to declare my array size in the class’s general declared variables. So for now, it is just hard coded at some decently large array size (like 10) until I find a better solution.

NEXT STEP

I would still like to test this setup with a more complicated puzzle scenario, as this simple one is already helping me see a lot of possibilities and flaws that will need adjusted.

HFFWS Building Prototype Setup

September 19, 2019

Building Prototype

Level Generator

Prototype Frame

The idea of this prototype design is simply to show the general concept of the final hoped for result of my thesis project. It will cover the core concepts of: creating the proper objects for a puzzle type, varying parameters of those objects, communication between objects.

This prototype will be a very simple puzzle. It will simply be an elevated ledge that the player must be able to climb up onto by using a block in the environment. This will demonstrated the concept of tying specific object types to a puzzle type (connected the instantiated block to an elevated ledge puzzle). It will have varied parameters by varying the position of the ledge (most notably the height) and the size of the block. Finally, the system demonstrates communication between objects by using information on the ledge’s position to control the range of the block size.

PROTOTYPE CLASSES

Class: Generator System

This class was created with the purpose of receiving data from all the individual creation classes which would be important for communicating with other creation classes. Information that a class needs to receive from another to inform how it should generate or instantiate objects should all be compiled here for other classes to pull from.

Class: Create Ledge

This is a small example of a creation type class which simply instantiates a ledge. The ledge is just a long box object. A range for its position, most notably its height, can be input by the designer. This class then instantiates the ledge somewhere within this range, and then passes the height information to the GeneratorSystem class.

Class: Create Box

This is another small creation type class, but this one exemplifies receing information from the GeneratorSystem as opposed to passing information to it. Its main function is just instantiating a box object. This class has ranges of inputs for the position of the box in 3D space as well. It also has a range determining what scale the box object should be instantiated at. This scale range however, uses information from the GeneratorSystem to see if it needs adjusted, and adjusts accordingly.

Just to show the general concept, the minimum scale that is given to this class will adjust based on how high the platform is instantiated. This is to ensure that the box is at least big enough to allow the player to reach the ledge, regardless of height (theoretically). There is also a max scale limitation which is just a fixed value to be put into the GeneratorSystem, which is there to make sure the box isn’t so big that the player cannot climb onto it in the first place.

Concept for General Flow

There needs to be a flow where all values that can be determined before instantiation are found and passed into the GeneratorSystem. This then needs to be followed by classes accessing this information (if they need other class information before determining some of their own values). Finally, the creation classes should all have the information they need to proceed and generate the puzzle scenario.

Testing Flow

I initially tried having each of these classes set static references of themselves in Awake in Unity, then pass information to GeneratorSystem in Awake, and finally grab values from GeneratorSystem in Start before instantiating at the end of Start. This however had an issue where the instances weren’t all being set in Awake in time to also pass values within it (between several classes). Basically, the small public GetInstance methods were being called before the instance in GeneratorSystem was actually set.

As a temporary fix, I simply changed the GeneratorSystem references within each seperate class into a public variable so I could just set them in the Unity inspector. This ensures that they are taken care of before anything else. This solved that problem, and could actually be a fine solution avenue as long as separate scenes are not needed.

GENERAL NOTES

This practice was helpful for visualzing the process I want to achieve, as well as getting started on figuring out the basics of how the individual classes should be setup to build this process. I am already starting to see repeated patterns that may be better suited with parent abstract classes or interfaces if I continue this route of just having many creation classes and one general GeneratorSystem class. That may also be helpful in the future for having GeneratorSystem find/store/etc. all these different classes.

This exercise has also helped me start to identify what values and variables may make sense to have the final product system determine on its own. For example, maybe the system could figure out on its own how much shorter the box can be than the ledge while still allowing the player to complete the level. Similarly, maybe it could determine the maximum size the box can be to allow the player to still climb onto it.

With this very quick and simple test, the objects did spawn inside of each other sometimes. This was noted as something I would have to look into at some point previously, so I am just reiterating.

NEXT STEP

Test this prototype out some more to get a feel for how this system works, and what fine tuning I can do to make it work a bit better. This will also help me get a better idea for the general framework of some of the classes I may need to make, and what higher level parent classes or interfaces I can make that can serve as the foundation for some of these creation classes.

This can also help me get a better understanding of how the data flow should work, and whether that should be switched around to any degree. This general framework was made with the intention that individual creation classes would contain the individual methods needed to adjust their personal ranges and needs, but maybe it could make more sense to do more work with the overarching GeneratorSystem class.

HFFWS Prototype Setup

September 18, 2019

Setting Up Prototype

Level Generator

Prototype Frame

The idea of this prototype design is simply to show the general concept of the final hoped for result of my thesis project. It will cover the core concepts of: creating the proper objects for a puzzle type, varying parameters of those objects, communication between objects.

This prototype will be a very simple puzzle. It will simply be an elevated ledge that the player must be able to climb up onto by using a block in the environment. This will demonstrated the concept of tying specific object types to a puzzle type (connected the instantiated block to an elevated ledge puzzle). It will have varied parameters by varying the position of the ledge (most notably the height) and the size of the block. Finally, the system demonstrates communication between objects by using information on the ledge’s position to control the range of the block size.

Unity – Testing Collision on Instantiation for HFFWS

September 17, 2019

General Testing

HFFWS

Rigidbody Collision on Instantiation

Since having the system place objects itself is an eventual goal of my project, I wanted to see if rigid body gameobjects with colliders would collide immediately with each other if one was instantiated within the bounds of the other. I also wanted to check with collision checks would work best (or at all) for this, between OnEnter, OnExit, Stay, or anything else I could find.

To test this, I placed a cube (with collider and rigid body component) in the virtual space in the editor, and an empty gameobject that would be the TestSpawner at the same transform location. The TestSpawner simply instantiated an input gameobject at Start. This object was a simple sphere that had a collider and rigid body component. I think created a CollisionDetector script that I placed on both of these objects. This just had methods for OnCollisionEnter, OnCollisionExit, and OnCollisionStay to return a debug.log stating the name of the object itself and what it was colliding with, with information on which method it used to detect this collision.

The test did work as expected. They both immediately called OnCollisionEnter detecting each other, then had many OnCollisionStay calls as they stayed collided/near each other. Since the objects cannot occupy the same space, they did displace each other, which will be something I will have to monitor in the future. I am not sure if this will be an issue, but depending on how precisely objects need to be located in their original positions, this could cause some issues. I may need something that can detect an impending collision and stop an instantiation process before actually displacing the existing object.