平面との距離や、レーザーが平面に当たる位置などを計算したいんだけど、数式を立てるのが難しくて困っているの…
Unityが提供しているPlane構造体を使えば、この辺の扱いが楽になるわ。
Unityには、平面に関する計算を楽に扱えるようにしたPlane構造体が存在します。
このPlane構造体を用いると、次のような計算を楽に行うことが可能です。
- 点と平面との最短距離を求める
- 投影点を求める
- レイキャストと平面との交点を求める
- 点が面の表と裏どちらにあるかを判定する
- 3点を通る平面を求める
これらの計算をPlane構造体のメソッドで行うことにより、数式を立てる必要がなくなるほか、ソースコードの見通しもよくなります。
本記事では、Plane構造体の使い方と使用例を解説していきます。なお、プリミティブオブジェクトのPlaneではありませんのでご注意ください。
- Unity2021.1.22f1
目次 非表示
Plane構造体が表す平面
Plane構造体は、裏表のある無限に続く平面を表します。
構造体内部では、法線ベクトルと原点からの距離の2つのパラメータを保持しています。
法線ベクトルは、矢印の向きが表面、その逆は裏面となります。
原点からの距離には符号があり、平面の表側に原点があるときは正、裏側に原点があるときは負となります。
平面の定義方法は3種類あり、それぞれオーバーロードされたコンストラクタとして初期化できます。
Plane構造体の初期化
次の3つのコンストラクタにより平面を定義して初期化します。
1つ目は、法線ベクトルinNormalと平面を通る点inPointで初期化するコンストラクタです。
2つ目は、法線ベクトルinNormalと原点からの距離dで初期化するコンストラクタです。
3つ目は、3点a、b、cを通る平面として初期化するコンストラクタです。3点は表面から見て時計回りとなります。
引数に指定する法線ベクトルinNormalは長さ1で正規化されている必要がある点にご注意ください。
参考:Unity – Scripting API: Plane.Plane
なお、初期化したPlaneインスタンスの値を後から変更することも可能です。
初期化して平面の定義ができたら、メソッドやプロパティを通じて計算処理ができるようになります。
次はこれらの使い方について解説していきます。
点と平面の距離を求める
Plane.GetDistanceToPoint()メソッドにより求めることができます。
メソッドの形式は次の通りです。
引数には、平面との距離を測定したい点を指定します。
実際の使い方は次の通りです。
平面との距離は、点が表側にある時は正、裏側にある時は負となります。
すなわち、得られる距離の符号によって点の表裏判定ができます。
なお、表裏判定をするだけの場合は、次のメソッドを使うと簡単です。
引数には表裏判定する点の座標を指定します。
戻り値は、点が表側ならtrue、裏側または平面上ならfalseとなります。
ある点から平面に最も近い位置を求める
Plane.ClosestPointOnPlane()メソッドで計算できます。
引数には点の座標を指定します。
戻り値は平面に最も近い位置座標です。
得られる結果は、点を面まで垂直に移動した点、言い換えると平面への投影点となります。
レイキャストの交点を求める
ある点からある向きに向かう線(レイ)と平面との交点は、Plane.Raycast()メソッドから求めることができます。
第1引数にはレイの情報を格納した構造体、第2引数には距離を受け取る変数を指定します。
戻り値はレイが平面に当たったらtrue、そうでない場合はfalseとなります。レイが平面と平行な場合もfalseとなります。表裏どちらからレイが平面に当たってもtrueとなります。
Ray構造体の使い方は、以下記事でも解説しています。
平面の裏表をひっくり返す
Plane.Flip()メソッドを用いると、平面の位置をそのままに、裏表だけひっくり返すことができます。
引数や戻り値はありません。また、Plane.flippedプロパティから新しいインスタンスとして取得することも可能です。
さいごに
Plane構造体の使い方について解説しました。
プログラム中で何か平面情報を扱いたい場合、Plane構造体を用いると便利です。数学的なベクトル計算をPlane構造体で内包してくれます。
コライダーを用いる必要が無く、内部的には内積や外積だけで計算処理が実装されているので計算が軽いというメリットもあります。
ぜひ活用方法を検討してみてください。