leAthlon
leAthlon

Reputation: 744

How to use C# events in Unity3D

I've been working with Events for some time with Winforms, but I'm still quite new with Unity stuff. My project is just to get some C# code running on Android so there's no need for a super efficient solution, just a working one.

Event Handler declaration:

public event EventHandler OnShow, OnHide, OnClose;

Event Handler call:

Debug.Log("OnShow");
if (OnShow != null) 
{
Debug.Log("OnShow_Firing");
OnShow(this, new EventArgs()); 
}
else{
Debug.Log("OnShow_empty");
}

Event Handler Added in an other script but the same gameobject

void Awake(){
Debug.Log("Awake");
this.gameObject.GetComponent<windowScript>().OnShow += OnShowCalled;
}
private void OnShowCalled(object o,EventArgs e)
{
Debug.Log("OnShowCalled");
}

My Debug output is following:

  1. "Awake"
  2. "OnShow"
  3. "OnShowFiring"

but "OnShowCalled" is never executed, there're no Exceptions in Unity's console. I tested EventArgs.Empty instead of new EventArgs() as mentioned in the comments with no effect on my problem .

Looking forward for any help.

Upvotes: 3

Views: 17180

Answers (3)

JD.B
JD.B

Reputation: 125

Not enough reputation, but possible duplicate or related?

Simple event system in Unity

Events in Unity should be using UnityEvent.

Standard C# events don't work as expected since Unity executes code in a different way than vanilla C# (I don't know much about the topic, but I'm sure someone else does).

In addition, Unity uses an Entity Component System. See http://answers.unity3d.com/questions/669643/entity-component-system.html for more information.

Upvotes: -2

Umair M
Umair M

Reputation: 10750

First of all check this tutorial : https://unity3d.com/learn/tutorials/topics/scripting/events

I would recommend using event Action. It is easier to use for beginners.

Example :

Class containing events:

public class EventContainer : MonoBehaviour
{
    public event Action<string> OnShow;
    public event Action<string,float> OnHide;
    public event Action<float> OnClose;

    void Show()
    {
        Debug.Log("Time to fire OnShow event");
        if(OnShow != null)
        {
            OnShow("This string will be received by listener as arg");
        }
    }

    void Hide()
    {
        Debug.Log("Time to fire OnHide event");
        if(OnHide != null)
        {
            OnHide ("This string will be received by listener as arg", Time.time);
        }
    }



    void Close()
    {
        Debug.Log("Time to fire OnClose event");
        if(OnClose!= null)
        {
            OnClose(Time.time); // passing float value.
        }
    }
}

Class which handles events of EventContainer class:

public class Listener : MonoBehaviour
{
    public EventContainer containor; // may assign from inspector


    void Awake()
    {
        containor.OnShow += Containor_OnShow;
        containor.OnHide += Containor_OnHide;
        containor.OnClose += Containor_OnClose;
    }

    void Containor_OnShow (string obj)
    {
        Debug.Log("Args from Show : " + obj);
    }

    void Containor_OnHide (string arg1, float arg2)
    {
        Debug.Log("Args from Hide : " + arg1);
        Debug.Log("Container's Hide called at " + arg2);
    }

    void Containor_OnClose (float obj)
    {
        Debug.Log("Container Closed called at : " + obj);
    }

}

Upvotes: 7

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112712

For debugging purposes add a Tag property to your component. Then initialize with:

var component = this.gameObject.GetComponent<windowScript>();
component.Tag = "foo";
component.OnShow += OnShowCalled;    

And change the logging

Debug.Log("OnShow: " + Tag);

and you will see whether you're dealing with the same object.

Upvotes: 1

Related Questions