74982


以下のCharacterクラスで_base_parameterにChildParameterクラスを保持したいです。  
その際、インスペクタからChildParameter1を保持するのか、ChildParameter2を保持するのかを設定できるようにし、それぞれのメンバ変数を設定できるようにしたいのですが、どのような手段がありますか

[code]

    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; 
    }
    
[/code]


CC BY-SA 4.0
2021-03-30T00:20:13.787
74976
2021-03-30T04:47:49.717
2021-03-30T00:52:40.790
22827
22827
question
c# unity3d
クラスのメンバ変数に親クラスを持ち、その変数にインスペクタ上で子クラスを設定できるようにしたい


CharacterにSerializableクラスをSerializeFieldまたはpublicフィールドとして配置してしまうと、  
インスペクタ上ではアタッチされたCharacter上に編集可能項目が展開されてしまいます。  
また継承関係は考慮できません（エディタ上の項目はメンバ変数の型で決まるため）

ChildParameter2をインスペクタ上でパラメータ調整できるようにしたければ、  
Serializableクラスで用意するのではなく、ScriptableObject継承クラスを使用します。

[![画像の説明をここに入力](https://i.stack.imgur.com/lNSkf.png)](https://i.stack.imgur.com/lNSkf.png)

① CharacterはSerializeFieldメンバとして以下のようにします。  
また、Instantiate（クローン）しないとlogicインスタンスの参照を共有してしまうため、Instantiateします。  
（Logicがパラメータを持たない純粋なロジックなら不要ですが、Hpなど個々のゲームオブジェクトの情報を持つならクローンが必須です）

[code]

    [SerializeField]
    Logic _logicPrototype;
    
    Logic _logic;
    
    …
    
    void Start()
    {
        this._logic = Instantiate(this._logicPrototype);
        this._logic.Foo(); // 大抵の場合、MonoBehaviourの情報を渡して適切に初期化する
    }
    
    void Update()
    {
        this._logic.Bar(); // やりたいようにやる
    }
    
[/code]

② 次に、個々のLogicChara1等のクラスは、以下の属性を付与することで、エディタのAssetsの右クリックメニュー>
Createで.assetファイルとして作成できるようにします。

[code]

    [CreateAssetMenu(menuName = "Foo/Bar/LogicChara1")]
    public class LogicChara1 : Logic
    
[/code]

③
ここまでで準備は整いました。CharacterのlogicPrototype項目には、logicを継承したクラスに対する.assetファイルがどれでもアタッチできるようになります。

ScriptableObjectの使い方はしっかり理解するまで難しいですが、適切に使うと非常に便利です。  
時間をかけて仕様や使い方を覚える価値は十分にあると思うので、いろいろ調べてみてください。


CC BY-SA 4.0
2021-03-30T04:37:52.667
74982
2021-03-30T04:47:49.717
2021-03-30T04:47:49.717
25396
25396
74976
answer