我知道这是一篇较旧的帖子,但当我在寻找一种方法来统一自动实例化静态 GameObject 时,它在 Google 的前几个结果中。不确定旧版本,但这与 5.6.1 完美结合。我需要一种方法来存储游戏设置并从许多场景中访问它们。我还需要访问某些只能从 MonoBehaviour 访问的统一功能(如屏幕资源等),因此不能选择普通的静态类。我想出的基本上是一个单例类型的统一游戏对象,如果您获得对实例的引用,并且场景中没有这些,它会自动创建它。如果存在,(更改回创建它的场景)复制的自毁,因此游戏中只有一个。
我想要这个的原因是因为我使用 Unity ScriptableObjects 来存储数据,因为它们可以在编辑和运行时从检查器中编辑,并且在运行时的更改不会恢复(如果您使用旧的 OnGUI 非常方便,因为您可以将矩形位置存储在可编写脚本的对象中,并观察您的控件在运行时四处移动,并且在您停止播放模式时位置不会恢复)
这是我非常基础的课程(从中删除了我的特定数据)
using UnityEngine;
public class GameSettings : MonoBehaviour
{
private static GameSettings _instance;
public static GameSettings Instance
{
get
{
if (_instance != null) return _instance;
else
{
Setup();
return _instance;
}
}
}
public void Start ()
{
DontDestroyOnLoad(this);
}
public void Awake()
{
if (_instance != null) Destroy(this);
}
public static void Setup()
{
GameObject settings = GameObject.Find("GameSettings");
if (settings == null)
{
settings = new GameObject("GameSettings");
settings.AddComponent<GameSettings>();
}
_instance = settings.GetComponent<GameSettings>();
}
}
您可以使用这两种方式:
1:在您的第一个场景中将其添加到游戏对象(这样您就可以从检查器中修改值)。如果您更改回该场景,由于检查 _instance,它不会创建副本。如果您确实将其手动添加到场景中,请确保将 GameObject.Find 字符串编辑为您的 GameObject 的名称,否则它将创建一个新的。
2:只需创建对 ClassName.Instance 的引用,如果它不存在,它将自动创建对象。
场景的示例实现脚本:
public class TestScene : MonoBehaviour
{
private GameSettings _settings;
public void Awake()
{
_settings = GameSettings.Instance;
}
public void Start()
{
}
public void Update()
{
}
}
现在您只需将公共数据(字符串、int 等)添加为 GameSettings 类的公共非静态成员,然后简单地使用 _settings.MemberName 即可访问数据。
希望这可以帮助那些正在寻找一种动态自动创建游戏对象的方法的人。如果您构建一个 Prefab 并将这个脚本附加到它的任何对象上,这也可以工作。可以方便地在特定场景中动态创建 UI 元素。
如果您只在一个场景中需要它并且不需要它在关卡加载中持续存在(例如在某些场景中自动实例化某些 UI 元素,例如 npc 对话框等),只需从类的 start 函数中删除 DontDestroyOnLoad那是附加在预制件上的。