【unity C#】リストList(T)の要素にポインタは使えない原因と解決方法

【unity C#】リストList(T)の要素にポインタは使えない原因と解決方法

 ステータスの構造体をリストに追加して、各キャラクターのステータス管理をしてました。もっと効率の良い方法があったかもしれませんが、今回はリストの中にポインタを入れる。つまりList<float *>のような定義ができないか試行錯誤してわかった原因と解決方法について書いています。

やりたかったこと

 最初に、ステータスを管理する構造体があるとします。

public struct STATUS
{
 public float HP;
 public float STR;
 public float INT;
 public float DEF;
 public float RES;
}

 そして、キャラクターを管理する構造体リストとしてList<STATUS>characterを作ります。

 スキルを発動する処理の時、スキルの演算等で該当するターゲットのステータスへポインタを指定して、その値を計算すると良いと考えました。こんな感じです。

//unsafe内---------
//スキルのターゲット
STATUS target;
//ポインタの初期値用
float tmp = 0f;
//ポインタ
float* E = &tmp;
switch(効果の種類){
 case 攻撃:
  E = &target.HP;
  break;
 case 回復:
  E = &target.HP;
  break;
 case 物理攻撃バフ:
  E = &target.STR;
  break;
 //省略
}

 ポインタはfloat* Eの一つだけで良いので実にシンプルですよね!

 いざ、コードを書いて実装してみると対象が単体の時は問題なく処理できました!

 後は全体を対象にするスキルも同じ要領でやってみます。

 List<float*>でポインタを格納するリストを…

error CS0211: Cannot take the address of the given expression

 その結果、このようなエラーが表示されました。

 検索しても英語の記事や難しい説明ばかり…。

 しかし、ついに原因と解決方法を突き止めましたのでこの記事を読んでくれている方に共有したいと思います!

原因

 C#の参照型と値型の違いを理解していませんでした。

組み込み型ユーザー定義型他の型から合成された型
値型単純型構造体
列挙型
NuLL許容型
参照型文字列型
オブジェクト型
クラス
インターフェイス
デリゲート
配列

 List<>にポインタするのは間違っているようで、ましてやリストの中にポインタを入れるのも間違っているようです。

 この問題を解決するためには参照型でステータスを定義する必要があるようですね。

解決方法

 ステータス用のクラスを作り、それにポインタをする方が良いみたいです。

 ですが、今回僕が実装したかったスキル発動の処理は別にポインタを使わなくても良く、コードを最小化したいってだけでしたのでポインタは諦めました。