Codingモード研究中
This commit is contained in:
79
Assets/Scripts/VRUIDoorFaceFollow.cs
Normal file
79
Assets/Scripts/VRUIDoorFaceFollow.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user