How to create game-wide object in Unity3d without singleton?

偶尔善良 提交于 2021-02-10 14:16:25

问题


Is there a way in Unity3d framework to register an object that would be accessible to all entities in all scenes in the game without resorting to singleton pattern (like a game state object)?


回答1:


You could take the following approach:

In the scene where the GameObject is created, in a MonoBehavior script attached to the GameObject:

  • Name the GameObject with "name = ..." in Awake() (or in the Editor)
    • Example: myObject.name = "FindMeInEveryScene";
    • Ref: https://docs.unity3d.com/ScriptReference/Object-name.html
  • Call "DontDestroyOnLoad" on the GameObject in Awake()
    • Example: DontDestroyOnLoad( myObject );
    • Ref: https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html

In the same scene and in subsequent scenes, in MonoBehavior scripts attached to other GameObjects.

  • Find the object with GameObject.Find(...) in Start()
    • Example: globalGameObject = GameObject.Find( "FindMeInEveryScene" );
    • Ref: https://docs.unity3d.com/ScriptReference/GameObject.Find.html

This will allow you to access the GameObject named "FindMeInEveryScene" without a singleton.

To pull it all together...

GlobalGameObject.cs

// Attached to the GameObject that needs to be accessd by any other
// GameObjects and needs to survive between loading scenes
public class GlobalGameObject : MonoBehaviour
{
    static bool gameObjectInitialized = false;

    void Awake()
    {
        if ( !gameObjectInitialized )
        {
            gameObject.name = "FindMeInEveryScene";
            DontDestroyOnLoad( gameObject );
            gameObjectInitialized = true;
        }
    }
}

UsingGameObject.cs

// Attached to GameObjects that need access to the GlobalGameObject
public class UsingGameObject : MonoBehaviour
{
    private GameObject globalGameObject = null;

    void Start()
    {
        globalGameObject = GameObject.Find( "FindMeInEveryScene" );
    }
}



回答2:


You could possibly do it using events but it isn't really the optimal way to use events. I'm intrigued to know why a singleton pattern doesn't work for you as this is pretty much their main purpose.




回答3:


If you aren't going to do this with a static or a singleton, I don't see any point in you using any kind of game state object in your system design. It would do the same thing, but slower (avoid GameObject.Find at all costs). It would lack the guaaranteed uniqueness of the singleton and the easy reference provided by both. I don't understand what tradeoffs you mean but I'll assume they're sound to try and answer your question.

Doing this without a central game state object is going to require a more decentralized solution. Tasks that would be performed by a static game manager are now controlled by the individual objects themselves and notified by other objects.

https://unity3d.com/learn/tutorials/topics/scripting/delegates

The beauty of this method is that objects don't need to know about eachother at all. They just need to listen for events and notify the system that an event has occured. I really can't think of another alternative. Hope this helps. Best of Luck!



来源:https://stackoverflow.com/questions/51682613/how-to-create-game-wide-object-in-unity3d-without-singleton

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!