Instance variables and this == null in event handler
I fire an event from a coroutine of class A and subscribe to that event an event handler in class B. After the event handler is invoked, I get an error when trying to access instance variables from it (variable of type MyType is destroyed but you're trying to access it). Even when I try to access 'this' property, I get NullReferenceException. This happens sometimes, in 15% of cases. Here's my code:
public class Alien : MonoBehaviour {
public delegate void AlienCorpseAction();
public static event AlienCorpseAction ProduceCorpse;
void MyFunc(){
StartCoroutine ("PooPoo");
}
IEnumerator PooPoo(){
yield return new WaitForSeconds (3);
ProduceCorpse ();
}
}
public class B : MonoBehaviour {
public Alien alien;
void Start () {
alien = ...;
Alien.ProduceCorpse += ProduceCorpse;
}
void FixedUpdate () {
Debug.Log(alien + " " + this); // I get normal values here
}
void ProduceCorpse(){
Debug.Log(alien + " " + this); // I got "null null" here sometimes
}
}
After I get 'null null' in event handler, console still shows me normal values in FixedUpdate.
Answer by NoseKills · Jun 09, 2016 at 04:21 PM
First suspicious thing i see is that your event is static. Not sure how much this affects things but it seems extra care shoulf be taken with static events.
Another thing is that you don't unsubscribe to the event anywhere. The subscription prevents the object from being garbage collected (i think it would even if it wasn't static ). So even objects that Unity has destroyed get the event and react to it.
You should unsubscribe '-=' to the event in OnDestroy for example.
The fact that 'this' can be null is due to the fact how Unity objects are just wrappers that can appear null without actually being null references.
For the same reason for exmple this bit of code doesn't add a component in case it is missing, although it should
Button button = GetComponent<Button>() ?? gameObject.AddComponent<Button>();
as i learned this week...
Yes, you're right, that's because the event was static, already changed it.