CodingMode完成

This commit is contained in:
ohgushiyuga
2026-06-15 16:17:09 +09:00
parent c6b593805b
commit f21a2896cb
8 changed files with 3219 additions and 2000 deletions

View File

@@ -0,0 +1,130 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.XR; // 振動機能のために必要
using System.Collections;
public class ElevatorSceneTransition : MonoBehaviour
{
[Header("遷移先の設定")]
[SerializeField] private string bossSceneName = "BossStage";
[SerializeField] private string playerTag = "Player";
[Header("ローディングUI設定")]
[SerializeField] private GameObject loadingCanvas;
[SerializeField] private Text progressText;
[SerializeField] private Slider progressSlider;
// ─── ★ここから下降演出用の設定項目を追加 ───
[Header("エレベーター下降演出設定")]
[Tooltip("エレベーターの部屋壁や床、UIすべてをまとめている一番親のTransformを指定してください")]
[SerializeField] private Transform elevatorCageTransform;
[Tooltip("ガタガタ揺れる激しさミリ単位。0.010.03あたりがVR酔いしにくく自然です")]
[SerializeField] private float shakeMagnitude = 0.015f;
[Tooltip("下降中のコントローラーの振動の強さ0.0 1.0")]
[SerializeField] private float hapticAmplitude = 0.15f;
// ─────────────────────────────────────────
private bool isLoadingStarted = false;
private Vector3 originalCagePosition; // 揺らす前のエレベーターの初期位置を記憶する用
private void Start()
{
if (loadingCanvas != null)
{
loadingCanvas.SetActive(false);
}
// 部屋の初期位置を保存
if (elevatorCageTransform != null)
{
originalCagePosition = elevatorCageTransform.localPosition;
}
}
private void OnTriggerEnter(Collider other)
{
if (isLoadingStarted) return;
if (other.CompareTag(playerTag))
{
isLoadingStarted = true;
Debug.Log("🛗 プレイヤー乗車:下降演出と非同期ロードを開始します。");
StartCoroutine(LoadSceneAsyncRoutine());
}
}
private IEnumerator LoadSceneAsyncRoutine()
{
if (loadingCanvas != null) loadingCanvas.SetActive(true);
// 次のシーンの非同期ロードを開始(画面切り替えはまだロックする)
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(bossSceneName);
asyncLoad.allowSceneActivation = false;
// コントローラーの振動のタイミングを計るためのタイマー
float hapticTimer = 0f;
// ロード中progressが0.9未満の間)、ずっとループして演出を実行
while (asyncLoad.progress < 0.9f)
{
// 1. UIの進捗率を更新
float currentProgress = Mathf.Clamp01(asyncLoad.progress / 0.9f);
if (progressText != null) progressText.text = $"LOADING: {(currentProgress * 100f):F0}%";
if (progressSlider != null) progressSlider.value = currentProgress;
// 2. 【演出:部屋をガタガタ揺らす】
// 初期位置をベースに、毎フレームごくわずかなランダム座標を計算して部屋を揺らす
if (elevatorCageTransform != null)
{
Vector3 randomOffset = Random.insideUnitSphere * shakeMagnitude;
// ※左右前後のブレX, Zのみを揺らし、Y上下はあえて固定すると「ガタガタ感」が出ます
randomOffset.y = 0;
elevatorCageTransform.localPosition = originalCagePosition + randomOffset;
}
// 3. 【演出:両手のコントローラーを定期的に微振動させる】
hapticTimer += Time.deltaTime;
if (hapticTimer >= 0.1f) // 0.1秒ごとにブルブルと脈打つような振動を送る
{
TriggerBothHandHaptics(hapticAmplitude, 0.08f);
hapticTimer = 0f;
}
yield return null;
}
// ─── ロード完了後の処理 ───
// 4. 【演出の停止】エレベーターの揺れをピタッと止め、位置を綺麗にリセットする
if (elevatorCageTransform != null)
{
elevatorCageTransform.localPosition = originalCagePosition;
}
if (progressText != null) progressText.text = "ARRIVED";
if (progressSlider != null) progressSlider.value = 1f;
// 到着後の余韻ガタガタが止まってから、扉が開いてシーンが変わるまでの静寂1秒
yield return new WaitForSeconds(1.0f);
Debug.Log("🎉 ボスステージに到着。シーンを切り替えます。");
asyncLoad.allowSceneActivation = true;
}
/// <summary>
/// 左右両方のコントローラーを同時に微振動させるヘルパーメソッド
/// </summary>
private void TriggerBothHandHaptics(float amplitude, float duration)
{
// 左手
InputDevice leftDevice = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
if (leftDevice.isValid) leftDevice.SendHapticImpulse(0, amplitude, duration);
// 右手
InputDevice rightDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
if (rightDevice.isValid) rightDevice.SendHapticImpulse(0, amplitude, duration);
}
}