Search Unity

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

Discussion in 'Scripting' started by Juxtaposed, Jan 6, 2020.

  1. Juxtaposed

    Juxtaposed

    Joined:
    Aug 23, 2015
    Posts:
    29
    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.

    Code (CSharp):
    1. public class ObjectTouch : MonoBehaviour
    2. {
    3.     private Ray ray;
    4.     private RaycastHit hit;
    5.     private Touch touch;
    6.     Camera cam;
    7.     bool trueFalse = true;
    8.     ActionOnTouch action;
    9.  
    10.     void Start()
    11.     {
    12.         cam = Camera.main;      
    13.     }
    14.  
    15.     // Update is called once per frame
    16.     void Update()
    17.     {
    18.         if (Input.touchCount > 0)
    19.         {  
    20.             touch = Input.GetTouch(0);
    21.             if (touch.phase == TouchPhase.Began)
    22.             {
    23.                 ray = cam.ScreenPointToRay(touch.position);
    24.                 Physics.Raycast(ray, out hit, 100);
    25.  
    26.                 if (hit.collider != null)
    27.                 {
    28.                     if (hit.collider.transform.gameObject.TryGetComponent<ActionOnTouch>(out action))
    29.                     {
    30.  
    31.                         Debug.Log("will pass " + trueFalse.ToString());
    32.                         action.DoIt(trueFalse);
    33.                         if (trueFalse)
    34.                         {                          
    35.                             trueFalse = false;
    36.                             Debug.Log("setting to " + trueFalse.ToString());
    37.                         }
    38.                         else
    39.                         {                          
    40.                             trueFalse = true;
    41.                             Debug.Log("setting to " + trueFalse.ToString());
    42.                         }
    43.                     }
    44.                     else
    45.                     {
    46.                         Debug.Log("object has no action");
    47.                     }
    48.                 }
    49.                 else
    50.                 {
    51.                     Debug.Log("nothing touched");
    52.                 }
    53.             }
    54.         }
    55.     }
    56. }
    ActionOnTouch is placed on objects that have colliders. I have a single cube that has this script on it in my test scene.

    Code (CSharp):
    1. [System.Serializable]
    2. public class BoolEvent : UnityEvent<bool>
    3. {
    4. }
    5.  
    6. public class ActionOnTouch : MonoBehaviour
    7. {
    8.     public BoolEvent boolEvent;
    9.  
    10.     private void Start()
    11.     {
    12.         if(boolEvent == null)
    13.         {
    14.             boolEvent = new BoolEvent();
    15.         }
    16.     }
    17.  
    18.     public void DoIt(bool highLow)
    19.     {
    20.         Debug.Log("invoker received and passed " + highLow.ToString());
    21.         boolEvent.Invoke(highLow);      
    22.     }
    23.  
    24. }
    The following script is what is registered using the Inspector.

    Code (CSharp):
    1. public class testRegistrant : MonoBehaviour
    2. {
    3.     public void RegisterThis(bool highLow)
    4.     {      
    5.         Debug.Log("registrant received " + highLow.ToString());
    6.     }
    7. }
    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?
     
    Last edited: Jan 6, 2020
  2. Juxtaposed

    Juxtaposed

    Joined:
    Aug 23, 2015
    Posts:
    29
    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.

    Code (CSharp):
    1. public class ActionOnTouch : MonoBehaviour
    2. {
    3. //edit from here
    4.     public BoolEvent boolEvent;                            
    5. //to here
    6.     private UnityAction<bool> boolAction;
    7.  
    8.     private void Start()
    9.     {
    10.         if(boolEvent == null)
    11.         {
    12.             boolEvent = new BoolEvent();
    13.         }
    14. //edit from here
    15.         boolAction = BoolAction;                                                            
    16.         boolEvent.AddListener(boolAction);                                          
    17.         testRegistrant testReg = FindObjectOfType<testRegistrant>();
    18.         if (testReg != null)
    19.         {
    20.             boolAction = testReg.RegisterThisToo;
    21.         }
    22.         boolEvent.AddListener(boolAction);
    23. //to here
    24.     }
    25.  
    26.     public void DoIt(bool highLow)
    27.     {
    28.         if(boolEvent != null)
    29.         {
    30.             Debug.Log("invoker received and passed " + highLow.ToString());
    31.             boolEvent.Invoke(highLow);
    32.         }  
    33.     }
    34.  
    35. //edit from here
    36.     private void BoolAction(bool highLow)                                            
    37.     {
    38.         Debug.Log("code registrant received " + highLow.ToString());  
    39.     }                                    
    40. //to here
    41. }
    42.  
    Code (csharp):
    1. public class testRegistrant : MonoBehaviour
    2. {
    3.     public void RegisterThis(bool highLow)
    4.     {  
    5.         Debug.Log("registrant received " + highLow.ToString());
    6.     }
    7.  
    8. //edit from here
    9.     public void RegisterThisToo(bool highLow)                                  
    10.     {
    11.         Debug.Log("Register this too received " + highLow.ToString());    
    12.     }                                                              
    13. //to here
    14. }
    15.  
    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?
     
    Last edited: Jan 6, 2020
  3. Juxtaposed

    Juxtaposed

    Joined:
    Aug 23, 2015
    Posts:
    29
    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?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    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!