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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Systems start before MonoBehaviour.Awake()

Discussion in 'Entity Component System' started by Cell-i-Zenit, May 22, 2020.

  1. Cell-i-Zenit

    Cell-i-Zenit

    Joined:
    Mar 11, 2016
    Posts:
    290
    Hi,

    i have a singleton monobehaviour where i have assigned all the stuff (materials, meshes etc) i need for my systems. I also use Odin to nicely format everything.

    But now i have a problem: Some systems need some stuff in the OnCreate Method which is computed in the Awake() method of the singleton. The problem is that the OnCreate methods of the systems are started before the Awake Method happens...

    I now cannot use the Singleton as a "resource manager" anymore...

    Any ideas to solve this?
     
  2. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    I am also using this method for material referencing for systems that need those.
    Have you tried instead of OnCreate, using OnStartRunning?
     
    Last edited: May 22, 2020
  3. agurskis22cans

    agurskis22cans

    Joined:
    Jul 17, 2019
    Posts:
    9
    Yes, this is true. However, OnStartRunning() runs only if the system starts running. In a case it doesn't find any queries available, it doesn't run. It might be a problem here.
     
  4. Cell-i-Zenit

    Cell-i-Zenit

    Joined:
    Mar 11, 2016
    Posts:
    290
    My systems start running on startup so this wouldnt work right?
     
  5. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,993
    You have a few options:
    1) Make the resource management a hybrid component.
    2) Add an event that systems can subscribe to that get invoked from Awake.
    3) Have a system that reacts ti a hybrid component and then invokes events that other systems can subscribe to.

    Personally I would go with option 1, but if I really needed state in the system option 3 isn't bad because it also avoids statics.
     
  6. Cell-i-Zenit

    Cell-i-Zenit

    Joined:
    Mar 11, 2016
    Posts:
    290
    I went with 4.) have a "GetResourceX" method on that singleton which creates the resource if it doesnt exist

    Its maybe the simplest of all methods, but now i need to do that for each resource which needs computation
     
  7. Aratow

    Aratow

    Joined:
    Nov 4, 2016
    Posts:
    49
    If your monobehaviour is run first, the created entities that will act as prefabs should already exist and so, it should always find those queries in the systems.
     
  8. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Puts your data in ScriptableObject's and load them with Resources.Load. You can also have a singleton SO that contains other SO's. That's the simplest most direct approach I know of.
     
    Krajca likes this.
  9. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    To get you started. This leverages naming to avoid hard coding strings as far as the resources themselves, just name your SO after it's type. Add fields that contain other SO's to use it as an SO container.

    Code (csharp):
    1.  
    2. [CreateAssetMenu(menuName = @"Custom/GameConfigData")]
    3.     public class GameConfigData : ScriptableObject
    4.     {
    5.         private static GameConfigData instance;
    6.         public static GameConfigData Instance
    7.         {
    8.             get
    9.             {
    10.                 if (instance == null)
    11.                 {
    12.                     instance = Resources.Load(typeof(GameConfigData).Name, typeof(GameConfigData)) as GameConfigData;
    13.                 }
    14.                 return instance;
    15.             }
    16.         }
    17.  
    18.     }
    19.  
     
  10. ZzAtomiic

    ZzAtomiic

    Joined:
    Mar 17, 2018
    Posts:
    6
    You can also tag the systems with the
    [DisableAutoCreation]
    attribute:
    https://docs.unity3d.com/Packages/c...ty.Entities.DisableAutoCreationAttribute.html
    And manually create the systems that need initialization to happen after the Awake of MonoBehaviours.