Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Resolved How to set Unity Events with unmatching parameters by code?

Discussion in 'Scripting' started by Dennooo, Sep 22, 2021.

  1. Dennooo

    Dennooo

    Joined:
    May 12, 2015
    Posts:
    78
    Hi there,

    the topic seems a bit odd but it is probably quite simple. So let me elaborate:
    When I have a UnityEvent that accepts parameters and I put it on a MonoBehaviour, I can freely assign UnityActions that don't match the type of the parameter.

    Lets assume we have an UnityEvent that accepts integers

    Code (CSharp):
    1. using UnityEngine.Events;
    2.  
    3. [System.Serializable]
    4. public class UnityIntEvent : UnityEvent<int>{}
    and put it on a a simple MonoBehaviour in a scene:

    Code (CSharp):
    1. using UnityEngine;
    2. public class EventCarrier : MonoBehaviour
    3. {
    4.     public UnityIntEvent intEvent;
    5. }
    I can now also select non-matching functions like gameobject.SetActive(bool), via the inspector:
    upload_2021-9-22_15-50-58.png

    However, for my usecase I want to be able to set such bindings via code.
    Type matching subscriptions work simply by e.g., using UnityEventTools.AddPersistentListener() - Any suggestions on how to achieve such a behaviour for non-matching types like functions that don't accept any parameters?:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Events;
    3. using UnityEditor.Events;
    4.  
    5. public class EventCarrier : MonoBehaviour
    6. {
    7.     public UnityIntEvent intEvent;
    8.  
    9.     private void Start()
    10.     {
    11.         // the type-matching case
    12.         UnityEventTools.AddPersistentListener(intEvent, IntParameterMethod);
    13.  
    14.         // how would I go about adding the "NoParameterMethod"?
    15.     }
    16.  
    17.     public void IntParameterMethod(int value) { }
    18.  
    19.     public void NoParameterMethod() { }
    20. }
    21.  
     
    Last edited: Sep 22, 2021
  2. Dennooo

    Dennooo

    Joined:
    May 12, 2015
    Posts:
    78
    One potential solution would be the following:

    Code (CSharp):
    1.     public UnityIntEvent intEvent;
    2.  
    3.     private void Start()
    4.     {
    5.         UnityEventTools.AddPersistentListener(intEvent, (intValue) =>
    6.         {
    7.             NoParameterMethod();
    8.             BoolParameterMethod(true);
    9.         });
    10.     }
    11.  
    12.     public void NoParameterMethod()
    13.     {
    14.         Debug.Log("No parameter method");
    15.     }
    16.  
    17.     public void BoolParameterMethod(bool _bool)
    18.     {
    19.         Debug.Log(_bool.ToString());
    20.     }
    21.  

    However, this has two major drawbacks, making it unsuitable for my usecase.
    1. The lambda expression creates a reference to the class that calls UnityEventTools.AddPersistentListener(). If this no longer exists, the functions will not be called by the event.
    2. Due to the lambda expression it is no longer possible to trace in the inspector which functions are called with which parameters:
    upload_2021-9-23_11-34-29.png

    I appreciate any potential suggestions for a solution to set the events via code without those two drawbacks.
     
  3. Dennooo

    Dennooo

    Joined:
    May 12, 2015
    Posts:
    78
    Found the solution after checking the API more thoroughly. This works like a charm:

    UnityEventTools.AddVoidPersistentListener(intEvent, NoParameterMethod);
    UnityEventTools.AddBoolPersistentListener(intEvent, BoolParameterMethod,true);