Zoeken…


Opmerkingen

ScriptableObjects with AssetBundles

Let op bij het toevoegen van prefabs aan AssetBundles als ze verwijzingen naar ScriptableObjects bevatten. Aangezien ScriptableObjects in wezen activa zijn, maakt Unity er duplicaten van voordat ze aan AssetBundles worden toegevoegd, wat kan leiden tot ongewenst gedrag tijdens runtime.

Wanneer u een dergelijk GameObject vanuit een AssetBundle laadt, kan het nodig zijn om de ScriptableObject-activa opnieuw in te voeren in de geladen scripts en de gebundelde te vervangen. Zie Afhankelijkheidsinjectie

Invoering

ScriptableObjects zijn geserialiseerde objecten die niet gebonden zijn aan scènes of gameobjecten zoals MonoBehaviours dat zijn. Kort gezegd zijn het gegevens en methoden die zijn gebonden aan activabestanden in uw project. Deze ScriptableObject-middelen kunnen worden doorgegeven aan MonoBehaviours of andere ScriptableObjects, waar hun openbare methoden kunnen worden gebruikt.

Vanwege hun aard als geserialiseerde activa, zorgen ze voor uitstekende beheerklassen en gegevensbronnen.

Activa voor ScriptableObject maken

Hieronder staat een eenvoudige ScriptableObject-implementatie.

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);
    }
}

Door het kenmerk CreateAssetMenu aan de klasse toe te voegen, CreateAssetMenu Unity dit in het submenu Activa / Maken . In dit geval staat dit onder Activa / Maken / StackOverflow / Voorbeelden .

Eenmaal gemaakt, kunnen ScriptableObject-instanties worden doorgegeven aan andere scripts en ScriptableObjects via de Inspector.

using UnityEngine;

public class SampleScript : MonoBehaviour {

    [SerializeField]
    MyScriptableObject myScriptableObject;

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

Maak ScriptableObject-instanties via code

U maakt nieuwe ScriptableObject-instanties via ScriptableObject.CreateInstance<T>()

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

Waar T ScriptableObject .

Maak geen ScriptableObjects door hun constructors aan te roepen, dwz. new ScriptableObject() .

Het creëren van ScriptableObjects op basis van code tijdens runtime wordt zelden gevraagd, omdat het belangrijkste gebruik ervan gegevensserialisatie is. Op dit punt kunt u net zo goed standaardklassen gebruiken. Het komt vaker voor wanneer u editor-extensies scripts.

ScriptableObjects worden in de editor geserialiseerd, zelfs in PlayMode

Extra aandacht moet worden besteed aan toegang tot geserialiseerde velden in een ScriptableObject-instantie.

Als een veld wordt gemarkeerd als public of geserialiseerd via SerializeField , is het wijzigen van de waarde permanent. Ze worden niet gereset bij het afsluiten van de afspeelmodus zoals MonoBehaviours. Dit kan soms handig zijn, maar het kan ook een puinhoop zijn.

Daarom is het het beste om geserialiseerde velden alleen-lezen te maken en openbare velden helemaal te vermijden.

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

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

Als u openbare waarden in een ScriptableObject wilt opslaan die worden gereset tussen spelsessies, kunt u het volgende patroon gebruiken.

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; }
    }
}

Bestaande ScriptableObjects zoeken tijdens runtime

Als u actieve ScriptableObjects tijdens runtime wilt vinden, kunt u Resources.FindObjectsOfTypeAll() .

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

Waar T het type is van de instantie ScriptableObject die u zoekt. Actief betekent dat het eerder in een of andere vorm in het geheugen is geladen.

Deze methode is erg traag, dus vergeet niet de retourwaarde in de cache te plaatsen en deze niet vaak aan te roepen. Verwijzen naar de ScriptableObjects rechtstreeks in uw scripts moet uw voorkeursoptie zijn.

Tip: U kunt uw eigen instantiecollecties onderhouden voor sneller zoeken. Laat uw ScriptableObjects zichzelf registreren bij een gedeelde verzameling tijdens OnEnable() .



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow