육지도착
This commit is contained in:
156
Assets/02_Scripts/Cave/RaftDamageReceiver.cs
Normal file
156
Assets/02_Scripts/Cave/RaftDamageReceiver.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.XR;
|
||||
|
||||
public class RaftDamageReceiver : MonoBehaviour
|
||||
{
|
||||
[Header("References")]
|
||||
[SerializeField] private RaftHealth raftHealth;
|
||||
|
||||
[Header("Damage Cooldown")]
|
||||
[SerializeField] private float sameObstacleDamageCooldown = 1.0f;
|
||||
[SerializeField] private float globalDamageCooldown = 0.2f;
|
||||
|
||||
[Header("Haptic Feedback")]
|
||||
[SerializeField] private bool useHapticFeedback = true;
|
||||
|
||||
[Range(0f, 1f)]
|
||||
[SerializeField] private float hapticAmplitude = 0.6f;
|
||||
|
||||
[SerializeField] private float hapticDuration = 0.15f;
|
||||
|
||||
[Tooltip("체력 데미지 수치에 따라 햅틱 세기를 살짝 키웁니다.")]
|
||||
[SerializeField] private bool scaleHapticByDamage = true;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool showDebugLog = true;
|
||||
|
||||
private readonly Dictionary<DamageObstacle, float> lastDamageTimeByObstacle = new();
|
||||
private float lastGlobalDamageTime = -999f;
|
||||
|
||||
private readonly List<InputDevice> hapticDevices = new();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (raftHealth == null)
|
||||
{
|
||||
raftHealth = GetComponentInParent<RaftHealth>();
|
||||
}
|
||||
|
||||
if (raftHealth == null)
|
||||
{
|
||||
raftHealth = FindFirstObjectByType<RaftHealth>();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
TryDamage(other);
|
||||
}
|
||||
|
||||
private void OnTriggerStay(Collider other)
|
||||
{
|
||||
TryDamage(other);
|
||||
}
|
||||
|
||||
private void TryDamage(Collider other)
|
||||
{
|
||||
if (raftHealth == null)
|
||||
{
|
||||
if (showDebugLog)
|
||||
Debug.LogWarning("[RaftDamageReceiver] RaftHealth가 연결되지 않았습니다.", this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DamageObstacle obstacle = other.GetComponentInParent<DamageObstacle>();
|
||||
|
||||
if (obstacle == null)
|
||||
return;
|
||||
|
||||
if (!obstacle.CanDamage)
|
||||
return;
|
||||
|
||||
if (raftHealth.IsDead)
|
||||
return;
|
||||
|
||||
float now = Time.time;
|
||||
|
||||
if (now < lastGlobalDamageTime + globalDamageCooldown)
|
||||
return;
|
||||
|
||||
if (lastDamageTimeByObstacle.TryGetValue(obstacle, out float lastObstacleTime))
|
||||
{
|
||||
if (now < lastObstacleTime + sameObstacleDamageCooldown)
|
||||
return;
|
||||
}
|
||||
|
||||
int damage = obstacle.Damage;
|
||||
|
||||
if (damage <= 0)
|
||||
return;
|
||||
|
||||
raftHealth.TakeDamage(damage);
|
||||
|
||||
lastGlobalDamageTime = now;
|
||||
lastDamageTimeByObstacle[obstacle] = now;
|
||||
|
||||
PlayHaptic(damage);
|
||||
|
||||
if (showDebugLog)
|
||||
{
|
||||
Debug.Log($"[RaftDamageReceiver] {obstacle.name} 충돌. 데미지: {damage}");
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayHaptic(int damage)
|
||||
{
|
||||
if (!useHapticFeedback)
|
||||
return;
|
||||
|
||||
float amplitude = hapticAmplitude;
|
||||
|
||||
if (scaleHapticByDamage)
|
||||
{
|
||||
// 10 데미지 = 기본값, 15 이상 = 조금 더 강하게
|
||||
float damageScale = Mathf.Clamp(damage / 10f, 1f, 1.5f);
|
||||
amplitude *= damageScale;
|
||||
}
|
||||
|
||||
amplitude = Mathf.Clamp01(amplitude);
|
||||
|
||||
SendHapticToDevice(XRNode.LeftHand, amplitude, hapticDuration);
|
||||
SendHapticToDevice(XRNode.RightHand, amplitude, hapticDuration);
|
||||
}
|
||||
|
||||
private void SendHapticToDevice(XRNode node, float amplitude, float duration)
|
||||
{
|
||||
InputDevice device = InputDevices.GetDeviceAtXRNode(node);
|
||||
|
||||
if (!device.isValid)
|
||||
{
|
||||
if (showDebugLog)
|
||||
Debug.Log($"[RaftDamageReceiver] {node} 컨트롤러를 찾지 못했습니다.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!device.TryGetHapticCapabilities(out HapticCapabilities capabilities))
|
||||
{
|
||||
if (showDebugLog)
|
||||
Debug.Log($"[RaftDamageReceiver] {node} 햅틱 기능을 확인할 수 없습니다.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!capabilities.supportsImpulse)
|
||||
{
|
||||
if (showDebugLog)
|
||||
Debug.Log($"[RaftDamageReceiver] {node} 컨트롤러가 impulse 햅틱을 지원하지 않습니다.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
device.SendHapticImpulse(0u, amplitude, duration);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user