質問: 以下のCharacterクラスで_base_parameterにChildParameterクラスを保持したいです。 その際、インスペクタからChildParameter1を保持するのか、ChildParameter2を保持するのかを設定できるようにし、それぞれのメンバ変数を設定できるようにしたいのですが、どのような手段がありますか ``` public class Character : MonoBehaviour { [SerializeField] BaseParameter _base_parameter; } [System.Serializable] public class BaseParameter { } [System.Serializable] public class ChildParameter1 : BaseParameter { [SerializeField] _child1_parameter; } [System.Serializable] public class ChildParameter2 : BaseParameter { [SerializeField] _child2_parameter; } ```
回答: CharacterにSerializableクラスをSerializeFieldまたはpublicフィールドとして配置してしまうと、 インスペクタ上ではアタッチされたCharacter上に編集可能項目が展開されてしまいます。 また継承関係は考慮できません(エディタ上の項目はメンバ変数の型で決まるため) ChildParameter2をインスペクタ上でパラメータ調整できるようにしたければ、 Serializableクラスで用意するのではなく、ScriptableObject継承クラスを使用します。 !画像の説明をここに入力 1 CharacterはSerializeFieldメンバとして以下のようにします。 また、Instantiate(クローン)しないとlogicインスタンスの参照を共有してしまうため、Instantiateします。 (Logicがパラメータを持たない純粋なロジックなら不要ですが、Hpなど個々のゲームオブジェクトの情報を持つならクローンが必須です) ``` [SerializeField] Logic _logicPrototype; Logic _logic; ... void Start() { this._logic = Instantiate(this._logicPrototype); this._logic.Foo(); // 大抵の場合、MonoBehaviourの情報を渡して適切に初期化する } void Update() { this._logic.Bar(); // やりたいようにやる } ``` 2 次に、個々のLogicChara1等のクラスは、以下の属性を付与することで、エディタのAssetsの右クリックメニュー> Createで.assetファイルとして作成できるようにします。 ``` [CreateAssetMenu(menuName = "Foo/Bar/LogicChara1")] public class LogicChara1 : Logic ``` 3 ここまでで準備は整いました。CharacterのlogicPrototype項目には、logicを継承したクラスに対する.assetファイルがどれでもアタッチできるようになります。 ScriptableObjectの使い方はしっかり理解するまで難しいですが、適切に使うと非常に便利です。 時間をかけて仕様や使い方を覚える価値は十分にあると思うので、いろいろ調べてみてください。