축제 잔디 사망루트
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Locomotion;
|
||||
using UnityEngine.InputSystem.XR;
|
||||
|
||||
public class PlayerController : MonoBehaviour
|
||||
{
|
||||
// 시야 가림용 구체(Sight)가 쓰는 머티리얼 — 알파 0(투명)이면 정상 시야, 1(불투명)이면 암전
|
||||
[SerializeField] private Material _sightMat;
|
||||
|
||||
[SerializeField] private GameObject _bloodDieImgRef;
|
||||
[SerializeField] private AudioClip _bloodSfx;
|
||||
|
||||
private static readonly int _baseColorId = Shader.PropertyToID("_BaseColor");
|
||||
private static readonly int _colorId = Shader.PropertyToID("_Color");
|
||||
|
||||
@@ -46,4 +51,39 @@ private void SetSightAlpha(float alpha)
|
||||
color.a = alpha;
|
||||
_sightMat.SetColor(AlphaProp, color);
|
||||
}
|
||||
|
||||
public void PlayerBloodDie(float duration)
|
||||
{
|
||||
_ = Util.RunDelayed(duration, () =>
|
||||
{
|
||||
StopPlayerMovement(); // XR 이동/회전 정지 — PauseAllAnimations로는 못 막는다
|
||||
LocalManager.PauseAllAnimations();
|
||||
_bloodDieImgRef.SetActive(true);
|
||||
SoundManager.Instance.PlaySFX(_bloodSfx);
|
||||
},this.destroyCancellationToken);
|
||||
|
||||
}
|
||||
|
||||
// Player 태그 루트(XR Origin) 아래에서 플레이어가 시야/위치를 바꾸는 수단을 전부 정지시킨다:
|
||||
// 1) LocomotionProvider → 이동/회전(중력 포함)
|
||||
// 2) TrackedPoseDriver → 헤드셋·컨트롤러 트래킹. 카메라 드라이버를 꺼야 머리를 돌려도 시야가 안 돈다
|
||||
// PauseAllAnimations는 Animator/타임라인/파티클만 멈추므로 이 둘은 못 막는다. 사망 연출이라 복구하지 않는다.
|
||||
private static void StopPlayerMovement()
|
||||
{
|
||||
var playerRoot = GameObject.FindWithTag("Player");
|
||||
if (playerRoot == null)
|
||||
{
|
||||
Debug.LogWarning("[PlayerController] 'Player' 태그 루트를 찾지 못해 이동 정지를 건너뜁니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 이동/회전(로코모션)
|
||||
foreach (var provider in playerRoot.GetComponentsInChildren<LocomotionProvider>(true))
|
||||
provider.enabled = false;
|
||||
|
||||
// 헤드셋/컨트롤러 트래킹 — 실제 포즈를 매 프레임 카메라/손에 적용하는 드라이버를 꺼 시야를 고정.
|
||||
// (컨트롤러 손도 함께 멈춘다. 카메라만 얼리려면 Camera.main의 드라이버만 끄면 됨)
|
||||
foreach (var driver in playerRoot.GetComponentsInChildren<TrackedPoseDriver>(true))
|
||||
driver.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/02_Scripts/Managers/HideDuringLoading.cs
Normal file
11
Assets/02_Scripts/Managers/HideDuringLoading.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using UnityEngine;
|
||||
|
||||
// 이 컴포넌트가 붙은 오브젝트는 씬 로딩 중 화면이 어두워진 순간 SetActive(false)된다.
|
||||
// SceneLoadManager가 전환 시점에 씬에서 찾아 끈다.
|
||||
//
|
||||
// 글로벌 매니저(DontDestroyOnLoad)에 씬 오브젝트를 직접 참조하면 씬을 넘나들 때 참조가 사라지므로,
|
||||
// 참조를 반대로 — 끄고 싶은 오브젝트 쪽에 이 마커를 달아 런타임에 수집한다.
|
||||
// (현재 씬 오브젝트면 어차피 씬 언로드로 사라지지만, 어두워지기 전 전환 구간의 깜빡임을 막아준다.)
|
||||
public class HideDuringLoading : MonoBehaviour
|
||||
{
|
||||
}
|
||||
2
Assets/02_Scripts/Managers/HideDuringLoading.cs.meta
Normal file
2
Assets/02_Scripts/Managers/HideDuringLoading.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59721f2668c7f5c47b205b7d61ff4822
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
public class LocalManager : MonoBehaviour,ISceneInitializable
|
||||
{
|
||||
[SerializeField] private string _startSceneName;
|
||||
[SerializeField] private string _nextSceneName;
|
||||
[SerializeField] private AudioClip _caffebeneBGM;
|
||||
|
||||
@@ -63,7 +64,7 @@ private async Awaitable CaffebeneSequence(int delay)
|
||||
|
||||
// 씬 안의 Animator / 타임라인 / 파티클을 전부 일시정지
|
||||
// (Time.timeScale은 건드리지 않는다 — BGM 페이드와 씬 전환 딜레이가 scaled time 기준이라 함께 멈춰버림)
|
||||
private static void PauseAllAnimations()
|
||||
public static void PauseAllAnimations()
|
||||
{
|
||||
foreach (var animator in FindObjectsByType<Animator>())
|
||||
animator.speed = 0f;
|
||||
@@ -152,4 +153,22 @@ public void OnSceneLoaded()
|
||||
SceneLoadManager.Instance.SetSceneSkybox(_sceneSkybox);
|
||||
}
|
||||
|
||||
public void StartSceneChange(int delay)
|
||||
{
|
||||
_ = StartSceneChangeSequence(delay);
|
||||
}
|
||||
|
||||
private async Awaitable StartSceneChangeSequence(int delay)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Awaitable.WaitForSecondsAsync((float)delay);
|
||||
|
||||
SceneLoadManager.Instance.RequestSceneChange(_startSceneName);
|
||||
}
|
||||
catch (System.OperationCanceledException)
|
||||
{
|
||||
// 씬 전환 등으로 자신이 파괴되어 취소됨
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +204,14 @@ private void MovePlayerToLoadingArea()
|
||||
if (cc != null) cc.enabled = true;
|
||||
}
|
||||
|
||||
// 화면이 어두워진 뒤, HideDuringLoading 마커가 붙은 오브젝트를 전부 끈다 (로딩 중 노출/깜빡임 방지).
|
||||
// 글로벌 매니저라 씬 오브젝트를 직접 참조할 수 없으므로(씬 전환 시 참조가 끊김) 런타임에 씬에서 찾는다.
|
||||
private void DisableDarkObjects()
|
||||
{
|
||||
foreach (var marker in FindObjectsByType<HideDuringLoading>())
|
||||
marker.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void RequestSceneChange(string sceneName)
|
||||
{
|
||||
_ = SceneChange(sceneName);
|
||||
@@ -233,6 +241,9 @@ private async Awaitable SceneChange(string sceneName)
|
||||
// (로딩 룸은 카메라를 따라다니므로 함께 이동한다)
|
||||
MovePlayerToLoadingArea();
|
||||
|
||||
// 어두워진 상태에서 지정 오브젝트들 끄기 (로딩 중 보이면 안 되는 것들)
|
||||
DisableDarkObjects();
|
||||
|
||||
// 로딩 룸에 도착했으니 시야를 다시 연다 (스카이박스 페이드 인과 동시 진행)
|
||||
if (pc != null)
|
||||
_ = pc.FadeSight(true, 0.8f);
|
||||
|
||||
Reference in New Issue
Block a user