Я знаю, что это более старое сообщение, но оно в нескольких лучших результатах Google, когда я искал способ автоматического создания статического GameObject в единстве. не уверен в более старых версиях, но это работает безупречно с 5.6.1. Мне нужен был способ хранения настроек игры и доступа к ним из многих сцен. Я также нуждался в доступе к определенным функциям единства (например, res экрана и т. Д.), Которые доступны только из MonoBehaviour, поэтому простой статический класс не был вариантом. то, что я придумал, - это в основном однопользовательское единство GameObject, что, если вы получаете ссылку на экземпляр, и нет ни одного из них в сцене, он автоматически создает его. если он существует (сменяется обратно на сцену, где он был создан), дубликат самоуничтожается, так что в игре есть только один из них.
Причина, по которой я хотел этого, заключалась в том, что я использую 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: добавьте его в GameObject в свою первую сцену (чтобы вы могли изменять значения от инспектора). Если вы когда-нибудь перейдете к этой сцене, он не создаст дубликат из-за проверки на _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 для получить доступ к данным.
надеюсь, что это поможет кому-то искать способ автоматического создания GameObjects на лету. Это также работает, если вы создаете Prefab и привязываете этот скрипт к любому из его объектов. Может быть удобно для автоматического создания элементов пользовательского интерфейса «на лету» в определенных сценах.
Если вам это нужно только в одной сцене и не нужно, чтобы он сохранялся на разных уровнях нагрузки (например, автоматическое создание определенных элементов пользовательского интерфейса в определенных сценах, таких как npc-диалог и т. Д.), Просто удалите DontDestroyOnLoad из функции запуска класс, прикрепленный к сборке.