using UnityEngine; using System.Collections; /// /// 1つのトリガーで左右のドアを反対方向にスライド開閉させ、 /// 一定時間後に自動で閉じるクラス /// public class VRDoorController : MonoBehaviour { [Header("ドアのオブジェクト登録")] [Tooltip("左側にスライドさせたいドアのTransformを指定してください")] [SerializeField] private Transform leftDoor; [Tooltip("右側にスライドさせたいドアのTransformを指定してください")] [SerializeField] private Transform rightDoor; [Header("スライド量と速度の設定")] [Tooltip("ドアが横に何メートルずれるか(移動量)")] [SerializeField] private float slideDistance = 1.0f; [Tooltip("ドアが完全に開ききる(閉じきる)までにかかる時間(秒)")] [SerializeField] private float openSpeed = 1.2f; [Tooltip("ドアが開ききった後、自動で閉まり始めるまでの待ち時間(秒)")] [SerializeField] private float autoCloseDelay = 4.0f; // ドアの「閉じた位置」と「開いた位置」の座標を記憶する変数 private Vector3 leftDoorClosedPos; private Vector3 rightDoorClosedPos; private Vector3 leftDoorOpenPos; private Vector3 rightDoorOpenPos; // ドアの状態を管理するフラグ(バグ連打の防止用) private bool isOpen = false; private bool isMoving = false; private void Start() { // 1. ゲーム開始時の位置を「閉じた状態」として記憶 if (leftDoor != null) { leftDoorClosedPos = leftDoor.localPosition; // 左ドアはローカルのX軸のマイナス方向へスライドさせる leftDoorOpenPos = leftDoorClosedPos + new Vector3(-slideDistance, 0, 0); } if (rightDoor != null) { rightDoorClosedPos = rightDoor.localPosition; // 右ドアはローカルのX軸のプラス方向へスライドさせる rightDoorOpenPos = rightDoorClosedPos + new Vector3(slideDistance, 0, 0); } } /// /// 【外部連携用】VRのボタンが押されたときに呼び出す公開メソッド /// public void OnButtonPress() { // すでに移動中、またはすでに開いている場合はボタンの入力を完全に無視する if (isMoving || isOpen) return; // 開いてから自動で閉まるまでの一連のコルーチンを始動 StartCoroutine(OpenAndAutoCloseRoutine()); } /// /// ドアを開け、待機し、自動で閉める一連の流れを管理するコルーチン /// private IEnumerator OpenAndAutoCloseRoutine() { // ─── 1. ドアを開ける処理 ─── isMoving = true; float elapsedTime = 0f; while (elapsedTime < openSpeed) { elapsedTime += Time.deltaTime; float t = elapsedTime / openSpeed; // ★VR酔い・チープさ対策:数値を滑らかに補間して、リアルな加減速(イージング)をかける float easedT = Mathf.SmoothStep(0f, 1f, t); if (leftDoor != null) leftDoor.localPosition = Vector3.Lerp(leftDoorClosedPos, leftDoorOpenPos, easedT); if (rightDoor != null) rightDoor.localPosition = Vector3.Lerp(rightDoorClosedPos, rightDoorOpenPos, easedT); yield return null; // 1フレーム待機 } // 完全に開ききった座標で固定 if (leftDoor != null) leftDoor.localPosition = leftDoorOpenPos; if (rightDoor != null) rightDoor.localPosition = rightDoorOpenPos; isOpen = true; isMoving = false; Debug.Log("🚪 ドアが完全に開きました。"); // ─── 2. 開いた状態での待機(自動クローズのカウントダウン) ─── yield return new WaitForSeconds(autoCloseDelay); // ─── 3. ドアを閉じる処理 ─── isMoving = true; isOpen = false; elapsedTime = 0f; while (elapsedTime < openSpeed) { elapsedTime += Time.deltaTime; float t = elapsedTime / openSpeed; float easedT = Mathf.SmoothStep(0f, 1f, t); if (leftDoor != null) leftDoor.localPosition = Vector3.Lerp(leftDoorOpenPos, leftDoorClosedPos, easedT); if (rightDoor != null) rightDoor.localPosition = Vector3.Lerp(rightDoorOpenPos, rightDoorClosedPos, easedT); yield return null; } // 完全に閉じた座標で固定 if (leftDoor != null) leftDoor.localPosition = leftDoorClosedPos; if (rightDoor != null) rightDoor.localPosition = rightDoorClosedPos; isMoving = false; Debug.Log("🔒 ドアが自動で閉じました。"); } }