using UnityEvent<T0> the invoked function always receives the same value for the parameter

I’m just getting into using UnityEvent and am trying to create a UnityEvent that receives a single bool parameter. However the function I invoke through the UnityEvent always receives a value of false.

I am running on Android. I have three scripts

ObjectTouch raycasts from the touch location and calls the function ActionOnTouch.DoIT(someBool) if the object has that script.

public class ObjectTouch : MonoBehaviour
{
    private Ray ray;
    private RaycastHit hit;
    private Touch touch;
    Camera cam;
    bool trueFalse = true;
    ActionOnTouch action;

    void Start()
    {
        cam = Camera.main;      
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.touchCount > 0)
        {  
            touch = Input.GetTouch(0);
            if (touch.phase == TouchPhase.Began)
            {
                ray = cam.ScreenPointToRay(touch.position);
                Physics.Raycast(ray, out hit, 100);

                if (hit.collider != null)
                {
                    if (hit.collider.transform.gameObject.TryGetComponent<ActionOnTouch>(out action))
                    {

                        Debug.Log("will pass " + trueFalse.ToString());
                        action.DoIt(trueFalse);
                        if (trueFalse)
                        {                          
                            trueFalse = false;
                            Debug.Log("setting to " + trueFalse.ToString());
                        }
                        else
                        {                          
                            trueFalse = true;
                            Debug.Log("setting to " + trueFalse.ToString());
                        }
                    }
                    else
                    {
                        Debug.Log("object has no action");
                    }
                }
                else
                {
                    Debug.Log("nothing touched");
                }
            }
        }
    }
}

ActionOnTouch is placed on objects that have colliders. I have a single cube that has this script on it in my test scene.

[System.Serializable]
public class BoolEvent : UnityEvent<bool>
{
}

public class ActionOnTouch : MonoBehaviour
{
    public BoolEvent boolEvent;

    private void Start()
    {
        if(boolEvent == null)
        {
            boolEvent = new BoolEvent();
        }
    }

    public void DoIt(bool highLow)
    {
        Debug.Log("invoker received and passed " + highLow.ToString());
        boolEvent.Invoke(highLow);      
    }

}

The following script is what is registered using the Inspector.

public class testRegistrant : MonoBehaviour
{
    public void RegisterThis(bool highLow)
    {      
        Debug.Log("registrant received " + highLow.ToString());
    }
}

Everything but the value that the registered function receives behaves as expected. The registered function always receives false no matter what.

Example execution:
User touches the cube.
Logcat: will pass True
Logcat: invoker received and passed True
Logcat: registrant received False
Logcat: setting False
User touches the cube
Logcat: will pass False
Logcat: invoker received and passed False
Logcat: registrant received False
Logcat: setting True
and so on back and forth…

What am I doing wrong?

I modified ActionOnTouch and testRegistrant a bit (changes are in marked by comments). It now registers two new functions through script, one found on the object doing the invoking and one found on a separate object.

public class ActionOnTouch : MonoBehaviour
{
//edit from here
    public BoolEvent boolEvent;                            
//to here
    private UnityAction<bool> boolAction;

    private void Start()
    {
        if(boolEvent == null)
        {
            boolEvent = new BoolEvent();
        }
//edit from here
        boolAction = BoolAction;                                                            
        boolEvent.AddListener(boolAction);                                          
        testRegistrant testReg = FindObjectOfType<testRegistrant>();
        if (testReg != null)
        {
            boolAction = testReg.RegisterThisToo;
        }
        boolEvent.AddListener(boolAction);
//to here
    }

    public void DoIt(bool highLow)
    {
        if(boolEvent != null)
        {
            Debug.Log("invoker received and passed " + highLow.ToString());
            boolEvent.Invoke(highLow);
        }  
    }

//edit from here
    private void BoolAction(bool highLow)                                            
    {
        Debug.Log("code registrant received " + highLow.ToString());   
    }                                    
//to here
}
public class testRegistrant : MonoBehaviour
{
    public void RegisterThis(bool highLow)
    {   
        Debug.Log("registrant received " + highLow.ToString());
    }

//edit from here
    public void RegisterThisToo(bool highLow)                                   
    {
        Debug.Log("Register this too received " + highLow.ToString());    
    }                                                               
//to here
}

Both functions registered in this way function correctly. The one that is registered using the Inspector does not but it now always reports True, before these changes it always reported False.

I want to be able to register functions through the inspector as well though. Again, what am I doing incorrectly?

So I found out the problem. When I registered the event in the inspector I did not notice the headings on the groupings of the functions. There were two groupings “Dynamic Bool” and “Static Parameters”. I had selected my function I was registering from the “Static Parameter” list when I should have selected the same function from the “Dynamic Bool” list.

Now I understand the presence of the checkbox that appears after selecting my function. It determines the value that will be passed to the function at run time every time it is invoked (when I register it as a “Static Parameter” function.

Where can I read further on this?

3 Likes

I’m guessing the documentation for those methods would be the best place to start, but you seem quite sharp yourself so you can probably tinker with it and learn a great deal about it, assuming you simplify everything down to just what you’re testing and avoid any red herrings or false confirmations!