unity3d
ScriptableObject
Szukaj…
Uwagi
ScriptableObjects with AssetBundles
Podczas dodawania prefabrykatów do AssetBundles należy zwrócić uwagę, jeśli zawierają one odwołania do ScriptableObjects. Ponieważ ScriptableObjects są zasadniczo zasobami, Unity tworzy ich duplikaty przed dodaniem ich do AssetBundles, co może spowodować niepożądane zachowanie podczas działania.
Podczas ładowania takiego GameObject z AssetBundle może być konieczne ponowne włączenie zasobów ScriptableObject do załadowanych skryptów, zastępując je w pakiecie. Patrz Wstrzyknięcie zależności
Wprowadzenie
ScriptableObjects to obiekty serializowane, które nie są powiązane ze scenami lub obiektami gry, jak MonoBehaviours. Innymi słowy, są to dane i metody powiązane z plikami zasobów w projekcie. Te zasoby ScriptableObject można przekazać do MonoBehaviours lub innych ScriptableObjects, gdzie można uzyskać dostęp do ich metod publicznych.
Ze względu na swój charakter jako zserializowane zasoby stanowią doskonałe klasy menedżerskie i źródła danych.
Tworzenie zasobów ScriptableObject
Poniżej znajduje się prosta implementacja 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);
}
}
Dodając atrybut CreateAssetMenu
do klasy, Unity wyświetli go w podmenu Assets / Create . W tym przypadku znajduje się pod Assets / Create / StackOverflow / Examples .
Po utworzeniu instancje ScriptableObject mogą być przekazywane do innych skryptów i ScriptableObjects za pośrednictwem Inspektora.
using UnityEngine;
public class SampleScript : MonoBehaviour {
[SerializeField]
MyScriptableObject myScriptableObject;
void OnEnable()
{
myScriptableObject.HelloWorld();
}
}
Twórz wystąpienia ScriptableObject za pomocą kodu
Nowe instancje ScriptableObject tworzy się za pomocą ScriptableObject.CreateInstance<T>()
T obj = ScriptableObject.CreateInstance<T>();
Gdzie T
rozszerza ScriptableObject
.
Nie twórz ScriptableObjects przez wywoływanie ich konstruktorów, tj.
new ScriptableObject()
.
Rzadko wywoływane jest tworzenie ScriptableObjects za pomocą kodu w czasie wykonywania, ponieważ ich głównym zastosowaniem jest serializacja danych. W tym momencie możesz równie dobrze użyć klas standardowych. Jest to bardziej powszechne, gdy piszesz rozszerzenia edytora.
Obiekty ScriptableObjects są serializowane w edytorze nawet w PlayMode
Należy zachować szczególną ostrożność podczas uzyskiwania dostępu do pól zserializowanych w instancji ScriptableObject.
Jeśli pole jest oznaczone jako public
lub zserializowane przez SerializeField
, zmiana jego wartości jest trwała. Nie resetują się przy wychodzeniu z trybu gry, jak robią to MonoBehaviours. Czasami może to być przydatne, ale może również popsuć bałagan.
Z tego powodu najlepiej jest zrobić zserializowane pola tylko do odczytu i całkowicie unikać pól publicznych.
public class MyScriptableObject : ScriptableObject
{
[SerializeField]
int mySerializedValue;
public int MySerializedValue
{
get { return mySerializedValue; }
}
}
Jeśli chcesz przechowywać wartości publiczne w ScriptableObject, które są resetowane między sesjami odtwarzania, rozważ użycie następującego wzorca.
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; }
}
}
Znajdź istniejące obiekty ScriptableObjects w czasie wykonywania
Aby znaleźć aktywne ScriptableObjects podczas działania, możesz użyć Resources.FindObjectsOfTypeAll()
.
T[] instances = Resources.FindObjectsOfTypeAll<T>();
Gdzie T
jest typem szukanej instancji ScriptableObject. Aktywny oznacza, że został wcześniej załadowany w jakiejś formie.
Ta metoda jest bardzo powolna, więc pamiętaj o buforowaniu wartości zwracanej i unikaj częstego jej wywoływania. Odwoływanie się do ScriptableObjects bezpośrednio w skryptach powinno być preferowaną opcją.
Wskazówka: możesz utrzymywać własne kolekcje instancji w celu szybszego wyszukiwania. Niech Twoje ScriptableObjects zarejestrują się w kolekcji udostępnionej podczas
OnEnable()
.