109 lines
3.4 KiB
C#
109 lines
3.4 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
public class EnemyAttack : MonoBehaviour
|
|
{
|
|
[Header("Attack Settings")]
|
|
public float damage = 10f;
|
|
public float attackRange = 0.5f; // 표면 기준이므로 0.5~1.0 정도면 충분합니다.
|
|
public float attackCooldown = 1.0f;
|
|
|
|
[Header("Visual Feedback")]
|
|
public Renderer enemyRenderer;
|
|
[ColorUsage(true, true)] public Color flashEmissionColor = Color.white * 3f;
|
|
public float flashDuration = 0.1f;
|
|
|
|
private Material _enemyMaterial;
|
|
private Color _originalEmissionColor;
|
|
private float _nextAttackTime;
|
|
|
|
private Transform _target;
|
|
private IDamageable _targetDamageable;
|
|
private EnemyMoveDefault _moveScript;
|
|
private Collider _targetCollider; // 타겟의 콜라이더 캐싱
|
|
|
|
private static readonly int EmissionColorProp = Shader.PropertyToID("_EmissionColor");
|
|
|
|
void Awake()
|
|
{
|
|
_moveScript = GetComponent<EnemyMoveDefault>();
|
|
if (enemyRenderer == null) enemyRenderer = GetComponentInChildren<Renderer>();
|
|
if (enemyRenderer != null)
|
|
{
|
|
_enemyMaterial = enemyRenderer.material;
|
|
_enemyMaterial.EnableKeyword("_EMISSION");
|
|
_originalEmissionColor = _enemyMaterial.GetColor(EmissionColorProp);
|
|
}
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (_moveScript != null && _moveScript.Target != _target)
|
|
{
|
|
SetAttackTarget(_moveScript.Target);
|
|
}
|
|
|
|
if (_target == null) return;
|
|
|
|
// --- 거리 계산 방식 수정 (핵심) ---
|
|
float distance = GetDistanceToTarget();
|
|
|
|
if (distance <= attackRange)
|
|
{
|
|
if (Time.time >= _nextAttackTime)
|
|
{
|
|
Attack();
|
|
}
|
|
}
|
|
}
|
|
|
|
private float GetDistanceToTarget()
|
|
{
|
|
if (_targetCollider == null) return Vector3.Distance(transform.position, _target.position);
|
|
|
|
// 타겟의 표면상에서 내 위치와 가장 가까운 점을 찾습니다.
|
|
Vector3 closestPoint = _targetCollider.ClosestPoint(transform.position);
|
|
|
|
// 내 발밑(transform.position)과 그 표면 사이의 실제 거리를 계산합니다.
|
|
return Vector3.Distance(transform.position, closestPoint);
|
|
}
|
|
|
|
private void Attack()
|
|
{
|
|
if (_target == null) return;
|
|
if (_targetDamageable == null) _targetDamageable = _target.GetComponentInParent<IDamageable>();
|
|
|
|
if (_targetDamageable != null)
|
|
{
|
|
_targetDamageable.TakeDamage(damage);
|
|
_nextAttackTime = Time.time + attackCooldown;
|
|
StartCoroutine(FlashEmissionRoutine());
|
|
Debug.Log($"[공격!] 대상: {_target.name}");
|
|
}
|
|
}
|
|
|
|
public void SetAttackTarget(Transform newTarget)
|
|
{
|
|
_target = newTarget;
|
|
if (_target != null)
|
|
{
|
|
_targetCollider = _target.GetComponentInChildren<Collider>();
|
|
_targetDamageable = _target.GetComponentInParent<IDamageable>();
|
|
}
|
|
else
|
|
{
|
|
_targetCollider = null;
|
|
_targetDamageable = null;
|
|
}
|
|
}
|
|
|
|
private IEnumerator FlashEmissionRoutine()
|
|
{
|
|
if (_enemyMaterial != null)
|
|
{
|
|
_enemyMaterial.SetColor(EmissionColorProp, flashEmissionColor);
|
|
yield return new WaitForSeconds(flashDuration);
|
|
_enemyMaterial.SetColor(EmissionColorProp, _originalEmissionColor);
|
|
}
|
|
}
|
|
} |