15. decimal型VectorをUnityEditorで制御したかった
Unity(2020.3.6f1) の話です。
計算精度が欲しかったので decimal 型で独自の Vector クラスを作成しました。
これで困ったのは、UnityEditor の Inspector で編集できないということです。
どうも Unity の Inspector は decimal 型をサポートしていないらしく、変数に SerializeField を付けても表示されません。
まぁ通常必要になることはないですし、下手にサポートすると初学者の人が誤りそうということでサポートしない方針も理解できます。
Inspector 拡張など色々やれば出せるようになると思いますが、Vector クラスは純粋な算術クラスとして扱いたいので Unity に依存させたくありませんでした。
そこで、苦肉の策として Unity の Vector3 と自作の Vector3decimal を仲介する Vector3UnityProxy というクラスを作成しました。
using UnityEngine; [Serializable] public sealed class Vector3UnityProxy { public Vector3decimal Impl { get; set; } [SerializeField] private Vector3 value; public void Awake() { this.Impl = new Vector3decimal((decimal)this.value.x, (decimal)this.value.y, (decimal)this.value.z); } public void Update() { this.value = this.Impl.ToUnityVector(); } }
コード中で操作するのは Impl で、value は初期値を Impl に伝える役割と、Impl の値を UnityEditor へ伝える役割を持ちます。
だいぶ適当に作ったのですが、このクラスは色々と問題があります。
- Impl への直接アクセスを許容しており、Proxy としての役割を正しく果たせていない
- 利用者側からの記述が冗長になる(必ず Impl を挟む)
- UnityEditor へ見せるための変数が private、裏方としてのプロパティが public で直感的に矛盾しているように見える
…と、今こうやって書き出すとかなり微妙だなぁ…と思っています。
ちゃんとやるなら Vector3decimal 用のインターフェースを切るのが良さそうですね。
.NET の Vector と実装を合わせたい気持ちがありましたが、流石にこの設計は嫌なのでインターフェースの追加は許容しようかなぁ、と思います。