Search Unity

Event System - OnEnable() or Start()

Discussion in 'UGUI & TextMesh Pro' started by vptb, Sep 3, 2014.

  1. vptb

    vptb

    Joined:
    Jan 15, 2014
    Posts:
    28
    Since we have the new event system for the new UI, I am using the OnClick event on buttons, which then call a specific function on my script. So far so good.

    But I also want to customise those buttons when I enter the scene, for example, on a level selection screen, some buttons should't be interactable because they are still locked. But at the moment to do this I have to either put a script on each button, or create a global script and reference all of the buttons.

    So my question is, can we extend the event system and create an OnEnable() or Start() event? If it is possible please point me in a direction so I can work on it.
     
  2. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    Just make those buttons children of some gameobject and add a CanvasGroup component to that gameobject. You can then set 'interactable' to false and all the buttons will become non interactive.
     
  3. vptb

    vptb

    Joined:
    Jan 15, 2014
    Posts:
    28
    The interactable was just an example, for each level I want to change its text if the level was completed or not, enable star images in case the level is complete. I just wanted to know if it was possible to do something like that with the event system, so that I can call a function to do all that for each button. That way I only need 1 script on the scene and 1 function (that handles the event of each button).
     
  4. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,037
    If what you're looking for is basically a quest/mission manager that toggles objects depending on steps completed, there are ways to do it. The best would be to use delegates. See this example: http://wiki.unity3d.com/index.php?title=CSharpMessenger_Extended

    So what you need is a subscribe option for each event (and possibly a corresponding unsubscribe) so that any number of objects can add their OnWhatever() method to the list.
     
  5. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,225
    You can extend the event system to do the things you describe, but you will also need to extend an Input module to actually send the events:

    Here is a quick example (that doesn't do much!):

    Code (csharp):
    1.  
    2. // interface you implement in your MB to receive events
    3. public interface ICustomHandler : IEventSystemHandler
    4. {
    5.     void OnCustomCode(CustomEventData eventData);
    6. }
    7.  
    8. // Custom data we will send via the event system
    9. public class CustomEventData : BaseEventData
    10. {
    11.     public string m_CustomData;
    12.  
    13.     public CustomEventData(EventSystem eventSystem, string customData)
    14.         : base(eventSystem)
    15.     {
    16.         m_CustomData = customData;
    17.     }
    18. }
    19.  
    20. // container class that holds the execution logic
    21. // called by the event system to delecate the call to
    22. // the intercea
    23. public static class MyCustomEvents
    24. {
    25.     // call that does the mapping
    26.     private static void Execute(ICustomHandler handler, BaseEventData eventData)
    27.     {
    28.         // The ValidateEventData makes sure the passed event data is of the correct type
    29.         handler.OnCustomCode (ExecuteEvents.ValidateEventData<CustomEventData> (eventData));
    30.     }
    31.  
    32.     // helper to return the functor that should be invoked
    33.     public static ExecuteEvents.EventFunction<ICustomHandler> customEventHandler
    34.     {
    35.         get { return Execute; }
    36.     }
    37. }
    38.  
    39. //Custom input module that can send the events
    40. public class MyInputModule : BaseInputModule
    41. {
    42.     // list of objects to invoke on
    43.     public GameObject[] m_TargetObjects;
    44.  
    45.     // called each tick on active input module
    46.     public override void Process()
    47.     {
    48.         // if we don't have targets return
    49.         if (m_TargetObjects == null || m_TargetObjects.Length == 0)
    50.             return;
    51.  
    52.         // for each target invoke our custom event
    53.         foreach (var target in m_TargetObjects)
    54.             ExecuteEvents.Execute (target, new CustomEventData (eventSystem, "Custom Data"), MyCustomEvents.customEventHandler);
    55.     }
    56. }
    57.  
    58. // Class that implements the Handler
    59. public class MyCustomMB : MonoBehaviour, ICustomHandler
    60. {
    61.     public void OnCustomCode(CustomEventData eventData)
    62.     {
    63.         Debug.Log (eventData.m_CustomData);
    64.     }
    65. }
    66.  
     
  6. vptb

    vptb

    Joined:
    Jan 15, 2014
    Posts:
    28
    Thank you Tim C, that's exactly what I was looking for!