- Home /
Question regarding Delegates & Events
Hello
I am trying to learn the subject of Delegates and events in unity.
I have seen this example on: http://www.indiedb.com/groups/unity-devs/tutorials/delegates-events-and-singletons-with-unity3d-c The examples there are quite good and simple to understand so i followed it..
in the delegate/events it uses the following example:
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);
}
}
}
}
And now to reference the delegate from our other scripts that are listening to the call: Other script:
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;
}
}
}
Now, what i am asking? It seems to be that if you have like 100 GoldPile Scripts attached to objects. Everytime i "GetMouseButtonUP(0)" it will call 100 times the 100 scripts (since u have 100 objects of GolePile) to check if its a GoldPile gameobject. it seems to be inefficient and could cause slowdowns if you have like 1,000 GoldPiles.
I want to learn Delegates & Events, but i also want to learn how to use them the right way.
I would love to learn from your experience.
Answer by AlwaysSunny · Apr 04, 2015 at 09:57 AM
Subscribe in OnEnable and unsubscribe in OnDisable. Failure to do so can and will cause memory leaks.
void OnEnable() { foo += bar; }
void OnDisable() { foo -= bar; }
To answer your question; I would not recommend using an event system like this in such situations. It's overkill. Any situation which creates 999 wasted calls to detect 1 valid call would be incredibly sloppy.
Instead, just pass the single object you clicked to a method which makes decisions about that single object. Event systems are useful when all other alternatives are somehow grossly inconvenient, but they are not a "magic bullet" programming technique.
do you mean just to use a singleton to pass parameters ins$$anonymous$$d of delegates/events for the example case?
Your update function in Clicker knows what object the raycast has hit, so you can call its OnClick method directly.
So for example ins$$anonymous$$d of line 22 you could do
GoldPile gp = hit.gameObject.GetComponent< GoldPile >();
if (gp != null) gp.OnClick();
For the example you've illustrated, a singleton is likewise unnecessary.
edit: Bonfire Boy is correct, that is the absolute easiest way to accomplish what you're trying to do. ;)
Simply let the object expose a public OnInteraction() method. You could create an InteractableEntity base class with a virtual OnInteraction() method you override, or an IInteractable interface your GoldPile implements which includes an OnInteraction() method.
Then when you pick / interact with an object, you could just call its OnInteraction() method. In the case of a GoldPile, the method should add its value to the player's gold inventory and self-destruct. A trap might harm the player OnInteract, or an IGetable object might add itself to the player's inventory.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Is it possible to access OnValidate() when using a custom inspector? 1 Answer
A real head-scratcher 0 Answers