using UnityEngine;
///
/// 바닥에 떨어진 화살 아이템 (발사체로도 사용 가능)
/// 모드 전환: 아이템 모드 ↔ 발사 모드
///
public class ArrowItem : MonoBehaviour
{
[Header("--- 화살 정보 ---")]
[SerializeField] private string arrowName = "기본 화살";
[SerializeField] private float damage = 15f;
[SerializeField] private float speed = 20f;
[SerializeField] private float range = 15f;
[Header("--- UI 표시 (아이템 모드) ---")]
[SerializeField] private GameObject pickupUI;
[SerializeField] private float uiDisplayRange = 3f;
[Header("--- 비주얼 ---")]
[SerializeField] private GameObject visualModel; // 화살 모델
private Transform playerTransform;
private Rigidbody rb;
private Collider col;
// 모드 구분
private bool isItemMode = true; // true: 아이템 모드, false: 발사 모드
private Vector3 startPos;
private bool isFired = false;
private void Awake()
{
rb = GetComponent();
col = GetComponent();
}
private void Start()
{
if (isItemMode)
{
SetupAsItem();
}
}
private void Update()
{
if (isItemMode)
{
UpdateItemMode();
}
else
{
UpdateProjectileMode();
}
}
#region 아이템 모드
private void SetupAsItem()
{
// 플레이어 찾기
GameObject player = GameObject.FindGameObjectWithTag("Player");
if (player != null)
{
playerTransform = player.transform;
}
// UI 숨기기
if (pickupUI != null)
{
pickupUI.SetActive(false);
}
// 물리 설정 (바닥에 떨어진 아이템)
if (rb != null)
{
rb.useGravity = true;
rb.isKinematic = false;
}
if (col != null)
{
col.isTrigger = true;
}
}
private void UpdateItemMode()
{
if (playerTransform == null || pickupUI == null) return;
// 플레이어와의 거리 체크 (UI 표시용)
float distance = Vector3.Distance(transform.position, playerTransform.position);
bool isNear = distance <= uiDisplayRange;
pickupUI.SetActive(isNear);
}
///
/// PlayerInteraction에서 호출
///
public void Pickup(PlayerAttack playerAttack)
{
if (playerAttack == null) return;
// 자기 자신을 복제해서 발사용 프리팹으로 제공
GameObject arrowPrefab = gameObject;
playerAttack.SwapArrow(arrowPrefab);
Debug.Log($"화살이 [{arrowName}](으)로 교체되었습니다!");
// 아이템 제거
Destroy(gameObject);
}
#endregion
#region 발사 모드
///
/// PlayerAttack에서 호출 (발사 초기화)
///
public void Initialize(float dmg, float arrowSpeed, float maxRange)
{
Debug.Log($"🏹 화살 발사! 방향: {transform.forward}, 속도: {arrowSpeed}");
// 발사 모드로 전환
isItemMode = false;
isFired = true;
// 스탯 설정
this.damage = dmg;
this.speed = arrowSpeed;
this.range = maxRange;
this.startPos = transform.position;
// UI 숨기기
if (pickupUI != null)
{
pickupUI.SetActive(false);
}
// 물리 설정 (발사체)
if (rb != null)
{
rb.useGravity = false;
rb.isKinematic = false;
// ✅ [중요] transform.forward 방향으로 발사
// 화살이 Z축(파란 화살표) 방향을 앞으로 향하고 있어야 함!
Vector3 shootDirection = transform.forward;
rb.velocity = shootDirection * speed;
Debug.Log($"📍 발사 방향: {shootDirection}, 속도 벡터: {rb.velocity}");
}
if (col != null)
{
col.isTrigger = true;
}
// 5초 후 자동 삭제
Destroy(gameObject, 5f);
}
private void UpdateProjectileMode()
{
if (!isFired) return;
// 최대 사거리 체크
if (Vector3.Distance(startPos, transform.position) >= range)
{
Destroy(gameObject);
}
}
private void OnTriggerEnter(Collider other)
{
// 아이템 모드에서는 충돌 무시
if (isItemMode) return;
// 발사 모드: 적 또는 벽 충돌
if (other.CompareTag("Enemy"))
{
var monster = other.GetComponent();
if (monster != null)
{
monster.TakeDamage(damage);
}
Destroy(gameObject);
}
else if (other.CompareTag("Wall") || other.CompareTag("Ground"))
{
Destroy(gameObject);
}
}
#endregion
#region 외부 설정용
///
/// 몬스터 드롭 시 화살 정보 설정
///
public void SetArrowData(string name, float dmg, float spd, float rng)
{
arrowName = name;
damage = dmg;
speed = spd;
range = rng;
}
#endregion
}