記事の狙い
vciのスクリプトはいろいろ便利なAPIが搭載されているのですが、一見して使い道がわからなかったり、文書や使用例が少なかったりして知られていない関数があるように思います。
実際、知っていれば結構簡単に実装できるのに、知らないというだけで大変な労力をかけて自作するというもったいない例を見ることも多いです。
本記事では、そのような便利だけど隠れた関数を発掘し、皆様の開発時間の節減や品質の向上によってVCI界隈全体に貢献することを目的とします。(という前文が書かれた備忘録)
今回紹介する関数
Vector3.ProjectOnPlane(vector: Vec3, planeNormal: Vec3) :Vec3
使用率(レア度)
他人使用例0例 (レア度SSR)
調査方法:VScodeでvci scriptが保存されるフォルダ内の全ファイルを検索した
対象:2019年6月より筆者のいる空間で出たVCIスクリプト共有を可能にしている全VCI(208ファイル)
何をする関数なの?
planeNormalを法線ベクトルとする面へのvectorベクトルの投影ベクトルを求めます。(virtualcast wikiより引用)
使いどころ
- UIなどの平面上にオブジェクトを拘束する。
- 向いている方向を求める
- 平面上での距離を求める
以下解説します。
UIなどの平面上にオブジェクトを拘束する
もっとも単純な使い方です。この関数を使うと、指定平面に対してオブジェクトを垂直に落とした場所が求まります。
これはUIなどで多用します。
上記は、前回のアドベントカレンダーの記事で作ったカラーピッカーですが、パレット上からの色を拾うためのスタイラスペン(画像の円錐)でパレット表面を動くポインター球の位置を動かしています。
そのほか、VRCのゲームワールドなどでよくある、マップ上にキャラクター現在位置を表示するようなUIなど、使い道は様々です。
向いている方向を求める
これは応用になりますが、現在向いている方向を求めることもできます。
基準面が座標系に直立であればEulerのy軸だけ指定などで事足りるのですが、斜めだったりするとオイラー角では途端に計算が複雑になります。
以下は、平面plainに対して棒状のarrowというオブジェクトの角度を求めます。
dummyというオブジェクトをplainの子オブジェクトにしてコメントアウトを外せば、arrowに追従してぐるぐる回ります。
またUIの話になってしまいますが、時計のようなぐるぐる回すUIには便利です。
-- arrowの平面plain(法線ベクトルがNplain)上での向いている方向を求める
local plain = vci.assets.GetTransform("plain")
local arrow = vci.assets.GetTransform("arrow")
--local dummy = vci.assets.GetTransform("dummy")
function update()
local Nplain = plain.GetUp()
local Darrow = arrow.GetForward()
local PDarrow = Vector3.ProjectOnPlane(Darrow, Nplain)
-- dummy.SetLocalRotation(Quaternion.AngleAxis(Vector3.SignedAngle(plain.GetForward(),PDarrow,Nplain),Vector3.up))
print(string.format("direction of projected arrow:%f"
,Vector3.SignedAngle(plain.GetForward(),PDarrow,Nplain)))
end
平面上での距離を求める
また、当然基準点からの位置・距離も取得できるため、柔軟なUIを作ることも可能です。よくある実装では衝突判定などでボタンの操作を検知しますが、ボタンの形状や数が変わってしまうため画面遷移のようなものがむつかしくなります。製作上もオブジェクトを多数管理せねばならず煩雑です。位置を読み込む形式にすれば、変化に対する管理が格段に楽になります。(例えば、公式のホワイトボードなどはおそらくこの関数を使っているものだと思われます)
上記のように、useしたときのポインターの位置をとることで、作動させることができます。キーボードのようなボタンが多いUIや、可変形状のものの際でも柔軟に対応することができます。