Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

run method after Start event

Discussion in 'Scripting' started by Garzec, Aug 18, 2019.

  1. Garzec

    Garzec

    Joined:
    Mar 3, 2016
    Posts:
    151
    Hey guys,
    I am trying to get into developing an event driven game. At first I created a singleton with a bunch of events

    Code (CSharp):
    1. public class LevelEvents : MonoBehaviour
    2. {
    3.     public static LevelEvents instance;
    4.  
    5.     public event Action onLevelRead;
    6.     public event Action onLevelSerialized;
    7.  
    8.     private void Awake()
    9.     {
    10.         instance = this;
    11.     }
    12.  
    13.     public void LevelRead()
    14.     {
    15.         if (onLevelRead != null)
    16.         {
    17.             onLevelRead();
    18.         }
    19.     }
    20.  
    21.     public void LevelSerialized()
    22.     {
    23.         if (onLevelSerialized != null)
    24.         {
    25.             onLevelSerialized();
    26.         }
    27.     }
    28. }
    and I would like to create an event chain from reading the level file up to serializing the level. So these events seem to be pretty straight forward.

    My LevelReader is the entry point and dispatches an event after reading the file.

    Code (CSharp):
    1. public class LevelReader : MonoBehaviour
    2. {
    3.     void OnEnable()
    4.     {
    5.         SceneManager.sceneLoaded += ReadLevelFile;
    6.     }
    7.  
    8.     private void OnDestroy()
    9.     {
    10.         SceneManager.sceneLoaded -= ReadLevelFile;
    11.     }
    12.  
    13.     private void ReadLevelFile(Scene scene, LoadSceneMode loadSceneMode)
    14.     {
    15.         // not implemented yet
    16.         LevelEvents.instance.LevelRead();
    17.         Destroy(gameObject);
    18.     }
    19. }
    The serializer will listen to the event and serializes the level. After that, it will dispatch the serialized event for next scripts

    Code (CSharp):
    1. public class LevelSerializer : MonoBehaviour
    2. {
    3.     private void Start()
    4.     {
    5.         LevelEvents.instance.onLevelRead += SerializeLevel;
    6.     }
    7.  
    8.     private void OnDestroy()
    9.     {
    10.         LevelEvents.instance.onLevelRead -= SerializeLevel;
    11.     }
    12.  
    13.     private void SerializeLevel()
    14.     {
    15.         // not implemented yet
    16.         LevelEvents.instance.LevelSerialized();
    17.         Destroy(gameObject);
    18.     }
    19. }
    So there is a problem. The reader dispatches the read event after the scene has loaded. The serializer will listen to this event on start. This is too late, the serializer will not receive a notification. I can't use Awake because this is required for the event singleton registration (LevelEvents).

    I thought about not listening for the sceneLoaded event and call the ReadLevelFile method in the Start method. This is still too late, because the Start method of the LevelReader gets fired and the Serializer will still not receive a notification.

    How can I run the ReadLevelFile method after every Start method was fired? I am hoping to get a better solution than my approaches:

    - Invoke this method after X seconds (timers are dangerous)
    - Run the Update method once (bad solution I think)
    - Write a system that keeps track of every EventSubscriber and fires the first method after every EventSubscriber launched its Start method (too much logic for this, no?)
    - Define an script execution order (bad solution I think)
     
    Last edited: Aug 18, 2019
  2. Kwel

    Kwel

    Joined:
    Jun 9, 2014
    Posts:
    80
    I'm not sure I got the whole idea, but what about a coroutine?
    I found this thread about a similar need: How to initialize after Start()
    I hope it helps :)
     
  3. Garzec

    Garzec

    Joined:
    Mar 3, 2016
    Posts:
    151
    sorry but then I would have to pass in a time in seconds and I think this is bad