本日はアプリ作成枠です。
HoloLens2でホロモンアプリを作る進捗を書き留めていきます。
今回はホロモンやアイテムの説明パネルを起動時に一回だけ表示するメモです。
ホロモンやアイテムの説明パネル
ホロモンアプリを初めて体験する方が音声コマンドや掴みアクションの存在を認識できるように説明パネルを追加しました。
例えば、ホロモンには以下のような説明パネルを追加しました。
これらの説明パネルは一度説明を読めば邪魔になるだけなので自動で非表示になり、その後は表示されないようにしておきます。
以前、ホロモンやアイテムの台座として上に乗っているものがなくなると台座が自動的に消滅する仕組みを作成しました。
bluebirdofoz.hatenablog.com
今回はこのスクリプトを拡張して消失時に連動して説明パネルを無効化する仕組みを追加しました。
・StandSpawnController.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UniRx; using HoloMonApp.ConditionSpace; namespace HoloMonApp.ItemSpace { public class StandSpawnController : MonoBehaviour { /// <summary> /// デフォルト座標 /// </summary> [SerializeField, Tooltip("デフォルト座標")] private Vector3 p_DefaultLocalPosition; /// <summary> /// デフォルト回転 /// </summary> [SerializeField, Tooltip("デフォルト回転")] private Quaternion p_DefaultLocalRotation; /// <summary> /// デフォルトサイズ /// </summary> [SerializeField, Tooltip("デフォルトサイズ")] private Vector3 p_DefaultLocalScale; [SerializeField, Tooltip("消失アニメーション中か")] private bool p_NowDisappear; /// <summary> /// ヘルプ参照 /// </summary> [SerializeField, Tooltip("ヘルプ参照")] private GameObject p_HelpObject; /// <summary> /// 消失トリガー /// </summary> private IDisposable p_DisappearLerpTrigger; /// <summary> /// スタンド消失のチェックカウント /// </summary> private int p_CheckStandOnThreshold = 5; private int p_CheckStandOnCount; private void OnEnable() { // チェック変数をリセット p_CheckStandOnCount = 0; p_NowDisappear = false; } // Start is called before the first frame update void Start() { // デフォルト座標を保存 p_DefaultLocalPosition = this.transform.localPosition; // デフォルト回転を保存 p_DefaultLocalRotation = this.transform.localRotation; // デフォルトスケールを保存 p_DefaultLocalScale = this.transform.localScale; } // Update is called once per frame void Update() { // 表示状態のときは上に何か乗っているか常にチェックする if (!CheckStandOn()) { // 上に物がないときはカウントアップ p_CheckStandOnCount++; if (p_CheckStandOnCount > p_CheckStandOnThreshold) { // 一定フレーム間、上に物がないときはスタンドを消失させる DisappearStand(); } } else { // 物があればカウントをリセットする p_CheckStandOnCount = 0; } } /// <summary> /// スタンドを消失させる /// </summary> public void DisappearStand() { // 消失アニメーション中は処理しない if (p_NowDisappear) return; p_NowDisappear = true; // スムーズにトランスフォームを移動させる // 分割フレーム数 int lerpTime = 5; // 反映前トランスフォーム Vector3 beforeScale = this.transform.localScale; // 反映後トランスフォーム Vector3 afterScale = Vector3.zero; // トリガーを設定済みの場合は一旦破棄する p_DisappearLerpTrigger?.Dispose(); // 1フレームごとにトランスフォームを徐々に変化させる p_DisappearLerpTrigger = Observable .IntervalFrame(1) .Take(lerpTime) .SubscribeOnMainThread() .Subscribe( x => { // Lerpを使って徐々にトランスフォームを変化させる float current = (float)(1.0 / lerpTime) * x; Vector3 settingScale = Vector3.Lerp(beforeScale, afterScale, current); this.transform.localScale = settingScale; }, () => { // 完了時はオブジェクトを非表示にしてトランスフォームを戻す this.transform.localScale = beforeScale; // オブジェクトを無効化する this.gameObject.SetActive(false); // ヘルプオブジェクトがあれば無効化する // ヘルプオブジェクトは個別に有効化しない限り再表示されない p_HelpObject?.SetActive(false); // 消失アニメーション完了 p_NowDisappear = false; }) .AddTo(this); } /// <summary> /// スタンドの上に何か乗っているかチェックする /// </summary> /// <returns></returns> private bool CheckStandOn() { bool onStand = false; // レイキャストの結果 RaycastHit[] raycastHits = new RaycastHit[2]; // 現在のホロモンの大きさに合わせてチェック距離を調整する float checkDistance = 1.0f * CurrentHeightScale(); // レイキャストでスタンド上方の衝突オブジェクトを検知する int hitCount = Physics.RaycastNonAlloc(this.transform.position, Vector3.up, raycastHits, checkDistance); if (hitCount > 0) { // ヒット数が 0 より多いなら障害物があるので何か乗っている return true; } return onStand; } /// <summary> /// 現在のホロモンの身体スケールを取得する /// </summary> /// <returns></returns> private float CurrentHeightScale() { // 現在の体の大きさを取得する float currentHeight = HoloMonConditionBodySingleton.Instance. IReadOnlyReactivePropertyHoloMonBodyStatus.Value.BodyHeight; return currentHeight; } } }
本スクリプトの p_HelpObject にオブジェクト参照を設定しておき、台座の消滅と共にオブジェクトが無効化されるようにしておきます。
動作確認
シーンを再生して動作を確認します。
初期状態ではホロモンの台座と連動する説明パネルが表示された状態になっています。
ホロモンを呼ぶか掴むかして台座から降ろすと、台座と説明パネルが消失します。
「もどる」ボタンを押しても再度有効化されるのは台座オブジェクトだけで説明パネルは2回目以降表示されません。
アイテムオブジェクトにも同じ仕組みを使って説明パネルを設定しています。