pesho hristov
pesho hristov

Reputation: 2060

Can not add function to UnityEvent

I have a prefab Animal with attached script Animal.cs. There I'm trying to fire an event, which I want to handle in another script.

I'm trying two different approaches - and the code for that is like so:

[System.Serializable] public class _UnityEventFloat:UnityEvent<float> {}

public class Animal : MonoBehaviour
{
    [SerializeField]
    UnityEvent onAnimalKill;
    [SerializeField]
    _UnityEventFloat whenAnimalIsKilled;
    ...
    void OnMouseDown()
    {
        onAnimalKill.Invoke();
        whenAnimalIsKilled.Invoke(10f)
    }
}

And then I have an empty global GameObject with attached script - GameController.cs. There I'm trying to catch the events fired - like this:

public class GameController : MonoBehaviour
{
    ...
    public void OnSomeAnimalKill()
    {
        Debug.Log("ANIMAL WAS KILLED!!!");
    }
    public void OnSomeAnimalKillWithScore(float score)
    {
        Debug.Log("ANIMAL WAS KILLED - WITH SCORE: " + score);
    }
}

However - I can't connect the two scripts. I'm trying to drag the methods from GameController on the slots of the Animal - but it doesn't work:

enter image description here

enter image description here

Any idea what I'm doing wrong? ... I guess it's something super simple - but I can't figure it out.

Upvotes: 1

Views: 1395

Answers (1)

derHugo
derHugo

Reputation: 90580

From your comments we now know:

You are dragging in the GameController Script Asset into the slots of Animal Prefabs!

Two problems with that:

  • You don't want to reference the script asset itself but rather an instance of it attached to an existing GameObject
  • You can't have any Scene references in Prefabs anyway

What you rather want to do is right where you instantiate your instances there assign the callback dynamically like e.g. (we don't have your exact code)

[SerializeField] private Animal prefab;

and then

var animal = Instantiate (prefab);
animal.onAnimalKill.AddCallback(OnSomeAnimalKill);
animal.whenAnimalIsKilled.AddCallback(OnSomeAnimalKillWithScore);

Note: you will not see these dynamically added callbacks in the UnityEvent in the Inspector.


Or what I would actually suggest would be not using UnityEvent at all since you can't serialize the callbacks anyway but rather e.g.

public static event Action onAnimalKilled;
public static event Action<float> whenAnimalKilled;

and later invoke them like

onAnimalKilled?.Invoke();
whenAnimalKilled?.Invoke(10f);

And then all you ever need to do in the Gamecontroller is

private void Awake ()
{
    Animal.onAnimalKilled += OnSomeAnimalKill;
    Animal.whenAnimalKilled += OnSomeAnimalKillWithScore;
}

private void OnDestroy ()
{
    Animal.onAnimalKilled -= OnSomeAnimalKill;
    Animal.whenAnimalKilled -= OnSomeAnimalKillWithScore;
}

Upvotes: 1

Related Questions