GPU Instancing in Unity

April 25, 2019

GPU Instancing

Tutorials for Unity

Youtube – GPU Instancing Tutorial (No, Seriously, This Is Easy)

By: Craig Perko

Youtube – [Unity] GPU Instancing Tutorial

By: Blendcraft Creations

Youtube – Unity3D – 2 Minute Tips – Use GPU Instancing to reduce drawcalls when batching won’t

By: Unity3d College

Youtube – GPU Instancer – Features Showcase

By: GurBu Technologies

I am starting a project in class that is potentially looking to instantiate a lot of flower objects in Unity, so I wanted to take a look at GPU instancing and see if this was a practical solution for us if we ended up going down this route. If not, this is still a good opportunity for me to get a taste of working on purposefully passing certain information to the GPU and using it for specific tasks.

The first three videos are direct tutorials showing how to set this up or how to use it, while the last one is an already made asset in the Unity Asset Store showcasing a very strong GPU Instancing heavy asset and some of its capabilities. I think the final one is nice to have to at least show some of the more interesting capabilities this can lead to.

Tower Defense Scene Management Issues

April 25, 2019

Scene Management Solutions

Identifying Issues and Possible Solutions

Scene Conflict
  • There are two scenes that load at the same time that have scripts within them that want to reference scripts within the other or both reference the Logic scene which needs to be updated simultaneously
  • Even though they should ideally be loading at the same time, one is always loading ‘just before the other’
  • This causes the first scene loading to miss its references since the other scene does not exist to it yet when it goes to get those references
  • The second scene loading in does however load its references properly
  • I’ve tested switching the order of loading and the second scene functions properly consistently, while the first scene has errors
Current Issues
  • Level scene loading second to make sure the nodes can get the BuildManager reference
  • However, the Level scene sets the number of lives the player has (LevelPlayerStats passes lives in to the PlayerStats script in the Logic scene)
  • The LevelManager in the Base scene checks the player lives to see if it should end the game
  • Since the Base scene is loading first, it checks and sees there are 0 lives before LevelPlayerStats can set the correct amount of lives for the level
  • This is setting the game to Game Over immediately
Proposed Solutions

Find way to time events: Setup the scene manager system in a way that it makes sure everything is loaded before attempting to setup references. Functionality of the game also needs to wait some time to make sure the newly loaded scenes have time to set the values necessary in the Logic scene before actually starting so they don’t try to work with default values instead.

Move references: Currently the issue is that no matter which scene loads first, there are reference timing issues with one of them. This could be evaded by placing all of the references that should be done first into the same scene and just making sure that scene loads first.

I believe the timing control solution is the better and more powerful solution, as this will help anytime I really need to have multiple interscene references in the future. That is also the much more difficult solution though. I may go with the simpler solution for now just so I can continue experimenting with the more game design heavy concepts of working on the tower defense game and then come back to figure out the stronger solution later.

Setting Up Java

April 15, 2019

Setting Up Java

Dev Kit, Eclipse, and Working in Command Prompt

Oracle – Java SE Development Kit 8 Downloads
Eclipse Site

Basic Setup

As I’m preparing for a foundational programming course, I needed to get Java setup on my computer. This started with downloading the Java Development Kit (JDK) and Eclipse (an IDE package for working with Java). I had to make sure to run and install the JDK first, as Eclipse needed some of its components to setup initially.

I needed to do some work using the command prompt on Windows, and found I was having trouble using the javac and java commands. This turned out to be an environment variable issue (something I ran into similarly when starting Python). I was able to easily resolve this by checking the “Edit the System Environment Variables” section of my control panel and adding the path to the Java jdk bin file to my “Path” system variable.

Unity Multiple Scenes and Controlling Loading

March 25, 2019

Advancing Tower Defense Tutorial

Moving Objects and References to New Scenes

Catlike Coding – Multiple Scenes and Loading Levels
Catlike Coding – Object Management

The Catlike Coding information on Multiple Scenes and Loading levels has a lot on how scenes are loaded in Unity and how to control that process better. I also included the link to the overal Object Management tutorial that this Multiple Scene write up is a part of. That seems like another useful overall source, that could also enhance the application of this Multiple Scene tutorial.

They start by creating a new scene and moving certain objects into it. After setting this up, they correct an issue they had where recompilation messes up the pool scene. This happens because they are using a scriptable object instead of the default monobehaviour for their script. Unity serializes the private fields of Monobehaviours when compiling, but not for Scriptable Objects. This meant CreatePools would get invoked on every recompilation and you would get errors trying to create the same scene several times.

To protect against this issue, they check if the scene is loaded using the Scene Manager isLoaded method. If that is true, they just return on their created method. This requires getting the scene value first since recompilation resets the poolScene scene struct to its default values on recompilation.

Level 01 – Multi-Scene Editing

Main Scene will be their scene for containing everything to run the game, no matter what level they’re playing. It contains the Main Camera, the Event System, and some other parts. Their basic Level 1 scene just contains the Light for now.

They first explore using the Scene Manager LoadScene() method to load their additional scene. This does not work, as LoadScene first unloads all currently open scenes before loading the requested scene. To load the scene in addition to what is already there, they add the LoadSceneMode.Additive as an argument to LoadScene().

The lighting is still incorrect because they need the Level 01 scene to be the active scene. This can be done in script with the SetActiveScene() method. They try placing this in their method for loading the scene, but it does not work. SetActiveScene only works for loaded scenes, and the loaded scene isn’t technically loaded yet even though it was called previously. This is because loading a scene takes some time.

To get around this, you can wait a frame between loading the scene and setting the newly loaded scene to the active scene. This can be done by making LoadLevel into a coroutine and adding a yield return null command between loading the scene and setting it active. This will give the desired result.

If your game takes a while to load, this simple load command may cause undesired results. This is because the game would basically freeze until the loading is finished. To prevent this, scenes can be loaded asynchronously, using the SceneManager.LoadSceneAsync method. This begins the process of loading a scene and returns an AsyncOperation object reference. This can be used to check whether a scene has finished loading. This can also be used to yield in a coroutine. This is how their example looks:

IEnumerator LoadLevel () {
//SceneManager.LoadScene(“Level 1”, LoadSceneMode.Additive);
//yield return null;
yield return SceneManager.LoadSceneAsync(
“Level 1”, LoadSceneMode.Additive
);
SceneManager.SetActiveScene(SceneManager.GetSceneByName(“Level 1”));
}

This coroutine now waits until the scene is completely loaded to continue its processes, but also does not freeze the game while loading. This however creates another issue where Update be called during the loading of the level. This would be bad for most games as you don’t want the player issuing commands before the loading is finished or the level has appeared. This can be corrected by having the Game component disable itself before starting the load, then enabling itself after finishing loading. This time would also be where you would place a loading screen.

Awake gets invoked immediately when a scene is loaded, but the scene does not count as loaded yet. In Start and later Update calls, the scene is considered officially loaded.

They get into creating another level and go into unloading scenes to prevent their level scenes from piling up as the go back and forth loading new instances of them. They start by making sure to keep track of the current scene build index and updating that whenever they load a new scene (this is similar to the approach I took with my Tower Defense scene management).

They then use the SceneManager.UnloadSceneAsync method to unload the old level index, before loading the next scene. They make sure to yield on the unloading as well before loading the next scene. This is their example:

IEnumerator LoadLevel (int levelBuildIndex) {
enabled = false;
if (loadedLevelBuildIndex > 0) {
yield return SceneManager.UnloadSceneAsync(loadedLevelBuildIndex);
}
yield return SceneManager.LoadSceneAsync(
levelBuildIndex, LoadSceneMode.Additive
);
SceneManager.SetActiveScene(
SceneManager.GetSceneByBuildIndex(levelBuildIndex)
);
loadedLevelBuildIndex = levelBuildIndex;
enabled = true;
}

Applications

I could look into the disable/reenable method used in loading the level for my scene management issue. Since I have objects from different scenes that are both trying to reference something in the other at Start, maybe I could try to reenable the components that need to reference each other at the same time and have them create the references OnEnable.

Make sure Scene Management keeps track of the current build indices loaded and update this on scene loads. This can help when you finally need to unload the scenes before loading the next ones.

Unity Scene Management – Fixing New Scenes to Work

March 21, 2019

Advancing Tower Defense Tutorial

Moving Objects and References to New Scenes

Myriad Games Studio – HOW TO USE THE UNITY SCENEMANAGER

Now that I had the scenes loading properly enough, I actually needed to get all the references fixed finally. I had not altered the references since looking to implement the concept of having an all time Logic Scene, a Base Scene, and a Level Scene, so some of the references were broken when I split them up, especially between the Base Scene and Level Scene. This provided an interesting challenge since I did not want to make objects/scripts in the Base Scene public static, so I wanted to look to a way to have them communicate to each other through the Logic Scene.

Currently, I think all of my GameManager functionality does not work being in the Base Scene. I am looking to split some of its functionality so that I can move the GameManager to the Logic Scene, and keep the more level related info in a new LevelManager that would be in the base scene.

There are also some scripts on the GameManager object I want to move into the Level Scene. These would include: WaveSpawner (controls the information on enemies in the wave, how many waves, etc.), PlayerStats (controls values such as the player gold and lives).

Some general thoughts I had looking to advance all of these scripts to get them to work in the new scene setup:

  • Moved GameManager to Logic Scene with: WaveSpawner, PlayerStats, GameManager
  • Added Singleton pattern to GameManager
  • GameManager should start inactive [Same with WaveSpawner and PlayerStats, so entire GameManager object] (Only active during level)
  • While the WaveSpawner would be in the Logic Scene, I wanted to move the wave information to the individual Level Scenes
    • WaveSpawner should solely be responsible for taking in the information from the scene and then performing functions
    • The wave information, WaveInformation script, would be an object/script in the individual Level Scenes that could be modified to pass on varying information to the acutal WaveSpawner
    • This separates the WaveSpawner functionality from the various information a designer could mess with in individual scenes

From the tutorial I watched on persisting data between scenes, I learned more about static variables and how to control them a bit better. Following this I changed all my singleton pattern referenced manager objects from they themselves being public static, to just static. Then I created a method for each of them simply called GetInstance that is a public static method that simply returns the static instance variable I set for each of those classes. This may be cleaner with properties, but I don’t quite know how to use those well enough currently so I am using this safer method approach for now. The scripts affected were: SceneManagerLite, GameManager, PlayerStats, WaveSpawner.

I also decided to clean up my PlayerStats script a lot to make it much more secure using properties with public methods. I changed it to the following:

public class PlayerStats : MonoBehaviour
{
#region Variables
static PlayerStats playerStatsInstance;

private int _playerMoney;
public int playerMoney { get { return _playerMoney; } }

private int _playerLives;
public int playerLives { get { return _playerLives; } }

public int rounds = 0;

#endregion


#region Unity Methods

private void Start()
{
if (playerStatsInstance != null)
{
Debug.Log(“More than one Player Stats Instance in scene”);
return;
}
playerStatsInstance = this;

rounds = 0;
}

public static PlayerStats GetInstance()
{
return playerStatsInstance;
}

public void AddMoney(int moneyToAdd)
{
_playerMoney += moneyToAdd;
}

public void SetLives(int numberOfLives)
{
_playerLives = numberOfLives;
}

public void LoseLives(int numberOfLivesLost)
{
_playerLives -= numberOfLivesLost;
}


#endregion
}

I changed playerMoney and playerLives to properties that could only be altered through the public methods added below, to keep these from randomly being set to crazy values throughout editing. This was also done in hopes that it would make doing the cross scene references easier to manage.

Now that all the singleton pattern objects were cleaned up, as well as significantly restructuring PlayerStats, I moved on to the WaveSpawner. I found that it made more sense to move the UI Text reference in the WaveSpawner to the actual UI object itself in the BaseScene. I created a new TimerUI script that I placed directly on the UI Text object dealing with time and just moved the snippet of code dealing with that from WaveSpawner to here, and just had the TimerUI script reference the WaveSpawner to get the time value. This just cleaned up WaveSpawner a bit to focus solely on spawning waves. I also fixed the SpawnWave method to work with the new PlayerStats setup, as rounds are also found there. This just meant changing a direct variable alteration to an indirect method alteration (from rounds++ to AddRound()).

Next I really needed to clean up the GameManager and the LevelManager as their purposes were a bit unclear. I decided that for the most part, the GameManager should just deal with what levels the player has unlocked. This was the only big “player stat” that needed recorded over multiple plays and levels. The LevelManager would then deal with actually determining when the player won or lost a level, as well as controlling the UI elements. This did help clean both of these up a lot and make their purposes clearer. The LevelManager dealt with the UI elements, the GameIsOver bool, and actually determining if the player won or lost the level. The GameManager then just updated the levels unlocked when calling WinLevel() method in LevelManager.

After all of this updating, it was time for more testing. It got through the Logic Scene well, and started with the MainMenu. Clicking Play got into the LevelSelect scene fine. I went into level 1, and it looked like the timer and money text were working properly, but no enemies were spawning (I also still have my issue where the Nodes are in a scene separate from the BuildManager that I need to fix). It appeared the WaveSpawner was turning itself off before receiving the WaveInformation from the Level Scene. I checked with a Debug.Log and this did in fact seem to be the case. The WaveSpawner checks in its Update function if the waveIndex (wave number it is up to for spawning) is equal to the total number of elements in the wave array (total amount of waves that should be spawned this level), and if this is the case, it turns itself off (to avoid errors with going outside of the array range). This however is causing it to turn off immediately because waveIndex starts at 0 and goes up to reach waves.Length, but since it doesn’t have the waveInformation in time, it thinks waves.Length is also 0 so it turns off instantly.

I think my issue with the Nodes is similar to that of the WaveSpawner. They get a reference to the BuildManager at Start, but it isn’t happening in time with how the scenes load so they don’t have anything to reference, and therefore never get the reference. Then they just never have the reference they need the rest of the time. So I need a way to enforce the order things happen between loading and running the scripts. This could be something I could solve with more use of IEnumerators and coroutines possibly.

The node solution is more difficult because both objects/scripts dealing with nodes are loaded in separate scenes at the same time. The BuildManager is in the Base Scene, while the Nodes are all in the Level Scene. These both get loaded at the same time. It turns out that by modifying my scene build index array setup I can alter which scene is loaded first, and both orders give me varying issues. Swapping the Base Scene to load first fixed the Node issue, as now the BuildManager exists first so the Nodes can get their reference, but then the game was immediatel ending (both winning and losing) since the win and lose conditions were met immediately as they require the Level Scene to pass the life and wave information to the Logic Scene to properly determine the game state. I need something that makes sure everything is loaded at the same time before starting the Start functions.

SOLUTION

Wave Spawner Issue

I remembered that the WaveSpawner being in the Logic Scene means it actually exists all of the time (I didn’t get the only activate in levels working properly yet, for similar reasons). This meant that by the time the level started, it had already been way past its Start function and into its Update function. This meant it was turning itself off way before I even entered the level. I then checked to see if it was at least receiving the WaveInformation even though it was disabled and it was. Knowing this, I just needed to reenable the script after giving it the WaveInformation. So directly after WaveInformation method PassWaveInformation(), I just also enabled the WaveSpawner script and it worked perfectly!

Preserving Data Between Scene Loads in Unity

March 21, 2019

Advancing Tower Defense Tutorial

Moving Objects and References to New Scenes

Youtube – Unity Tutorial: Preserving Data between Scene Loading/Switching

By: quill18creates

I came across this video on preserving data between scenes in Unity when trying to find ways to cross-scene reference variables. This did not solve those issues, but it was helpful for understanding static variables and their uses better.

Static Variables: These variables become part of the class. This is what allows them to persist between various scenes. A good practice for working with these is to make them protected, so they can not be get or set. Then you just allow other scripts to affect them by calling methods within the script that contain the protected static variable.

Using static variables can lead to messy “global” style variables, or nice encapsulation. Static variables can also lead to weird errors in Unity’s Editor specifically, just because of the way it deals with classes. I am not sure if this has been cleaned up with newer versions of Unity since this tutorial is a couple years old now, but still a good thing to be aware of.

This video also went over the DontDestroyOnLoad method for persisting data. Again, this was not the solution I was looking for, but it is a good concept to learn more about.

The biggest issue you have to remember with DontDestroyOnLoad, is that if you want to go back to a scene with that object, it will create another one. There is also another issue where testing becomes more difficult. If you want something to persist, you want to delete copies of it in other scenes so there is only one at any given time. This means if you want to work on a later scene that should inherit the DontDestroyOnLoad object, it won’t be there. These issues lead to the need for a Singleton pattern.

This was their suggested Singleton pattern:

if(ThisIsTheOneAndOnlyGameStatus != null)
{
Destroy(this.gameObject);
return;
}

ThisIsTheOneAndOnlyGameStatus = this;
GameObject.DontDestroyOnLoad(this.gameObject);

This is nice because it has the added benefit of allowin you to place multiple instances of the object around your scenes to get around that problem with testing, as when two instances run into each other, the new one will always destroy itself to make sure that the one you started with persists.

Something I could replicate to make my public static instances slightly less messy, was his use of creating a public static method called GetInstance, thst simply returns the instance. This at least makes it less likely to alter the existing instance from outside its original script.

Unity Scene Management – Finalizing Scene Loading/Unloading Process

March 19, 2019

Advancing Tower Defense Tutorial

Altering Scene Format

Myriad Games Studio – HOW TO USE THE UNITY SCENEMANAGER

Now we are going to look at fixing our scene loading so that occur with better timing and in the right order. The fading animation timing also needs fixed to work with this new scene loading setup.

We want to look at ordering these operations as: complete animation, complete loading next scene(s), unload current scene. Because we are looking to do several methods in order and only want to proceed when the previous is finished, my first thought was to make them all coroutines and have an overall IEnumerator run them with yield return. As far as I’ve seen, yield return can be used to ensure a coroutine finishing processing before starting the next action, as scene in the SceneLoaderAsync script I am following from Myriad Games in a previous blog post.

I started by removing any scene loading from the FadeOut coroutine so it was strictly dealing with fading out the screen. I then typed out the general scheme I was looking to follow with the timing of my coroutines:

  • IEnumerator Fade Out
  • IEnumerator Load Scene
  • IEnumerator Unload Scene
  • IEnumerator Fade In

This was the general order of actions I was intending to create. The screen should fade out, the next scene(s) should load in, the current scene(s) should unload, and then the screen should fade back in.

I started with a modified version of the SceneLoaderAsync script that I just called SceneLoader. I changed the input parameters of everything from string to int to work with build indices, and I modified LoadScenesInOrder by removing the part on using a loading screen for now as well as adding a line at the end that sets the loaded scene as active. I also added a coroutine that was UnloadSceneRoutine that was just a very minimalistic script to use UnloadSceneAsync method:

private IEnumerator UnloadSceneRoutine(int sceneBuildIndex)
{
SceneManager.UnloadSceneAsync(sceneBuildIndex);

yield return null;
}

Finally I put all of the SceneLoader script into my SceneManagerLite script for now since this is basically what it should be in charge of, and referncing coroutines from another script was giving me more issues than refencing methods, so this was easier for now. This gave me the 4 general coroutines I was looking to set up now.

I then went to test this with my Play method (which determines what scenes should be loaded/unloaded when the player presses Play from the main menu). The SceneLoaderAsync script just put their main coroutine into a method that was solely responsible for starting the coroutine, so I attempted to emulate that concept with my first attempt just to see if it would work. I had the LoadScenesInOrder and UnloadSceneRoutine just in their own methods and had them in the list of 4 actions I wanted to process, so it looked like:

IEnumerator PlayRoutine()
{
yield return StartCoroutine(FadeOut());

LoadScene(levelSelectorBuildIndex);

UnloadScene(mainMenuBuildIndex);

yield return StartCoroutine(FadeIn());
}

This was then just started in the method called Play(), so it would stay correctly tied to the button if was already attached to. I also wasn’t sure if this would be necessary to attach it to the button in the first place as well.

This setup almost worked, but the timing was still a bit weird. Just as the Fade In would happen, you would catch a glimpse of the scene to be unloaded before the actual scene being loaded in would appear. So I then just tried using all coroutines with yield return to see if that helped with the timing:

IEnumerator PlayRoutine()
{
yield return StartCoroutine(FadeOut());

yield return StartCoroutine(LoadScenesInOrder(levelSelectorSceneBuildIndex));

yield return StartCoroutine(UnloadSceneRoutine(mainMenuBuildIndex));

yield return StartCoroutine(FadeIn());

}

And this worked perfectly! Everything looked nice and orderly for my very low load time scene transition. From this, I could see larger scenes might present an issue since the screen would most likely just be black for a while, but for now this was a decent solution. Now I would also need to update my other scene transition methods but thought they would be pretty repetitive so I wanted to look into creating a single scene transition method to make working with these easier.

If I was going to be loading and unloading a single scene every time, this would be pretty straight forward to setup, but there are times where I need to load and unload more scenes than that. The method, called SceneTransition, would simply run the coroutine, SceneTransitionRoutine, which had a template similar to the one seen above in PlayRoutine, except that I added a foreach loop for the loading/unloading sections to go through an array to deal with the variable amount of scenes to deal with. This ended up coming out as this:

private IEnumerator SceneTransitionRoutine (int[] buildIndicesToBeLoaded, int[] buildIndicesToBeUnloaded)
{
yield return StartCoroutine(FadeOut());

foreach (int buildIndex in buildIndicesToBeLoaded)
{
yield return StartCoroutine(LoadScenesInOrder(buildIndex));
}

foreach (int buildIndex in buildIndicesToBeUnloaded)
{
yield return StartCoroutine(UnloadSceneRoutine(buildIndex));
}

yield return StartCoroutine(FadeIn());
}

This obviously would then have the SceneTransition method require int arrays as parameters as well. This solution is not amazing, but it ended up working for me for now. Now the methods connected to the buttons need to have their own int array variables that will just add the scenes to be loaded into one array, and scenes to be unloaded into a separate array. This feels a bit weird since this small project generally only deals with one scene at a time, sometimes with two, but I wanted to try and set something up that could handle more cases in the future. The Play() method was now:

public void Play()
{
int[] scenesToBeLoaded = { levelSelectorSceneBuildIndex };
int[] scenesToBeUnloaded = { mainMenuBuildIndex };

SceneTransition(scenesToBeLoaded, scenesToBeUnloaded);
}

And this also worked! I think this solution will be what I use going forward for the scene management for updating this tower defense tutorial. It’s not perfect, but it gets the job done and allows me to use a multiscene setup.

Last update, so this did give me a bit of trouble working with multiple scenes when determining the active scene. It wasn’t enough to just have the scene I wanted to be active just be the last value in the array, so I added a more controlled way to determine the active scenes. I moved the SetActive method from the loading method, to the overall SceneTransitionRoutine. This would be processed after the scenes were all loaded and unloaded. It would also take an input that was an additional parameter added to the SceneTransitionRoutine parameter list that was a single int that determined what build index would become the active scene. This resolved that issue.

Callbacks and Event Systems

March 18, 2019

Creating an Event System in Unity

Event System with Callbacks Tutorial

Youtube – Unity Tutorial: Callbacks and a (Really Awesome!) Event System

By: quill18creates

Following in my learning of delegates and events, I stumbled across an interesting tutorial on creating Event Systems in Unity. I just wanted to note this as something to follow up on in the future since the general concepts I got from skimming through sounded very promising and good to learn about.

Unity Programming – Delegates and Events

March 18, 2019

Unity Programming – Delegates and Events

Tutorials and Definitions

Youtube – Delegates – Unity Official Tutorials

By: Unity

Youtube – Events – Unity Official Tutorials

By: Unity

The scene management update has made significant progress, I am now currently loading and unloading the proper scenes at the proper times. The timing of the loading and unloading is still off however, as well as the fading animation timing is very strange. The fading error makes sense since I have the scene transition and the fading in the same method currently, so I will look to separate those and time them properly with IEnumerators. I was also told today that OnSceneLoad delegates would be a very helpful feature for me to look into to fix all my scene loading timings.

The basic IEnumerator timing I was also suggested to look into was: wait until animation is done, wait until next scene is loaded, then unload scenes to be unloaded.

Upon investigating delegates, I found that they are a very big part of coding in general. Looking into delegates also led me to events, which are somewhat like a specialized type of delegate. I believe understanding both of these will be very beneficial to my current scene loading issues, as well as being very useful for many other game programming purposes, so I wanted to take the time to better understand them before rushing back to my scene development needs.

TERMINOLOGY

Delegates

Delegates: Simply a container for a function that can be passed around, or used as a variable. Just like variables, delegates can have values assigned to them and can be changed at runtime. The difference is that while variables contain data, delegates contain functions.

First you create a delegate template with the delegate keyword. This dictates what types of methods we can assign to the delegate. Similar to a function, a delegate has: a return type, a name, and a parameter list. The methods you want to add to this delegate must have both the same type of return type and parameter list. You then have to declare a member variable with the type of the delegate you created.
Example:
delgate void MyDelegate(int num)
MyDelegate myDelegate

Then, you can either assign methods to the delegate as values directly, or add/remove methods from the delegate with the += or -= operators respectively. Adding several methods to a single delegate is called multicasting.

The example from the Unity Official Tutorial I linked is as follows: using UnityEngine;
using System.Collections;

public class MulticastScript : MonoBehaviour
{
delegate void MultiDelegate();
MultiDelegate myMultiDelegate;


void Start ()
{
myMultiDelegate += PowerUp;
myMultiDelegate += TurnRed;

if(myMultiDelegate != null)
{
myMultiDelegate();
}
}

void PowerUp()
{
print (“Orb is powering up!”);
}

void TurnRed()
{
renderer.material.color = Color.red;
}
}

This shows the potential of a multicast delegate. On start, the PowerUp and TurnRed methods are both added to the myMultiDelegate delegate (which is possible since both methods have return type of void with no parameter list, just as the delegate does). Now anytime afterward, if the myMultiDelegate is called, it will perform all of the methods added to it (in this case both PowerUp and TurnRed). It is also noted that if you want to remove methods from myMultiDelegate, just use the -= operator along with the name of the method you want to remove.

One final note was that attempting to use a delegate that has not been assigned anything will cause an error. In this case, a delegate will have its default value, which is null. This is why they show in the tutorial that it is good practice to check that the delegate is !null before attempting to use it.

Events

Events: specialized delegates that are useful when you want to alert other classes that something has happened. An event can be thought of as a broadcast system. Any class interested in an event can subscribe methods to it. When that specific situation occurs, the event is invoked, which calls the methods of the subscribed classes. So an event is just like a delegate classes can send methods to, and then when that event is called, all of those methods will happen.

In the Unity Event tutorial I linked, they start by creating an EventManager script they place on the camera (this might be different with Event Systems now, this is an old tutorial). They then create a public delegate, which is then the type used for the public static event they create. So it appears that an event might be something similar to a list of delegates, and you add the type of delegate to it to determine what types of methods you can subscribe to this event. The tutorial then ties the event to a button press. Now any time this button is pressed, every method subscribed to the event will be invoked.

To show the broadcasting nature of events, there are two separate game objects with two separate scripts attached to them that subscribe different methods to the same event. They also show the proper fundamental practice of dealing with events. The scripts subscribe their methods to the event OnEnable, and unsubscribe them OnDisable (this is similarly does as with delegates; the += operator subscribes a method to an event, and the -= operator removes the method). It is a good rule of thumb that every time you subscribe a method to an event, you should create a corresponding unsubscribe for it as well. Failing to do this properly can lead to memory leaks and other various errors.

They then describe why this system is effect for dealing with action in your game. The event manager only needs to worry about the event itself and the triggers for the event. It does not need to know about the Teleport of TurnColor script, and these two scripts didn’t need to know about each other either. This helps create a flexible broadcast system.

They then describe the difference between using a public delegate and the event they created. They state that you could acheive the same effect this way, since events are just specialized delegates. The reason to use an event here is that they have inherent security. Events ONLY allow other classes to subscribe and unsubscribe. If a delegate was used, other classes could invoke it or overwrite it.

The take away: if you want to create a dynamic method system that involves more than one class, use event variables instead of delegate variables.