サーチ…


備考

AssetBundlesを使用したScriptableObjects

スクリプト可能オブジェクトへの参照が含まれている場合、プリセットをAssetBundleに追加するときは注意してください。 ScriptableObjectsは基本的にアセットなので、UnityはそれらをAssetBundlesに追加する前に複製を作成します。これにより、実行時に望ましくない動作が発生する可能性があります。

このようなGameObjectをAssetBundleからロードするときには、ScriptableObjectアセットをロードされたスクリプトに再投入し、バンドルされたスクリプトを置き換える必要があります。 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サブメニューに表示します。この場合は、 Assets / Create / StackOverflow / Examplesの下にあります

作成したScriptableObjectインスタンスは、インスペクタを介して他のスクリプトやScriptableObjectに渡すことができます。

using UnityEngine;

public class SampleScript : MonoBehaviour {

    [SerializeField]
    MyScriptableObject myScriptableObject;

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

コードを使用してScriptableObjectインスタンスを作成する

ScriptableObject.CreateInstance<T>()を使用して新しいScriptableObjectインスタンスを作成します。

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

ここで、 TScriptableObjectます。

それらのコンストラクタを呼び出すことによってScriptableObjectを作成しないでください。 new ScriptableObject()

実行時にコードでScriptableObjectを作成することは、主にデータのシリアル化が使用されるため、めったに呼び出されません。この時点で標準クラスを使用することもできます。エディタの拡張機能をスクリプティングするときに、より一般的です。

ScriptableObjectsは、PlayModeでもエディタでシリアル化されます

ScriptableObjectインスタンスのシリアル化されたフィールドにアクセスするときは、特別な注意が必要です。

フィールドがpublicとマークされて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; }
    }
}

実行時に既存のScriptableObjectsを見つける

実行時にアクティブな ScriptableObjectを見つけるには、 Resources.FindObjectsOfTypeAll()使用しResources.FindObjectsOfTypeAll()

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

ここで、 Tは検索するScriptableObjectインスタンスのタイプです。 アクティブとは、何らかの形式でメモリにロードされたことを意味します。

このメソッドは非常に遅いので、戻り値をキャッシュして頻繁に呼び出さないようにしてください。スクリプトで直接ScriptableObjectsを参照することをお勧めします。

ヒント:より高速な検索のために、独自のインスタンスコレクションを維持することができます。 OnEnable()間にScriptableObjectsを共有コレクションに登録させます。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow