Search Unity

[Messaging System] Passing parameters with the event

Discussion in 'Scripting' started by lkarus, Jun 6, 2015.

  1. lkarus

    lkarus

    Joined:
    Feb 25, 2015
    Posts:
    51
    I just followed the "Creating a simple messaging system tutorial here:
    https://unity3d.com/learn/tutorials...chive/events-creating-simple-messaging-system

    I was able to create and register events. What I am wondering is am I able to register an event that takes a parameter?

    So for example, if I have a function 'someListener' that takes a boolean, is there a method that allows me to do something along the line of:

    EventManager.StartListening("test", someListener(false) );

    Still new to Unity and all these stuff so I apologize if its a stupid question/
     
  2. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
  3. raglet

    raglet

    Joined:
    Nov 22, 2015
    Posts:
    30
    BUMP

    Sorry to bump this old thread but I have the exact same doubt and I was hoping you or someone else could help me. I just implemented the EventSystem in my game but would love to have the option to pass a value on trigger. E. g. In my game, I would like to trigger a game level change event when the player reaches a certain score and also pass the current gamelevel int value while triggering. This will allow all listeners to receive the gamelevel and can act accordingly. Any help would be great.

    TIA
     
  4. HiddenMonk

    HiddenMonk

    Joined:
    Dec 19, 2014
    Posts:
    987
    Kk, I wrote up some examples.

    Code (CSharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using UnityEngine.Events;
    5.  
    6. public class LevelChangeUnityEventManager : MonoBehaviour
    7. {
    8.     [System.Serializable]
    9.     public class LevelChangeEvent : UnityEvent<int> {} //Unity event allow up to 4 parameters, but I think people found ways to do more?
    10.  
    11.     public LevelChangeEvent levelChanged;
    12.  
    13.     //void Awake()
    14.     //{
    15.     //    levelChanged = new LevelChangeEvent(); //Since we have it public in a monobehaviour, we dont need to do this. If we did, it would remove any editor stuff we did with the event.
    16.     //}
    17.  
    18.     public void AddListener(UnityAction<int> method)
    19.     {
    20.         levelChanged.AddListener(method);
    21.     }
    22.  
    23.     public void RemoveListener(UnityAction<int> method)
    24.     {
    25.         levelChanged.RemoveListener(method);
    26.     }
    27.  
    28.     public void LevelChanged(int gameLevel)
    29.     {
    30.         levelChanged.Invoke(gameLevel);
    31.     }
    32. }
    Code (CSharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4.  
    5. public class TestLevelChangeUnityEvent : MonoBehaviour
    6. {
    7.     public float coinCount;
    8.     public float changeLevelOnCoinCount = 2f;
    9.     public int changeLevelTo = 2;
    10.     bool hasChanged;
    11.  
    12.     LevelChangeUnityEventManager levelChanged;
    13.  
    14.     void Start() //We run this in start to make sure this runs after our LevelChangeUnityEventManager Awake was called for creating the event (wont matter in our case since we are letting the editor create it)
    15.     {
    16.         levelChanged = (LevelChangeUnityEventManager) GameObject.FindObjectOfType<LevelChangeUnityEventManager>(); //Should probably make this a singleton, but this is just an example
    17.         levelChanged.AddListener(OnLevelChanged); //Assigning the method we want event to call
    18.     }
    19.  
    20.     void Update()
    21.     {
    22.         coinCount += Time.deltaTime;
    23.  
    24.         if(coinCount > changeLevelOnCoinCount)
    25.         {
    26.             if(!hasChanged) levelChanged.LevelChanged(changeLevelTo); //Calling the event
    27.         }else{
    28.             hasChanged = false;
    29.         }
    30.     }
    31.  
    32.     void OnLevelChanged(int gameLevel)
    33.     {
    34.         Debug.Log("Level has changed to " + gameLevel);
    35.         hasChanged = true;
    36.     }
    37.  
    38.     void OnDisable()
    39.     {
    40.         levelChanged.RemoveListener(OnLevelChanged); //To avoid memory leak, unsubscribe the event if this gameobject is disabled / destroyed. Not sure if you need to do this for UnityEvents
    41.     }
    42. }
    The cool thing about UnityEvents is that you dont need to subscribe to events through code.
    For example...
    Code (CSharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4.  
    5. public class TestLevelChangeUnityEventInEditor : MonoBehaviour
    6. {
    7.     public void CallMeWhenLevelChanged(int gameLevel) //Must be public for UnityEvent to see in editor
    8.     {
    9.         Debug.Log("Oh hey, looks like the level changed to " + gameLevel);
    10.     }
    11. }
    To subscribe that method above to the LevelChange event, we go to our LevelChangeUnityEventManager component in the editor and click on that little circle thing to select the object that has the TestLevelChangeUnityEventInEditor component (or drag and drop the object). We then click on the thing on the right that should be saying "No Function" and find our TestLevelChangeUnityEventInEditor component. Within that there should be the CallMeWhenLevelChanged method (was at the top for me). Click that and now the event will call that method.

    Code (CSharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4.  
    5. public class TestLevelChangeEvent : MonoBehaviour
    6. {
    7.     public float coinCount;
    8.     public float changeLevelOnCoinCount = 2f;
    9.     public int changeLevelTo = 2;
    10.     bool hasChanged;
    11.  
    12.     void Awake()
    13.     {
    14.         LevelChangeEventManager.AddListener(OnLevelChanged); //Assigning the method we want event to call
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         coinCount += Time.deltaTime;
    20.  
    21.         if(coinCount > changeLevelOnCoinCount)
    22.         {
    23.             if(!hasChanged) LevelChangeEventManager.LevelChanged(changeLevelTo); //Calling the event
    24.         }else{
    25.             hasChanged = false;
    26.         }
    27.     }
    28.  
    29.     void OnLevelChanged(int gameLevel)
    30.     {
    31.         Debug.Log("Level has changed to " + gameLevel);
    32.         hasChanged = true;
    33.     }
    34.  
    35.     void OnDisable()
    36.     {
    37.         LevelChangeEventManager.RemoveListener(OnLevelChanged); //To avoid memory leak, unsubscribe the event if this gameobject is disabled / destroyed
    38.     }
    39. }
    40.  
    41. //Made static due to laziness
    42. public static class LevelChangeEventManager
    43. {
    44.     public delegate void LevelChangeEvent(int gameLevel);
    45.     static event LevelChangeEvent levelChanged;
    46.  
    47.     public static void AddListener(LevelChangeEventManager.LevelChangeEvent method)
    48.     {
    49.         levelChanged += method;
    50.     }
    51.  
    52.     public static void RemoveListener(LevelChangeEventManager.LevelChangeEvent method)
    53.     {
    54.         levelChanged -= method;
    55.     }
    56.  
    57.     public static void LevelChanged(int gameLevel)
    58.     {
    59.         if(levelChanged != null) levelChanged(gameLevel);
    60.     }
    61. }

    There are different reasons to use either UnityEvent or C# Events, of which you can research about.
     
    Last edited: Feb 11, 2016
  5. raglet

    raglet

    Joined:
    Nov 22, 2015
    Posts:
    30
    Hey thanks a lot HiddenMonk. With some help from your example and the unity page linked below I managed to rewrite that the tutorial script to accept one argument and it works perfectly. The same code can be extended for 2, 3 or more parameters.

    LINK: http://docs.unity3d.com/ScriptReference/Events.UnityEvent_1.html

    Here's the updated code for anyone who wants to use it

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Events;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. [System.Serializable]
    7. public class ThisEvent : UnityEvent<int>
    8. {
    9. }
    10.  
    11. public class EventManagerOneArgument : MonoBehaviour {
    12.  
    13.     private Dictionary <string, ThisEvent> eventDictionary;
    14.  
    15.     private static EventManagerOneArgument eventManagerArgs;
    16.    
    17.     public static EventManagerOneArgument instance
    18.     {
    19.         get
    20.         {
    21.             if (!eventManagerArgs)
    22.             {
    23.                 eventManagerArgs = FindObjectOfType (typeof (EventManagerOneArgument)) as EventManagerOneArgument;
    24.                
    25.                 if (!eventManagerArgs)
    26.                 {
    27.                     Debug.LogError ("There needs to be one active EventManger script on a GameObject in your scene.");
    28.                 }
    29.                 else
    30.                 {
    31.                     eventManagerArgs.Init ();
    32.                 }
    33.             }
    34.            
    35.             return eventManagerArgs;
    36.         }
    37.     }
    38.  
    39.     void Init ()
    40.     {
    41.         if (eventDictionary == null)
    42.         {
    43.             eventDictionary = new Dictionary<string, ThisEvent>();
    44.         }
    45.     }
    46.  
    47.     public static void startListening(string eventName, UnityAction<int> listener){
    48.         ThisEvent thisEvent = null;
    49.         if (instance.eventDictionary.TryGetValue (eventName, out thisEvent))
    50.         {
    51.             thisEvent.AddListener (listener);
    52.         }
    53.         else
    54.         {
    55.             thisEvent = new ThisEvent();
    56.             thisEvent.AddListener (listener);
    57.             instance.eventDictionary.Add (eventName, thisEvent);
    58.         }
    59.     }
    60.  
    61.     public static void stopListening(string eventName, UnityAction<int> listener){
    62.         if (eventManagerArgs == null) return;
    63.         ThisEvent thisEvent = null;
    64.         if (instance.eventDictionary.TryGetValue (eventName, out thisEvent))
    65.         {
    66.             thisEvent.RemoveListener (listener);
    67.         }
    68.     }
    69.  
    70.     public static void triggerEvent(string eventName, int value){
    71.         ThisEvent thisEvent = null;
    72.         if (instance.eventDictionary.TryGetValue (eventName, out thisEvent))
    73.         {
    74.             thisEvent.Invoke (value);
    75.         }
    76.     }
    77. }
    78.  
     
    tarun018 and HiddenMonk like this.
  6. DaDarkDan

    DaDarkDan

    Joined:
    Jan 16, 2017
    Posts:
    7
    another BUMP

    Seeing those examples I was wondering if it was possible to write this exact example with a generic type? Like, it does not matter if its a bool or string or int that I'm passing.
    Code (CSharp):
    1. UnityAction<T>
    Anyone? TIA
     
    StDanko likes this.
  7. chrisWhyTea

    chrisWhyTea

    Joined:
    Mar 24, 2017
    Posts:
    1
    Sorry for the Bump but i had this problem too, but couldn't found any nice solution on the internet... (Expect this thread) and solved the "using generic type problem" instead of "UnityAction<T>" and "UnityEvent<T>" use "UnityAction<object>" and "UnityEvent<object>".

    This way almost anything can be used as parameter but needs to be casted to the dessired type in the UnityAction. Its really ugly but till now it works...

    Code (CSharp):
    1. public class TestScript: MonoBehaviour
    2. {
    3.     private void OnEnable()
    4.     {
    5.         EventManager.StartListening("test", testFn);
    6.     }
    7.     private void testFn(object value){
    8.         var v = value as int;
    9.         Debug.Log(v)
    10. }
     
    Last edited: May 19, 2017
    Juruhn likes this.
  8. RacketRebel

    RacketRebel

    Joined:
    Jun 3, 2017
    Posts:
    7
    Looking into the same problem i think the best way is to use lambda expressions, than the EventManager is without any modifications and you are free to use any number and type of parameters.

    Code (CSharp):
    1. void OnEnable() {
    2.         EventManager.StartListening("MyFunction", () => { MyFunction(12);} );
    3.         // action = () => { Function(x);}
    4.  
    5. EventManager.StartListening("My2Function", () => { My2Function(12, "ActionDone");} );
    6.         // action = () => { Function(x, s);}
    7.     }
    8.  
    9.  
    10.     void OnDisable() {
    11.         EventManager.StopListening("MyFunction", () => { MyFunction(12);} );
    12. EventManager.StartListening("My2Function", () => { My2Function(12, "ActionDone");} );
    13.         // action = () => { Function(x, s);}
    14.     }
    15.  
    16.     void MyFunction(int seconds) {
    17.         Debug.Log(seconds.ToString());
    18.  
    19.     }
    20.  
    21.     void My2Function(int seconds, string myText) {
    22.         Debug.Log(seconds.ToString() + myText);
    23.  
    24.     }
    25.  
     
    dprydereid and Bedov like this.
  9. Meds_

    Meds_

    Joined:
    Jul 30, 2013
    Posts:
    1

    I know I'm late too this, but it's exactly what I need, but as far as I can you can't pass parameters to the Invoke method so

    Code (csharp):
    1.  
    2.     public static void triggerEvent(string eventName, int value){
    3.         ThisEvent thisEvent = null;
    4.         if (instance.eventDictionary.TryGetValue (eventName, out thisEvent))
    5.         {
    6.             thisEvent.Invoke (value);
    7.         }
    8.  
    won't work? Did this work for you??
     
  10. no_skills_ben

    no_skills_ben

    Joined:
    May 24, 2018
    Posts:
    2
    EDIT - this code works but see my second post for a better version using a json serialized string of a scriptable object.

    I tested it using raglets code for passing the int and ChrisWhyTea's idea of using object so you can pass any parameter(and any number of parameters at the same time by using scriptable objects or a game object with a script attached to it.) The only thing is I left the var as a var. Using the "as int" or as string gave me errors.

    event manager:
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine.Events;
    3. using UnityEngine;
    4.  
    5. /*
    6. Event messaging system for Unity with flexible parameter passing
    7. Code is 99% from the untiy tutorial here: https://unity3d.com/learn/tutorials/topics/scripting/events-creating-simple-messaging-system
    8. the other 1% is from this forum post: https://forum.unity.com/threads/messaging-system-passing-parameters-with-the-event.331284/
    9. */
    10.  
    11.  
    12.  
    13. // Replacement of the basic Unityevent with a unity event that has an object parameter <T> did not work
    14. [System.Serializable]
    15. public class ThisEvent : UnityEvent<object> { }
    16.  
    17.  
    18. // This class holds the messages, you need to attatch it to one gameobject in the scene
    19. public class EventManager : MonoBehaviour {
    20.     private Dictionary<string, ThisEvent> eventDictionary;
    21.  
    22.     private static EventManager eventManger;
    23.  
    24.     // grabs the instance of the event manager
    25.     public static EventManager Instance {
    26.         get
    27.         {
    28.             if (!eventManger)
    29.             {
    30.                 eventManger = FindObjectOfType(typeof(EventManager)) as EventManager;
    31.  
    32.                 if (!eventManger)
    33.                 {
    34.                     Debug.Log("There needs to be one active EventManager script on a gameobject in your scene.");
    35.                 }
    36.                 else
    37.                 {
    38.                     eventManger.Init();
    39.                  
    40.                 }
    41.             }
    42.             return eventManger;
    43.         }
    44.     }
    45.  
    46.     // creates dictionary for the events
    47.     void Init ()
    48.     {
    49.         if(eventDictionary == null)
    50.         {
    51.             eventDictionary = new Dictionary<string, ThisEvent>();
    52.         }
    53.     }
    54.  
    55.     // function called to insert an event in the dictionary
    56.     public static void StartListening (string eventName, UnityAction<object> listener)
    57.     {
    58.         ThisEvent thisEvent = null;
    59.         if (Instance.eventDictionary.TryGetValue (eventName,out thisEvent))
    60.         {
    61.             thisEvent.AddListener(listener);
    62.         }
    63.         else
    64.         {
    65.             thisEvent = new ThisEvent();
    66.             thisEvent.AddListener(listener);
    67.             Instance.eventDictionary.Add(eventName, thisEvent);
    68.         }
    69.     }
    70.  
    71.     // removes an event from the dictionary
    72.     public static void StopListening (string eventName, UnityAction<object> listener)
    73.     {
    74.         if (eventManger == null) return;
    75.         ThisEvent thisEvent = null;
    76.         if (Instance.eventDictionary.TryGetValue(eventName, out thisEvent))
    77.         {
    78.             thisEvent.RemoveListener(listener);
    79.         }
    80.     }
    81.  
    82.     // event trigger with an object passed as a parameter.
    83.     public static void TriggerEvent (string eventName, object variant)
    84.     {
    85.         ThisEvent thisEvent = null;
    86.         if (Instance.eventDictionary.TryGetValue(eventName, out thisEvent))
    87.         {
    88.             thisEvent.Invoke(variant);
    89.         }
    90.     }
    91. }
    92.  

    The class for the object receiving the message
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Events;
    3.  
    4.  
    5. // Example of registering a new event with an object as a parameter
    6. public class test1 : MonoBehaviour {
    7.  
    8.     // make sure to include the object here
    9.     private UnityAction<object> someListener;
    10.     private void Awake()
    11.     {
    12.         //make sure to include the object here
    13.         someListener = new UnityAction<object>(SomeFunction);
    14.     }
    15.  
    16.     private void OnEnable()
    17.     {
    18.         EventManager.StartListening("test",someListener);
    19.     }
    20.  
    21.     private void OnDisable()
    22.     {
    23.         EventManager.StopListening("test", someListener);
    24.     }
    25.  
    26.     // var has worked for strings and int. I haven't tried it yet but I'm guessing scriptable ojects or just prefabs with a script that just holds variables can be used to send unlimited parameters.
    27.     void SomeFunction(object variant)
    28.     {
    29.         var v = variant;
    30.  
    31.         Debug.Log("some function was called " + v.ToString());
    32.     }
    33. }

    An example of the message being sent:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3.  
    4. // Example of how to trigger an existing event with an object as a parameter.
    5. public class EventTriggerTest : MonoBehaviour {
    6.  
    7.  
    8.     // Update is called once per frame
    9.     void Update () {
    10.         if (Input.GetKeyDown("q"))
    11.         {
    12.             string variantTest = "test123";
    13.             EventManager.TriggerEvent("test",variantTest);
    14.         }
    15.     }
    16. }
     
    Last edited: Jun 2, 2018
  11. no_skills_ben

    no_skills_ben

    Joined:
    May 24, 2018
    Posts:
    2
    In retrospect <object> is not super great. you can use the code I posted previously and replace <object> with <GameObject> instead and use an empty object with a c# script attached to it but I think the easiest and most flexible was to pass messages trough the event is by serializing a scriptable object to a json string and passing it that way.

    With that method you will only need 1 event manager with 1 string parameter to pass an unlimited number of parameters.
    Just remember to use the same scriptable object class to send and recieve a specific event.


    place on an empty (or any object in the scene)
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine.Events;
    3. using UnityEngine;
    4.  
    5.  
    6. /*
    7. Event messaging system for Unity with flexible parameter passing
    8. Code is 99% from the untiy tutorial here: https://unity3d.com/learn/tutorials/topics/scripting/events-creating-simple-messaging-system
    9. the other 1% is from this forum post: https://forum.unity.com/threads/messaging-system-passing-parameters-with-the-event.331284/
    10. */
    11.  
    12.  
    13.  
    14. // Replacement of the basic Unityevent with a unity event that has a string that will be used to serialize JSON
    15. [System.Serializable]
    16. public class ThisEvent : UnityEvent<string> { }
    17.  
    18.  
    19. // This class holds the messages, you need to attatch it to one gameobject in the scene
    20. public class EventManager : MonoBehaviour {
    21.     private Dictionary<string, ThisEvent> eventDictionary;
    22.  
    23.     private static EventManager eventManger;
    24.  
    25.     // grabs the instance of the event manager
    26.     public static EventManager Instance {
    27.         get
    28.         {
    29.             if (!eventManger)
    30.             {
    31.                 eventManger = FindObjectOfType(typeof(EventManager)) as EventManager;
    32.  
    33.                 if (!eventManger)
    34.                 {
    35.                     Debug.Log("There needs to be one active EventManager script on a gameobject in your scene.");
    36.                 }
    37.                 else
    38.                 {
    39.                     eventManger.Init();
    40.                    
    41.                 }
    42.             }
    43.             return eventManger;
    44.         }
    45.     }
    46.  
    47.     // creates dictionary for the events
    48.     void Init ()
    49.     {
    50.         if(eventDictionary == null)
    51.         {
    52.             eventDictionary = new Dictionary<string, ThisEvent>();
    53.         }
    54.     }
    55.  
    56.     // function called to insert an event in the dictionary
    57.     public static void StartListening (string eventName, UnityAction<string> listener)
    58.     {
    59.         ThisEvent thisEvent = null;
    60.         if (Instance.eventDictionary.TryGetValue (eventName,out thisEvent))
    61.         {
    62.             thisEvent.AddListener(listener);
    63.         }
    64.         else
    65.         {
    66.             thisEvent = new ThisEvent();
    67.             thisEvent.AddListener(listener);
    68.             Instance.eventDictionary.Add(eventName, thisEvent);
    69.         }
    70.     }
    71.  
    72.     // removes an event from the dictionary
    73.     public static void StopListening (string eventName, UnityAction<string> listener)
    74.     {
    75.         if (eventManger == null) return;
    76.         ThisEvent thisEvent = null;
    77.         if (Instance.eventDictionary.TryGetValue(eventName, out thisEvent))
    78.         {
    79.             thisEvent.RemoveListener(listener);
    80.         }
    81.     }
    82.  
    83.     // event trigger with a string passed as a parameter.
    84.     public static void TriggerEvent (string eventName, string json)
    85.     {
    86.         ThisEvent thisEvent = null;
    87.         if (Instance.eventDictionary.TryGetValue(eventName, out thisEvent))
    88.         {
    89.             // finally passes the message.
    90.             thisEvent.Invoke(json);
    91.         }
    92.     }
    93. }

    place on objects that will receive the message, change "test" to whatever message handle you want, test_parameters to your own scriptable object and your own code instead of the debug log.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Events;
    3.  
    4.  
    5. // Example of registering a new event with a serialized scriptable object
    6. public class Template_RecieveEvent : MonoBehaviour
    7. {
    8.  
    9.     // make sure to include the string here.
    10.     private UnityAction<string> EventListener;
    11.  
    12.     private void Awake()
    13.     {
    14.         //make sure to include the string here
    15.         EventListener = new UnityAction<string>(EventTriggered);
    16.     }
    17.  
    18.     private void OnEnable()
    19.     {
    20.         EventManager.StartListening("test", EventListener);
    21.     }
    22.  
    23.     private void OnDisable()
    24.     {
    25.         EventManager.StopListening("test", EventListener);
    26.     }
    27.  
    28.     // the actual event that will recieve the "message"
    29.     void EventTriggered(string jsonVars)
    30.     {
    31.         // Remeber to use the same scriptable object when sending and recieving the same message since thats what you serialized.
    32.         test_parameters objVars = ScriptableObject.CreateInstance<test_parameters>();
    33.         // The fromjson might also work but it gave me some errors so I just switched to overwrite.
    34.         JsonUtility.FromJsonOverwrite(jsonVars, objVars);
    35.  
    36.         // from the test you see int was still included even though it was never set it just kept it to 0.
    37.         Debug.Log("some function was called " + jsonVars + " " + objVars.stringInfo);
    38.     }
    39. }

    Example of creating an instance of a scriptable object, serializing it and passing it while triggering the "test" event. Remeber to use the same scriptable object class when sending and receiving a specific message.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. /*
    4. *  Example how to send a json serialized object to objects that have registered to a "test" message.
    5. * Requires a GameObject in the scne with the EventManager script attached to it.
    6. */
    7.  
    8. public class Template_SendEvent : MonoBehaviour {
    9.     // Test parameters is just a sriptable object class with a bool, a string and an int.
    10.     // scriptable objects info: https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects
    11.  
    12.     private test_parameters objVars;
    13.    
    14.     // Update is called once per frame
    15.     void Update()
    16.     {
    17.         // just to test, message deployed when pressing q
    18.         if (Input.GetKeyDown("q"))
    19.         {
    20.             // uses createinstance instead of new test_parameters because it's a scriptable object.
    21.             objVars = ScriptableObject.CreateInstance<test_parameters>();
    22.             objVars.BoolInfo = true;
    23.             objVars.stringInfo = "Im a string";
    24.  
    25.             // converts to a json string, so the messge only needs 1 string to pass a large number of diverse parameters. and multiple objects subscribed to the message can pick the ones they need.
    26.             string jsonVars = JsonUtility.ToJson(objVars);
    27.  
    28.             // passing the json string as a parameter.
    29.             EventManager.TriggerEvent("test", jsonVars);
    30.         }
    31.     }
    32. }

    just the example scriptable object used in the example.
    the gist is replace monobehaviour with ScriptableObject but if you haven't used tyhem before go to https://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/scriptable-objects
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. // just a scriptable object class to test passing json serialized parameters as strings with an event manager
    4. public class test_parameters : ScriptableObject {
    5.     public int numberInfo;
    6.     public string stringInfo;
    7.     public bool BoolInfo;
    8. }
     
    dexterhhhh, kuronoir and Nikag like this.
  12. dexterhhhh

    dexterhhhh

    Joined:
    Mar 15, 2023
    Posts:
    4
    Sorry for the Bump. This solution is great and totally resolved the method parameters passing problem. Just one thing is not convenient, this event system is not compatible with methods that have no parameters. Right now the function has to have a string parameter, if a non-parameters method is listening to an event, you are going to have an error that says "No overload for 'xxxxx' matches delegate 'UnityAction<string>'.
    Can this event system also be compatible with non-parameters function, so we don't need one for parameters one for non-parameters and two event system separately
     
  13. hdaniel_unity

    hdaniel_unity

    Joined:
    Dec 30, 2021
    Posts:
    14
    Yes, you can just duplicate the functions to a version with no argument. C# is polymorphic, which means that the right function version will be called depending on the parameters passed. This tutorial (at 22:14) shows how to have base no parameter events and also events with an object parameter. Although it uses object as the type for event data rather than a scriptable object, the principle is the same.