Delegates, Events and Singletons with Unity3D-C #
Here I will demonstrate how to create representatives, events, and Singletons to work together. This tutorial is written for Unity3D.
I want to know why?
As a young self-learning programmer, I often find myself writing tons and Boolean statements to determine whether certain events or actions have occurred. I heard these events return values through the Coroutines coordinator and other methods. If you find yourself doing just as well, stop!
Welcome to the Events event ......
Introduction
Recently, I have been trying to improve my C # programming skills, discover my lack of knowledge, and understand the basics of Events. As a result, although I have read through many tutorials on MSDN and other blogs, I have found that most of the tutorials are complicated and flourishing with obscure core concepts unrelated to code. I don't want this to happen to you!
As a result, I will try to explain the Events and how to use them in the project ......
Singleton?
If you do not know anythingSingleton,. Single users cannot-or duplicate scripts. Well .......
I recommend that you useSingletonYou do not need to copy things in the game multiple times. Such as the Inventory System. Generally, players only need one inventory. When we call it, we want to ensure that it will not be copied.
There are many ways to create Singletons, but this method is often used because it is very simple ......
// This class sits on my camera and handles all the clicks I send with a Raycast public class Clicker : MonoBehaviour { // Singleton private static Clicker instance; // Construct private Clicker() {} // Instance public static Clicker Instance { get { if (instance == null) instance = GameObject.FindObjectOfType(typeof(Clicker)) as Clicker; return instance; } // Do something here, make sure this is public so we can access it through our Instance. public void DoSomething() { } ...
Here, the 'clicker' class is attached to my Camera. This type of processing is clicked on Raycast in 3D space.
To access my 'dosomething 'method from another script, I can only...
Clicker.Instance.DoSomething();
This eliminates the need to use a large number of static methods and variable calls, plus only one instance for us!
Delegate and event?
A delegate can be seen as a reference pointer to an object. When it is called, it notifies all methods that reference the delegate.
So, the first thing ......
Define the method triggered by a delegate and get a call ......
public class Clicker : MonoBehaviour { // Event Handler public delegate void OnClickEvent(GameObject g); public event OnClickEvent OnClick;
The proxy calls 'onclickevent' through a 'gameobject', which can be used to define the game objects it comes from. Then, we define the 'event' OnClick to obtain the delegate called during the call.
Now, in the same script, we need to call the delegate and pass it to our game object. Through Raycast ......
public class Clicker : MonoBehaviour { // Event Handler public delegate void OnClickEvent(GameObject g); public event OnClickEvent OnClick; // Handle our Ray and Hit void Update () { // Ray Ray ray = Camera.mainCamera.ScreenPointToRay(Input.mousePosition); // Raycast Hit RaycastHit hit; if (Physics.Raycast(ray, out hit, 100)) { // If we click it if (Input.GetMouseButtonUp(0)) { // Notify of the event! OnClick(hit.transform.gameObject); } } }}
As you can see, if Ray has been contacted, we click the object with the left mouse, we call this event and pass the game object.
The last thing we have to do is to reference the delegate from other scripts that we are listening to call. For this reason, I created a class named GoldPile.
public class GoldPile : MonoBehaviour { // Awake void Awake () { // Start the event listener Clicker.Instance.OnClick += OnClick; } // The event that gets called void OnClick(GameObject g) { // If g is THIS gameObject if (g == gameObject) { Debug.Log("Hide and give us money!"); // Hide gameObject.active = false; } }}
In our Awake () method, we define our listening event and assign a local method to get and call OnClick. 'Onclick' does not require the same delegate method, but it does.
Note:In previous posts, we added a singleton to our Clicker class. This allows us to use Clicker. Instance
As you can see, we have also created the OnClick () method for passing our click on our game.
Note:If you must use if (g = gameObject), otherwise, it will hide this method and other instances in the scenario... this is why we use GameObject for reference!
Now you are free to add this method to any other scripts in your game. Do not forget to define the method and assign it in your Awake.
Yes, best way is to use OnEnable/OnDisable:
Void OnEnable
{
Clicker. Instance. OnClick + = OnClick;
}
Void OnDisable
{
Clicker. Instance. OnClick-= OnClick;
}