Поиск…


замечания

ScriptableObjects с AssetBundles

Обратите внимание на добавление сборных данных в AssetBundles, если они содержат ссылки на ScriptableObjects. Поскольку ScriptableObjects по существу являются активами, Unity создает их дубликаты перед добавлением их в AssetBundles, что может привести к нежелательному поведению во время выполнения.

Когда вы загружаете такой GameObject из AssetBundle, может потребоваться повторно загрузить атрибуты ScriptableObject в загруженные сценарии, заменив связанные объекты. См. Injection Dependency Injection

Вступление

ScriptableObjects - это сериализованные объекты, которые не привязаны к сценам или игровым объектам как MonoBehaviours. Иными словами, это данные и методы, связанные с файлами активов внутри вашего проекта. Эти объекты ScriptableObject могут быть переданы MonoBehaviours или другим ScriptableObjects, к которым можно получить доступ к их общедоступным методам.

Из-за своей природы как сериализованных активов они делают отличные классы менеджеров и источники данных.

Создание объектов ScriptableObject

Ниже приведена простая реализация ScriptableObject.

using UnityEngine;

[CreateAssetMenu(menuName = "StackOverflow/Examples/MyScriptableObject")]
public class MyScriptableObject : ScriptableObject
{
    [SerializeField]
    int mySerializedNumber;

    int helloWorldCount = 0;

    public void HelloWorld()
    {
        helloWorldCount++;
        Debug.LogFormat("Hello! My number is {0}.", mySerializedNumber);
        Debug.LogFormat("I have been called {0} times.", helloWorldCount);
    }
}

Добавив атрибут CreateAssetMenu к классу, Unity перечислит его в подменю « Активы / Создать» . В этом случае это находится в разделе Assets / Create / StackOverflow / Examples .

После создания экземпляры ScriptableObject могут быть переданы другим скриптам и ScriptableObjects через Инспектор.

using UnityEngine;

public class SampleScript : MonoBehaviour {

    [SerializeField]
    MyScriptableObject myScriptableObject;

    void OnEnable()
    {
        myScriptableObject.HelloWorld();
    }
}

Создание экземпляров ScriptableObject с помощью кода

Вы создаете новые экземпляры ScriptableObject через ScriptableObject.CreateInstance<T>()

T obj = ScriptableObject.CreateInstance<T>();

Где T расширяет ScriptableObject .

Не создавайте ScriptableObjects, вызывая их конструкторы, т.е. new ScriptableObject() .

Создание ScriptableObjects по коду во время выполнения редко вызвано, потому что их основным использованием является сериализация данных. На этом этапе вы также можете использовать стандартные классы. Это чаще встречается при написании расширений редактора сценариев.

ScriptableObjects сериализуются в редакторе даже в PlayMode

Следует проявлять особую осторожность при доступе к сериализованным полям экземпляра ScriptableObject.

Если поле отмечено public или сериализованным через SerializeField , изменение его значения является постоянным. Они не сбрасываются при выходе из режима воспроизведения, такого как MonoBehaviours. Иногда это может быть полезно, но это также может вызвать беспорядок.

Из-за этого лучше всего делать сериализованные поля только для чтения и вообще избегать публичных полей.

public class MyScriptableObject : ScriptableObject
{
    [SerializeField]
    int mySerializedValue;

    public int MySerializedValue
    {
        get { return mySerializedValue; }
    }
}

Если вы хотите сохранить общедоступные значения в объекте ScriptableObject, которые были сброшены между сеансами воспроизведения, рассмотрите возможность использования следующего шаблона.

public class MyScriptableObject : ScriptableObject
{
    // Private fields are not serialized and will reset to default on reset
    private int mySerializedValue;

    public int MySerializedValue
    {
        get { return mySerializedValue; }
        set { mySerializedValue = value; }
    }
}

Найти существующие объекты ScriptableObject во время выполнения

Чтобы найти активные объекты ScriptableObject во время выполнения, вы можете использовать Resources.FindObjectsOfTypeAll() .

T[] instances = Resources.FindObjectsOfTypeAll<T>();

Где T - тип экземпляра ScriptableObject, который вы ищете. Active означает, что он ранее был загружен в память в какой-либо форме.

Этот метод очень медленный, поэтому не забудьте кэшировать возвращаемое значение и не часто его вызывать. Предпочтительным вариантом является ссылка на ScriptableObjects непосредственно в ваших сценариях.

Совет. Вы можете поддерживать собственные коллекции экземпляров для более быстрого поиска. Попросите свои ScriptableObjects зарегистрироваться в общую коллекцию во время OnEnable() .



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow