やったこと
今回はキーボードのESCを押した際にオリジナルのメニューを表示する機能を作成しました。
今手元にviveコンがないのでデスクトップモードのみを対象としています。
(発火させるボタン登録を変更すればVRモードでも実行可能)
UdonSharpをこねこねしてESCキーでオリジナルのメニューがでるようにしてみた。
— はんちょ (@sadimensions) April 30, 2020
消すにはもう一度ESCキーをプッシュ。#UdonSharp pic.twitter.com/rxmWsufWeh
参考文献
uGUIからUdonSharp関数を呼び出す方法について
ハツェさんのUdon#入門③
やり方
Canvasを作成します。
メニューを出すのに直接は関係ないですが、同時にuGUIからmanagerのUdonSharp関数呼び出しと、値の取得を試したかったため、Button, Slider, Textを追加しています。
実装の方針は
1.ESCキーが押されたら
2.メニューがアクティブならば非アクティブにして消す
3.メニューが非アクティブならば ユーザーの座標近くにメニューを移動して アクティブにする。
という考えです。
private void UM_Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
if (UM_userMenue.activeSelf)
{
//メニューがアクティブならば、非アクティブ化
UM_userMenue.SetActive(false);
}
else
{
//非アクティブならば、プレイヤーの前に移動しアクティブ化
//座標設定
Vector3 pos = GEN_localPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Head).position;
Quaternion rot = GEN_localPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Head).rotation;
//オイラー角に変換後、メニューが垂直になるようにx軸を0にする。
Vector3 rotEuler = rot.eulerAngles;
rotEuler.x = 0;
//オイラー角をクォータニオンに戻し、プレイヤー座標とずらす距離を計算する
rot = Quaternion.Euler(rotEuler);
Vector3 bias = rot * new Vector3(0f, 0f, 0.5f);//0.5mだけ前に出す
//座標設定
UM_userMenue.transform.position = pos + bias;
//角度設定
UM_userMenue.transform.rotation = rot;
//アクティブ化
UM_userMenue.SetActive(true);
}
}
//プレイヤーとの距離が遠い場合は非アクティブ化
float seqDist = Vector3.SqrMagnitude(GEN_localPlayer.GetTrackingData(VRCPlayerApi.TrackingDataType.Head).position - UM_userMenue.transform.position);
if(seqDist > 4.0f)
{
UM_userMenue.SetActive(false);
}
}
クォータニオンはよくわかりませんが、Vector3に掛け合わせると、クォータニオンの軸に従って回転してくれること。
直接操作できなくてもオイラー角に直せばなんとなく加工できることがわかりました。
メインとなるUodate関数は次の通り
void Update()
{
GEN_Update(); //前回の記事参照
UM_Update(); //今回追加したもの
FM_Update(); //前回の記事参照
}
uBUIのボタンからUdonSharp関数を呼び出す方法については参考文献にそのまま乗っているので、今回は記載しません。
他のオブジェクトから引数渡しでUdonSharpを呼び出すことはできませんが、uGUIのTextにデータを書き込んでから呼び出せば、実質データを渡しての外部からの実行ができそうですね。
ボタンを押すと、Textへ渡すデータを書き込む関数と、動かしたい関数を呼び出せば、うまくいきそう・・・
でももし二つが非同期で同時に走ったらそれもそれで面倒な予感はあります。