ボスステージが壊れていた

リカバリーしてエレベーターを作った
This commit is contained in:
ohgushiyuga
2026-06-30 12:29:10 +09:00
parent 9479a22419
commit da4bd5f684
10 changed files with 5545 additions and 1902 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 23f893a4670a7fc4180013174ddad3be
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,24 +0,0 @@
using UnityEditor;
using UnityEngine;
using System;
using System.Collections;
[InitializeOnLoad]
public class LaunchConifersInstaller
{
static LaunchConifersInstaller()
{
EditorApplication.update += Update;
}
static void Update()
{
EditorApplication.update -= Update;
if( !EditorApplication.isPlayingOrWillChangePlaymode )
{
ConifersInstaller.Init();
}
}
}

View File

@@ -1,18 +0,0 @@
fileFormatVersion: 2
guid: a763f5a1ec8fa1746bec38f0547741ab
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 142076
packageName: 'Conifers [BOTD]'
packageVersion: 2.01
assetPath: Assets/Forst/Conifers [BOTD]/Installer/Editor/LaunchConifersInstaller.cs
uploadId: 649803

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.XR; // 振動機能のために必要
using UnityEngine.XR;
using System.Collections;
public class ElevatorSceneTransition : MonoBehaviour
@@ -15,32 +15,33 @@ public class ElevatorSceneTransition : MonoBehaviour
[SerializeField] private Text progressText;
[SerializeField] private Slider progressSlider;
// ─── ★ここから下降演出用の設定項目を追加 ───
[Header("エレベーター下降演出設定")]
[Tooltip("エレベーターの部屋壁や床、UIすべてをまとめている一番親のTransformを指定してください")]
[Tooltip("エレベーターの部屋壁や床、UIすべてをまとめているオブジェクトを指定してください(※プレイヤーは外しておきます)")]
[SerializeField] private Transform elevatorCageTransform;
[Tooltip("ガタガタ揺れる激しさ(ミリ単位。0.010.03あたりがVR酔いしにくく自然です)")]
[Tooltip("ガタガタ揺れる激しさ0.010.03あたりが自然です)")]
[SerializeField] private float shakeMagnitude = 0.015f;
[Tooltip("下降中のコントローラーの振動の強さ0.0 1.0")]
[SerializeField] private float hapticAmplitude = 0.15f;
// ─────────────────────────────────────────
// ─── ★新設:親子関係にしないためのプレイヤー登録枠 ───
[Header("プレイヤーの同期設定")]
[Tooltip("XR OriginまたはXR RigのTransformを直接ドラッグドロップしてください")]
[SerializeField] private Transform playerTransform;
// ─────────────────────────────────────────────────────
private bool isLoadingStarted = false;
private Vector3 originalCagePosition; // 揺らす前のエレベーターの初期位置を記憶する用
private Vector3 originalCagePosition;
private void Start()
{
if (loadingCanvas != null)
{
loadingCanvas.SetActive(false);
}
if (loadingCanvas != null) loadingCanvas.SetActive(false);
// 部屋の初期位置を保存
if (elevatorCageTransform != null)
{
originalCagePosition = elevatorCageTransform.localPosition;
// ワールド空間での初期位置を記憶localPositionからpositionに変更し、より確実に
originalCagePosition = elevatorCageTransform.position;
}
}
@@ -51,7 +52,14 @@ public class ElevatorSceneTransition : MonoBehaviour
if (other.CompareTag(playerTag))
{
isLoadingStarted = true;
Debug.Log("🛗 プレイヤー乗車:下降演出と非同期ロードを開始します。");
// ★安全対策接触したプレイヤーのTransformを自動でキャッシュする
if (playerTransform == null)
{
playerTransform = other.transform;
}
Debug.Log("🛗 プレイヤー乗車:親子関係なしのデルタ同期で下降演出を開始します。");
StartCoroutine(LoadSceneAsyncRoutine());
}
}
@@ -60,34 +68,42 @@ public class ElevatorSceneTransition : MonoBehaviour
{
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. 【演出:部屋をガタガタ揺らす】
// 初期位置をベースに、毎フレームごくわずかなランダム座標を計算して部屋を揺らす
// ─── ★【超重要】親子関係なしでプレイヤーを完全同期させるロジック ───
// 1. 動かす前の、このフレームにおけるエレベーターの現在位置を記録
Vector3 previousCagePosition = elevatorCageTransform.position;
// 2. エレベーターの部屋だけをランダムにガタガタ動かす
if (elevatorCageTransform != null)
{
Vector3 randomOffset = Random.insideUnitSphere * shakeMagnitude;
// ※左右前後のブレX, Zのみを揺らし、Y上下はあえて固定すると「ガタガタ感」が出ます
randomOffset.y = 0;
elevatorCageTransform.localPosition = originalCagePosition + randomOffset;
randomOffset.y = 0; // 横揺れのみ
elevatorCageTransform.position = originalCagePosition + randomOffset;
}
// 3. 【演出:両手のコントローラーを定期的に微振動させる】
// 3. 「この1フレームでエレベーターが実際に動いた移動差分デルタ」を計算
Vector3 cageDelta = elevatorCageTransform.position - previousCagePosition;
// 4. その移動差分を、プレイヤーの座標にもそのまま上乗せして足し算する
if (playerTransform != null && cageDelta != Vector3.zero)
{
playerTransform.position += cageDelta;
}
// ───────────────────────────────────────────────────────────────────
hapticTimer += Time.deltaTime;
if (hapticTimer >= 0.1f) // 0.1秒ごとにブルブルと脈打つような振動を送る
if (hapticTimer >= 0.1f)
{
TriggerBothHandHaptics(hapticAmplitude, 0.08f);
hapticTimer = 0f;
@@ -96,34 +112,30 @@ public class ElevatorSceneTransition : MonoBehaviour
yield return null;
}
// ─── ロード完了後の処理 ───
// 4. 【演出の停止】エレベーターの揺れをピタッと止め、位置を綺麗にリセットする
// 到着後、エレベーターの位置を元の位置に綺麗に戻す
if (elevatorCageTransform != null)
{
elevatorCageTransform.localPosition = originalCagePosition;
// 最後の移動差分を計算してプレイヤーを戻す
Vector3 previousCagePosition = elevatorCageTransform.position;
elevatorCageTransform.position = originalCagePosition;
Vector3 cageDelta = elevatorCageTransform.position - previousCagePosition;
if (playerTransform != null) playerTransform.position += cageDelta;
}
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);
}

View File

@@ -0,0 +1,122 @@
using UnityEngine;
using System.Collections;
/// <summary>
/// 1つのトリガーで左右のドアを反対方向にスライド開閉させ、
/// 一定時間後に自動で閉じるクラス
/// </summary>
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);
}
}
/// <summary>
/// 【外部連携用】VRのボタンが押されたときに呼び出す公開メソッド
/// </summary>
public void OnButtonPress()
{
// すでに移動中、またはすでに開いている場合はボタンの入力を完全に無視する
if (isMoving || isOpen) return;
// 開いてから自動で閉まるまでの一連のコルーチンを始動
StartCoroutine(OpenAndAutoCloseRoutine());
}
/// <summary>
/// ドアを開け、待機し、自動で閉める一連の流れを管理するコルーチン
/// </summary>
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("🔒 ドアが自動で閉じました。");
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7c3e120316425604197ba905dffcef0d

View File

@@ -321,6 +321,28 @@ MonoBehaviour:
m_multiviewRenderRegionsOptimizationMode: 0
m_hasMigratedMultiviewRenderRegions: 1
spacewarpMotionVectorTextureFormat: 0
--- !u!114 &-6832857813982530537
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 12d3bf61b014a48a2b7564c61da9d7ad, type: 3}
m_Name: AndroidXRPerformanceMetrics Standalone
m_EditorClassIdentifier: Unity.XR.AndroidOpenXR::UnityEngine.XR.OpenXR.Features.Android.AndroidXRPerformanceMetrics
m_enabled: 0
nameUi: Android XR Performance Metrics
version: 0.1.0
featureIdInternal: com.unity.openxr.feature.androidxr-performance-metrics
openxrExtensionStrings: XR_ANDROID_performance_metrics
company: Unity Technologies
priority: 0
targetOpenXRApiVersion:
required: 0
customRuntimeLoaderName:
--- !u!114 &-6559185765804338520
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -543,8 +565,18 @@ MonoBehaviour:
features:
- {fileID: 8736661028334727731}
- {fileID: 3598254934845347770}
- {fileID: -6832857813982530537}
- {fileID: -4559034614451708685}
- {fileID: 1170704673688743257}
- {fileID: -1187533949232362847}
- {fileID: -949347770443697596}
- {fileID: -1529727133502117446}
- {fileID: 5153017048313567732}
- {fileID: 265326132771859475}
- {fileID: 2834828863856360103}
- {fileID: -2851827796942056979}
- {fileID: -8128959895479975907}
- {fileID: 431653824124869831}
- {fileID: 6481653220666705815}
- {fileID: 7393116930172532905}
- {fileID: 744375598501864353}
@@ -681,6 +713,31 @@ MonoBehaviour:
targetOpenXRApiVersion:
required: 0
customRuntimeLoaderName:
--- !u!114 &-4559034614451708685
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 90ae1e8c3c7a542bba339faf2e771c5a, type: 3}
m_Name: AndroidXRSupportFeature Standalone
m_EditorClassIdentifier: Unity.XR.AndroidOpenXR::UnityEngine.XR.OpenXR.Features.Android.AndroidXRSupportFeature
m_enabled: 0
nameUi: Android XR Support
version: 1.0.0
featureIdInternal: com.unity.openxr.feature.androidxr-support
openxrExtensionStrings:
company: Unity Technologies
priority: 0
targetOpenXRApiVersion:
required: 0
customRuntimeLoaderName:
symmetricProjection: 0
optimizeBufferDiscards: 1
multiviewRenderRegionsOptimizationMode: 0
--- !u!114 &-4363231183632145407
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -1169,8 +1226,8 @@ MonoBehaviour:
features:
- {fileID: 7011443450567333355}
- {fileID: -671281728444007487}
- {fileID: -901939997048047619}
- {fileID: -1734471456787174204}
- {fileID: 6956056911768161135}
- {fileID: 5091991234558418143}
- {fileID: 8980318060753866109}
- {fileID: -6559185765804338520}
- {fileID: -4756202077021157709}
@@ -1181,7 +1238,7 @@ MonoBehaviour:
- {fileID: 348827886137839178}
- {fileID: -7499073031166464939}
- {fileID: 7666556398442971420}
- {fileID: -7343570946846779558}
- {fileID: 1118878472687837173}
- {fileID: 3985858319333531581}
- {fileID: -6511185071715886993}
- {fileID: -4363231183632145407}
@@ -1381,6 +1438,28 @@ MonoBehaviour:
targetOpenXRApiVersion:
required: 0
customRuntimeLoaderName:
--- !u!114 &431653824124869831
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 6c36843bac48b29469f79baf3c98f9b6, type: 3}
m_Name: AndroidXRHandMeshData Standalone
m_EditorClassIdentifier: Unity.XR.AndroidOpenXR::UnityEngine.XR.OpenXR.Features.Android.AndroidXRHandMeshData
m_enabled: 0
nameUi: 'Android XR: Hand Mesh Data'
version: 0.1.0
featureIdInternal: com.unity.openxr.feature.androidxr-hand-mesh-data
openxrExtensionStrings: XR_ANDROID_hand_mesh
company: Unity Technologies
priority: 0
targetOpenXRApiVersion:
required: 0
customRuntimeLoaderName:
--- !u!114 &584509823047506666
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -1565,7 +1644,7 @@ MonoBehaviour:
nameUi: 'Android XR: AR Anchor'
version: 0.1.0
featureIdInternal: com.unity.openxr.feature.arfoundation-androidxr-anchor
openxrExtensionStrings: XR_ANDROID_trackables XR_ANDROID_device_anchor_persistence
openxrExtensionStrings: XR_ANDROID_trackables
company: Unity Technologies
priority: 0
targetOpenXRApiVersion:
@@ -2512,7 +2591,7 @@ MonoBehaviour:
nameUi: 'Android XR: AR Anchor'
version: 0.1.0
featureIdInternal: com.unity.openxr.feature.arfoundation-androidxr-anchor
openxrExtensionStrings: XR_ANDROID_trackables XR_ANDROID_device_anchor_persistence
openxrExtensionStrings: XR_ANDROID_trackables
company: Unity Technologies
priority: 0
targetOpenXRApiVersion: