육지도착
This commit is contained in:
160
Assets/02_Scripts/Cave/ClamBiteDetector.cs
Normal file
160
Assets/02_Scripts/Cave/ClamBiteDetector.cs
Normal file
@@ -0,0 +1,160 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ClamBiteDetector : MonoBehaviour
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private ClamOpenClose clam;
|
||||
[SerializeField] private RaftHealth health;
|
||||
[SerializeField] private MemoryFragmentReset memoryFragment;
|
||||
|
||||
[Header("Bite Damage")]
|
||||
[SerializeField] private int biteDamage = 20;
|
||||
|
||||
[Header("Bite Zone")]
|
||||
[SerializeField] private Collider biteZoneCollider;
|
||||
|
||||
[Tooltip("조개가 닫히는 동안 이미 한 번 물렸으면 추가 판정을 막습니다.")]
|
||||
[SerializeField] private bool biteOncePerClose = true;
|
||||
|
||||
[Header("Target Tags")]
|
||||
[SerializeField] private string handTag = "PlayerHand";
|
||||
[SerializeField] private string fragmentTag = "MemoryFragment";
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool showDebugLog = true;
|
||||
|
||||
private bool hasBittenThisClose;
|
||||
private readonly HashSet<Collider> collidersInside = new();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (biteZoneCollider == null)
|
||||
biteZoneCollider = GetComponent<Collider>();
|
||||
|
||||
if (biteZoneCollider != null)
|
||||
{
|
||||
biteZoneCollider.isTrigger = true;
|
||||
biteZoneCollider.enabled = false;
|
||||
}
|
||||
|
||||
if (clam == null)
|
||||
clam = GetComponentInParent<ClamOpenClose>();
|
||||
|
||||
if (health == null)
|
||||
health = FindFirstObjectByType<RaftHealth>();
|
||||
|
||||
if (memoryFragment == null)
|
||||
memoryFragment = FindFirstObjectByType<MemoryFragmentReset>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (clam != null)
|
||||
{
|
||||
clam.onCloseStarted.AddListener(EnableBiteWindow);
|
||||
clam.onClosed.AddListener(DisableBiteWindow);
|
||||
clam.onOpened.AddListener(ResetBiteState);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (clam != null)
|
||||
{
|
||||
clam.onCloseStarted.RemoveListener(EnableBiteWindow);
|
||||
clam.onClosed.RemoveListener(DisableBiteWindow);
|
||||
clam.onOpened.RemoveListener(ResetBiteState);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
collidersInside.Add(other);
|
||||
|
||||
if (IsBiteWindowOpen())
|
||||
TryBite(other);
|
||||
}
|
||||
|
||||
private void OnTriggerStay(Collider other)
|
||||
{
|
||||
collidersInside.Add(other);
|
||||
|
||||
if (IsBiteWindowOpen())
|
||||
TryBite(other);
|
||||
}
|
||||
|
||||
private void OnTriggerExit(Collider other)
|
||||
{
|
||||
collidersInside.Remove(other);
|
||||
}
|
||||
|
||||
private void EnableBiteWindow()
|
||||
{
|
||||
hasBittenThisClose = false;
|
||||
|
||||
if (biteZoneCollider != null)
|
||||
biteZoneCollider.enabled = true;
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("[ClamBiteDetector] 조개 물림 판정 ON", this);
|
||||
|
||||
foreach (Collider col in collidersInside)
|
||||
{
|
||||
if (col != null)
|
||||
TryBite(col);
|
||||
}
|
||||
}
|
||||
|
||||
private void DisableBiteWindow()
|
||||
{
|
||||
if (biteZoneCollider != null)
|
||||
biteZoneCollider.enabled = false;
|
||||
|
||||
collidersInside.Clear();
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log("[ClamBiteDetector] 조개 물림 판정 OFF", this);
|
||||
}
|
||||
|
||||
private void ResetBiteState()
|
||||
{
|
||||
hasBittenThisClose = false;
|
||||
}
|
||||
|
||||
private bool IsBiteWindowOpen()
|
||||
{
|
||||
if (biteZoneCollider == null)
|
||||
return false;
|
||||
|
||||
return biteZoneCollider.enabled;
|
||||
}
|
||||
|
||||
private void TryBite(Collider other)
|
||||
{
|
||||
if (other == null)
|
||||
return;
|
||||
|
||||
if (biteOncePerClose && hasBittenThisClose)
|
||||
return;
|
||||
|
||||
bool isHand = other.CompareTag(handTag) || other.GetComponentInParent<XRHandMarker>() != null;
|
||||
bool isFragment = other.CompareTag(fragmentTag) || other.GetComponentInParent<MemoryFragmentReset>() != null;
|
||||
|
||||
if (!isHand && !isFragment)
|
||||
return;
|
||||
|
||||
hasBittenThisClose = true;
|
||||
|
||||
if (health != null)
|
||||
health.TakeDamage(biteDamage);
|
||||
|
||||
if (memoryFragment != null)
|
||||
memoryFragment.ResetFragment();
|
||||
|
||||
if (showDebugLog)
|
||||
{
|
||||
Debug.Log($"[ClamBiteDetector] 조개에게 물림. 데미지 {biteDamage}, 기억의 조각 리셋", this);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user