126 lines
7.1 KiB
C#
126 lines
7.1 KiB
C#
|
|
using UnityEngine; // 유니티 기능을 불러올거에요 -> UnityEngine을
|
||
|
|
|
||
|
|
// ============================================================
|
||
|
|
// ZoneBGMTrigger
|
||
|
|
//
|
||
|
|
// 역할: 플레이어가 트리거 존에 진입/이탈할 때
|
||
|
|
// AudioManager에 BGM 전환 요청
|
||
|
|
//
|
||
|
|
// 사용법:
|
||
|
|
// 1. 빈 오브젝트 생성
|
||
|
|
// 2. Collider 추가 → Is Trigger 체크
|
||
|
|
// 3. 이 컴포넌트 Add Component
|
||
|
|
// 4. Inspector에서 BGM 클립 연결
|
||
|
|
// 5. Player Tag = "Player" 확인
|
||
|
|
// ============================================================
|
||
|
|
|
||
|
|
[RequireComponent(typeof(Collider))] // 컴포넌트를 강제 추가할거에요 -> Collider를
|
||
|
|
public class ZoneBGMTrigger : MonoBehaviour // 클래스를 선언할거에요 -> ZoneBGMTrigger를
|
||
|
|
{
|
||
|
|
// ─────────────────────────────────────────────────────────
|
||
|
|
// Inspector 설정
|
||
|
|
// ─────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
[Header("=== 구역 설정 ===")]
|
||
|
|
|
||
|
|
[Tooltip("이 구역에서 재생할 BGM")]
|
||
|
|
[SerializeField] private AudioClip zoneBGM; // 변수를 선언할거에요 -> 이 구역 BGM을
|
||
|
|
|
||
|
|
[Tooltip("구역 이름 (디버그/식별용)")]
|
||
|
|
[SerializeField] private string zoneName = "Zone"; // 변수를 선언할거에요 -> 구역 이름을
|
||
|
|
|
||
|
|
[Header("=== 전환 설정 ===")]
|
||
|
|
|
||
|
|
[Tooltip("BGM 페이드 시간 (-1이면 AudioManager 기본값 사용)")]
|
||
|
|
[SerializeField] private float fadeDuration = -1f; // 변수를 선언할거에요 -> 페이드 시간을
|
||
|
|
|
||
|
|
[Tooltip("이 구역 이탈 시 BGM 정지 여부\n켜면: 이탈 시 BGM 정지\n꺼면: 이탈해도 BGM 유지 (다른 존 진입 전까지)")]
|
||
|
|
[SerializeField] private bool stopOnExit = false; // 변수를 선언할거에요 -> 이탈 시 정지 여부를
|
||
|
|
|
||
|
|
[Tooltip("진입 감지 Tag (기본 Player)")]
|
||
|
|
[SerializeField] private string playerTag = "Player"; // 변수를 선언할거에요 -> 플레이어 태그를
|
||
|
|
|
||
|
|
// ─────────────────────────────────────────────────────────
|
||
|
|
// 초기화
|
||
|
|
// ─────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
private void Awake() // 함수를 실행할거에요 -> 초기화를
|
||
|
|
{
|
||
|
|
// Collider가 Trigger로 설정됐는지 확인
|
||
|
|
Collider col = GetComponent<Collider>(); // 가져올거에요 -> Collider를
|
||
|
|
if (!col.isTrigger) // 조건이 맞으면 실행할거에요 -> Trigger가 아니면
|
||
|
|
{
|
||
|
|
col.isTrigger = true; // 설정할거에요 -> Trigger로
|
||
|
|
Debug.LogWarning($"[ZoneBGMTrigger] {gameObject.name}의 Collider를 자동으로 IsTrigger = true로 설정했어요."); // 경고를 출력할거에요
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ─────────────────────────────────────────────────────────
|
||
|
|
// 트리거 감지
|
||
|
|
// ─────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
private void OnTriggerEnter(Collider other) // 함수를 실행할거에요 -> 트리거 진입 시
|
||
|
|
{
|
||
|
|
if (!other.CompareTag(playerTag)) return; // 중단할거에요 -> 플레이어가 아니면
|
||
|
|
|
||
|
|
if (AudioManager.Instance == null) // 조건이 맞으면 실행할거에요 -> AudioManager 없으면
|
||
|
|
{
|
||
|
|
Debug.LogWarning("[ZoneBGMTrigger] AudioManager가 씬에 없어요!"); // 경고를 출력할거에요
|
||
|
|
return; // 중단할거에요
|
||
|
|
}
|
||
|
|
|
||
|
|
if (zoneBGM == null) // 조건이 맞으면 실행할거에요 -> BGM 클립 없으면
|
||
|
|
{
|
||
|
|
Debug.LogWarning($"[ZoneBGMTrigger] {zoneName}에 BGM 클립이 연결되지 않았어요!"); // 경고를 출력할거에요
|
||
|
|
return; // 중단할거에요
|
||
|
|
}
|
||
|
|
|
||
|
|
AudioManager.Instance.PlayBGM(zoneBGM, fadeDuration); // 재생할거에요 -> 이 구역 BGM을
|
||
|
|
Debug.Log($"[ZoneBGMTrigger] 구역 진입: {zoneName}"); // 출력할거에요 -> 진입 로그를
|
||
|
|
}
|
||
|
|
|
||
|
|
private void OnTriggerExit(Collider other) // 함수를 실행할거에요 -> 트리거 이탈 시
|
||
|
|
{
|
||
|
|
if (!other.CompareTag(playerTag)) return; // 중단할거에요 -> 플레이어가 아니면
|
||
|
|
|
||
|
|
if (!stopOnExit) return; // 중단할거에요 -> 이탈 시 정지 옵션이 꺼져있으면
|
||
|
|
|
||
|
|
if (AudioManager.Instance == null) return; // 중단할거에요 -> AudioManager 없으면
|
||
|
|
|
||
|
|
AudioManager.Instance.StopBGM(fadeDuration); // 정지할거에요 -> BGM을 페이드아웃으로
|
||
|
|
Debug.Log($"[ZoneBGMTrigger] 구역 이탈: {zoneName}"); // 출력할거에요 -> 이탈 로그를
|
||
|
|
}
|
||
|
|
|
||
|
|
// ─────────────────────────────────────────────────────────
|
||
|
|
// 에디터 디버그 (씬 뷰에서 트리거 영역 시각화)
|
||
|
|
// ─────────────────────────────────────────────────────────
|
||
|
|
|
||
|
|
private void OnDrawGizmos() // 함수를 실행할거에요 -> 씬 뷰 기즈모를
|
||
|
|
{
|
||
|
|
Collider col = GetComponent<Collider>(); // 가져올거에요 -> Collider를
|
||
|
|
if (col == null) return; // 중단할거에요 -> 없으면
|
||
|
|
|
||
|
|
Gizmos.color = new Color(0.2f, 0.8f, 1f, 0.2f); // 설정할거에요 -> 하늘색 반투명으로
|
||
|
|
Gizmos.matrix = transform.localToWorldMatrix; // 설정할거에요 -> 오브젝트 기준 행렬로
|
||
|
|
|
||
|
|
if (col is BoxCollider box) // 조건이 맞으면 실행할거에요 -> BoxCollider면
|
||
|
|
{
|
||
|
|
Gizmos.DrawCube(box.center, box.size); // 그릴거에요 -> 채워진 박스를
|
||
|
|
Gizmos.color = new Color(0.2f, 0.8f, 1f, 0.8f); // 설정할거에요 -> 불투명 테두리 색으로
|
||
|
|
Gizmos.DrawWireCube(box.center, box.size); // 그릴거에요 -> 테두리 박스를
|
||
|
|
}
|
||
|
|
else if (col is SphereCollider sphere) // 조건이 맞으면 실행할거에요 -> SphereCollider면
|
||
|
|
{
|
||
|
|
Gizmos.DrawSphere(sphere.center, sphere.radius); // 그릴거에요 -> 채워진 구를
|
||
|
|
Gizmos.color = new Color(0.2f, 0.8f, 1f, 0.8f); // 설정할거에요 -> 불투명 테두리 색으로
|
||
|
|
Gizmos.DrawWireSphere(sphere.center, sphere.radius); // 그릴거에요 -> 테두리 구를
|
||
|
|
}
|
||
|
|
|
||
|
|
#if UNITY_EDITOR
|
||
|
|
// 구역 이름 씬 뷰에 표시
|
||
|
|
UnityEditor.Handles.color = Color.cyan; // 설정할거에요 -> 하늘색으로
|
||
|
|
UnityEditor.Handles.Label(transform.position + Vector3.up * 1.5f, $"♪ {zoneName}"); // 출력할거에요 -> 구역 이름을
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
}
|