using UnityEngine; // World Space Canvas をプレイヤーの真正面に移動させ、開いている間はプレイヤーの視点に滑らかに追従させるスクリプト public class VRUIDoorFaceFollow : MonoBehaviour { [SerializeField] private Transform vrCameraTransform; [Header("配置・追従のパラメータ")] [SerializeField] private float forwardDistance = 0.5f; [SerializeField] private float heightOffset = -0.1f; [SerializeField] private float followSpeed = 5.0f; // 画面がアクティブ(表示)になった瞬間を検知するためのフラグ private bool wasActiveLastFrame = false; private void Start() { // カメラが未設定の場合は、シーン内からメインカメラを自動取得 if (vrCameraTransform == null && Camera.main != null) { vrCameraTransform = Camera.main.transform; } } // 全体の時間が止まっている(Time.timeScale = 0)間でも動作させるため、カメラ移動の後に実行される LateUpdate を使用します private void LateUpdate() { if (vrCameraTransform == null) return; // このオブジェクト(UI画面)が有効化された「最初のフレーム」の処理 if (!wasActiveLastFrame) { // 開いた瞬間は、プレイヤーの今の向きの「完全な正面」に瞬間移動させる(遅れてついてくるのを防ぐため) SetInitialPosition(); wasActiveLastFrame = true; return; } // 毎フレームの滑らかな追従処理 SmoothFollowPlayer(); } private void OnDisable() { // 画面が閉じられたらフラグをリセットする wasActiveLastFrame = false; } /// 画面が開いた瞬間に、プレイヤーの正面の正しい位置・向きに強制配置する private void SetInitialPosition() { // カメラの位置から、カメラが向いている正面方向に一定距離進んだ座標を計算 Vector3 targetPosition = vrCameraTransform.position + (vrCameraTransform.forward * forwardDistance); targetPosition.y += heightOffset; // 高さを微調整 transform.position = targetPosition; // 画面の向きをプレイヤー(カメラ)の方向に向ける(背を向けないようにする) // UIパネルがプレイヤー側を正面にするよう、LookAtの後に180度回転させて裏返りを防ぎます transform.LookAt(vrCameraTransform.position); transform.Rotate(0, 180, 0); } /// プレイヤーが首を動かしたり移動したりした際、画面を滑らかについてこさせる private void SmoothFollowPlayer() { // 目的地(目標座標)の計算 Vector3 targetPosition = vrCameraTransform.position + (vrCameraTransform.forward * forwardDistance); targetPosition.y += heightOffset; // Time.timeScale = 0 でも動かすため、Time.unscaledDeltaTime を使用 // 現在位置から目標位置まで滑らかに補間移動(Lerp)させる transform.position = Vector3.Lerp(transform.position, targetPosition, Time.unscaledDeltaTime * followSpeed); // 向きも滑らかに補間(Slerp)してプレイヤーの方を向かせ続ける Quaternion targetRotation = Quaternion.LookRotation(transform.position - vrCameraTransform.position); transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, Time.unscaledDeltaTime * followSpeed); } }