はじめに
結論から言えば、Vector3IntはVector3を使ったほうが楽です。
たとえ整数しか格納されない場合でも何らかの演算する場合には面倒なことになります。
この記事は私がVector3Intを使ったときに困惑したことを解説する記事です。
なぜ使わないほうが楽なのか、早速見ていきましょう。
1. Matrix4x4と演算が不可能
ベクトルの回転や平行移動をするのに行列(Matrix4x4)を使うことがあります。
私の場合、グリッド上の位置ベクトルを90度回転するときにMatrix4x4.MultiplyPoint3x4(Vector3)を使用しようと考えました。
しかし、Vector3Intの場合これを使うことはできません。
引数がVector3Intの場合のメソッドが定義されておらず、Vector3への型変換も用意されていないためです。
Vector3Intは構造体なので、派生クラスを作って型変換を用意することはできません。
そのため、先ほどのような90度回転を実装する場合、以下のどれかを行う必要があります。
- Utilityクラスを作ってベクトル要素を直接いじるようなコードを書く
- Vector3Intに以下のどちらかの拡張メソッドを定義する
- 回転用のメソッド
- Vector3Int->Vector3の型変換オペレーター
正直面倒くさいです。
前者はあまりきれいな解決策ではありません。Utilityクラスの肥大化や乱立を招き可読性を損なう可能性があるため、できれば元の構造体内にメソッドを定義したいです。
後者は他のプロジェクトにコードを持ち出した際に予期せぬバグを生んだり、コンパイルエラーが起きてほしいところで起きなくなったりと副作用があり少し怖いです。
2. 浮動小数点数による掛け算や割り算が不可能
スカラー演算はint型にだけ定義されています。
返す値はVector3で良いので融通が利くようにしてほしかった。
解決策は先ほどとほぼ同様です。
3. 型変換が貧弱
9割方の悩みはこれに尽きます。これまでに挙げていた問題もこれができれば容易に解決策を出すことができたでしょう。
ここで問題視している型変換は、Vector3Int->Vector3です。
私はVector3Intを使用することを考えていた時、この型変換はできるものだろうと考えていました。
実際調べたところ以下のリファレンスページにて型変換できるという風に書かれていたため、これを受け止めてコーディングをしていきました。
しかし、いざコンパイルしようとすると型変換ができないと怒られます。
Cannot implicitly convert type 'UnityEngine.Vector3Int' to 'UnityEngine.Vector3'
先ほどのページを調べると、どうやらUnity 2021.2の日本語版にしか型変換の記述がないようです。
ドキュメントはしっかりと確かめなければならないという教訓になりました。
しかし、Vector3->Vector3Intであれば丸める必要があるので型変換がないのも理解できますが、今回の変換はただ単にすべての要素をint->floatに変換するだけで済むため、なぜ削除されたのか不明です。
動作を軽くするためでしょうか。
Vector3を引数に要求するメソッド、関数に対して代替的に引数として利用できなくなるため使い道が狭まります。
解決策としては拡張メソッドで型変換オペレーターを用意することです。
おわりに
ここまで書いてきましたが、基本的にはベクトルとしての演算が必要になる場合にのみ問題が発生します。
そのため、データの読み書きだけで一切の演算を行わない場合や、要素を使った演算だけを行う場合にはVector3よりも良い型となる可能性があります。
しかし、後から機能追加などによりベクトル演算が必要になることも考えられるため、その辺を踏まえて使用するか、それとも型変換を用意するかを決めるとよいでしょう。
同様のことがBoundsIntなどにも言えます。
以上です。良いUnityライフを!