unity3d
ScriptableObject
サーチ…
備考
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>();
ここで、 T
はScriptableObject
ます。
それらのコンストラクタを呼び出すことによって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を共有コレクションに登録させます。