本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
本記事はHeadLookControllerでカメラの方を見る設定です。
Head Look Controller
キャラクターの頭部ボーンのアニメーションをオーバライドしてカメラの方向を向けるアセットです。
ただし現在はアセットの更新がされておらず、アセットが非公開の状態になっています。
assetstore.unity.com
本記事では過去記事で取得したソースコードを元に設定を行いました。
bluebirdofoz.hatenablog.com
過去ソースコードを利用する場合、Unity 2018、2019 ではスクリプトを正常に動作させるため、一部コードを修正する必要があります。
nekuramakura.com
ソースコードの修正
Assets/HeadLookController/Script 配下の CursorHit.cs のコードを修正します。
16行目~20行目のコードをコメントアウトするだけです。
using UnityEngine; using System.Collections; public class CursorHit : MonoBehaviour { public HeadLookController headLook; private float offset = 1.5f; // Update is called once per frame void LateUpdate () { if (Input.GetKey(KeyCode.UpArrow)) offset += Time.deltaTime; if (Input.GetKey(KeyCode.DownArrow)) offset -= Time.deltaTime; /* Unity 2019 環境では無効化する */ // Ray cursorRay = Camera.main.ScreenPointToRay(Input.mousePosition); // RaycastHit hit; // if (Physics.Raycast(cursorRay, out hit)) { // transform.position = hit.point + offset * Vector3.up; // } headLook.target = transform.position; } }
HeadLookControllerの設定
HeadLookController はキャラクターの頭部オブジェクトをカメラの方向に追従させます。
適当なオブジェクトに HeadLookController スクリプトをアタッチします。
Inspector ビューから回転する部分や回転角度などの設定を行います。
[Segments]の[Size]から[Element]を追加して[Transform]で動く部位を指定できます。
[Override Animation]にチェックを入れることで指定部位のアニメーションを上書きします。
今回、他の身体の部分のアニメーションを上書きしたくなかったので、頭部の部分のみをオーバーライドする設定を行いました。
CursorHitの設定
次に追従させたい対象オブジェクトを指定します。
今回はカメラの方向を向けたいので、カメラの子オブジェクトを用意して CursorHit スクリプトをアタッチしました。
Inspector ビューの[Head Look]に先ほど HeadLookController を設定したオブジェクトを指定します。
これで設定は完了です。
動作確認
シーンを再生して確認します。
ホロモンのアニメーションの首の部分が上書きされて常にカメラの方を向くようになりました。
[MaxBendingAngle]の値を切り替えることでスムーズに振り向きの有効無効を切り替えることができます。
切り替えスクリプト一例
コンポーネントの bool 値を切り替えることでスムーズに振り向きの有効無効を切り替えるスクリプトを作ってみました。
using System.Collections; using System.Collections.Generic; using UnityEngine; // リアクティブプロパティ利用のため UniRx を使用 using UniRx; namespace HMProject { [RequireComponent(typeof(HeadLookController))] public class HeadLookSwitch : MonoBehaviour { [SerializeField, Tooltip("HeadLookの有効無効")] public BoolReactiveProperty isEnableReactive = new BoolReactiveProperty(true); /// <summary> /// HeadLookControllerの参照 /// </summary> private HeadLookController headLookController; /// <summary> /// HeadLookControllerの最大角デフォルト設定 /// </summary> private float[] defaultMaxBendingAngles; /// <summary> /// HeadLookControllerのアニメーション上書きのデフォルト設定 /// </summary> private bool defaultOverrideAnimation; // Start is called before the first frame update void Start() { // 参照の取得 headLookController = this.GetComponent<HeadLookController>(); // デフォルトの最大角の取得 int segmentnum = headLookController.segments.Length; if (segmentnum > 0) { defaultMaxBendingAngles = new float[segmentnum]; for (int loop = 0; loop < segmentnum; loop++) { defaultMaxBendingAngles[loop] = headLookController.segments[loop].maxBendingAngle; } } // デフォルトのアニメーション上書き設定の取得 defaultOverrideAnimation = headLookController.overrideAnimation; // 有効無効切り替え時のリアクティブ処理を設定する isEnableReactive.Subscribe( onoff => ChangeMaxBendingAngle(onoff), () => ChangeMaxBendingAngle(true) ); } /// <summary> /// 有効無効に合わせてHeadLookControllerの最大角を変更する /// </summary> /// <param name="onoff"></param> void ChangeMaxBendingAngle(bool onoff) { // 有効無効に合わせてHeadLookControllerの最大角を変更する int segmentnum = headLookController.segments.Length; if (segmentnum > 0) { for (int loop = 0; loop < segmentnum; loop++) { float setValue = 0; if (onoff) { setValue = defaultMaxBendingAngles[loop]; } headLookController.segments[loop].maxBendingAngle = setValue; } } // アニメーションの上書き設定も変更する if (onoff) { headLookController.overrideAnimation = defaultOverrideAnimation; } else { headLookController.overrideAnimation = false; } } } }