I have two very specific questions about a Unity tutorial I watched recently: Create a Simple Messaging System with Events - Unity Learn
The EventManager script has a section as follows:
public class EventManager : MonoBehaviour {
private Dictionary <string, UnityEvent> eventDictionary;
private static EventManager eventManager;
public static EventManager instance
{
get {
if (!eventManager) {
eventManager = FindObjectOfType (typeof (EventManager)) as EventManager;
if (!eventManager) {
Debug.LogError ("No EventManger found.");
} else {
eventManager.Init ();
}
}
return eventManager;
}
}
- Why do we need Lines 10-13 - won’t the script always find at least its own eventManager object?
- Why do we need to use typeof (EventManager) instead of EventManager as the argument to FindObjectOfType?
Answering #1: the FindObjectOfType method implies, “in the scene, on any game object, find the first instance of an EventManager and return a reference.” This reference is then stored in the private static EventManager eventManager field. It MAY be on this same game object where this script is located, but it does not have to be, and it certainly has nothing at all to do with “finding” the local variable in your script. For that you just refer to it by variable name.
Answering #2: Personally I don’t use that construct if there are generics available. I prefer using the generic construct as follows:
eventManager = FindObjectOfType<EventManager>();
1 Like
We’ll handle question 2 first its easier:
When you declare a variable (and I mean an int, float, class, struct ) the compiler has an internal list of things it knows:
- the name you used (like gameObject, or Myvar) so if it sees it again it can just use this list instead of creating a new one
- the Type it is , like int, float, class MyClass. This is so it knows how much memory the variable needs. I don’t fully know how the compiler treats the type field… but you can think of it as an internal struct or class. Its mainly so it knows that an int is 4 bytes long and can handle that in retrieving data. (or whatever type it is)
- a pointer to where the variable is in memory. This is what i mainly uses throughout your code.
So when you type int x= 5; it makes a pointer to some memory somewhere and sticks in 5. later on when you say x++ it replaces x with that exact same pointer. and changed 5 in to 6.
However the FindObjectOfType function isn’t expecting a pointer to where your X is. (it doesn’t care that the value is 6), it wants that Type field, so it can compare it against against a specific kind of type. This is what typeof (Variable) does. it returns the type rather than the pointer to the value.
Ok question 1 involves understanding singletons. Its an implementation to make sure no matter how many objects you attach this script to, there will always only be one instantiated copy of EventManager running around. In this code instance is the same as singleton. Secondly you need to understand about static keyword around the EventManager. Normally when I create a new class like MyClass myVar = new MyClass(); I get a brand new copy in memory of all the fields(variables). But if one of those variables is declared static, then only one copy of that variable will ever be made, and all the new MyClass() objects will share it.
So here is whats happening. When you attach Eventmanager script to a game object it creates a new copy of EventManager. Note: EventManager eventManager is just a variable. It hasn’t been set yet and is just null. So all that (!eventManager) code is exactly the same as saying if (eventManger == null). Its just checking if that variable hasn’t been set yet. When it makes that function call to eventManager.Init(), I bet its basically saying eventManager = this; so its setting the eventManager static variable to the current Copy of EventManager class.
Now once that is done, if you create a new EventManager by saying EventManager myNewEventManager = new EventManger(), the eventManager variable will NOT be null, it will be set to that first copy of EventManager . so if you tried if (eventManager == this) it would return false. since its pointing to that first copy.
So the long and short of it is this: Is eventManger == null if the answer is yes… lets set it to this copy. IF the answer is no, return the pointer to the original copy of EventManager. Often times if the answer is no, you just destroy the current copy thats checking it so only one exists
1 Like