问题
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