Projext/Assets/Scripts/Player/Controller/ArrowPickup.cs
2026-02-09 23:49:44 +09:00

228 lines
6.8 KiB
C#

using UnityEngine;
/// <summary>
/// 바닥에 떨어진 화살 아이템 (아이템 전용 — 발사체 기능 제거됨)
/// 습득 시 PlayerAttack에 파티클 프리팹 + 속성 정보를 전달합니다.
/// </summary>
public class ArrowPickup : MonoBehaviour
{
[Header("--- 화살 아이템 정보 ---")]
[SerializeField] private string arrowName = "기본 화살";
[SerializeField] private ArrowElementType elementType = ArrowElementType.None;
[Header("--- 스탯 ---")]
[SerializeField] private float baseDamage = 15f;
[SerializeField] private float elementDamage = 5f;
[SerializeField] private float elementDuration = 3f;
[Header("--- 발사체 파티클 ---")]
[Tooltip("이 화살이 장착될 때 발사할 파티클 프리팹")]
[SerializeField] private GameObject projectilePrefab;
[Header("--- 비주얼 (필드 아이템) ---")]
[SerializeField] private GameObject visualModel;
[Header("--- UI 표시 ---")]
[SerializeField] private GameObject pickupUI;
[SerializeField] private float uiDisplayRange = 3f;
[Header("--- Collider 설정 (자동 탐지) ---")]
[Tooltip("아이템 습득용 Sphere Collider (Trigger)")]
[SerializeField] private Collider pickupCollider;
[Tooltip("바닥 충돌용 Box Collider (물리)")]
[SerializeField] private Collider physicsCollider;
private Transform playerTransform;
private Rigidbody rb;
/// <summary>
/// [NEW] ArrowData 구조체로 정보 패키징
/// </summary>
public ArrowData GetArrowData()
{
return new ArrowData
{
arrowName = this.arrowName,
elementType = this.elementType,
baseDamage = this.baseDamage,
elementDamage = this.elementDamage,
elementDuration = this.elementDuration,
projectilePrefab = this.projectilePrefab
};
}
private void Awake()
{
rb = GetComponent<Rigidbody>();
if (pickupCollider == null || physicsCollider == null)
{
AutoDetectColliders();
}
}
/// <summary>
/// Collider 자동 탐지 (기존 로직 유지)
/// </summary>
private void AutoDetectColliders()
{
Collider[] allColliders = GetComponents<Collider>();
foreach (Collider col in allColliders)
{
if (col is SphereCollider && pickupCollider == null)
{
pickupCollider = col;
Debug.Log($"습득용 Collider: {col.GetType().Name}");
}
else if (col is BoxCollider && physicsCollider == null)
{
physicsCollider = col;
Debug.Log($"물리용 Collider: {col.GetType().Name}");
}
}
}
private void Start()
{
SetupAsItem();
}
/// <summary>
/// 아이템 모드 설정 (기존 로직 유지 + 단순화)
/// </summary>
private void SetupAsItem()
{
GameObject player = GameObject.FindGameObjectWithTag("Player");
if (player != null)
{
playerTransform = player.transform;
}
if (pickupUI != null) pickupUI.SetActive(false);
// Collider 설정
if (pickupCollider != null)
{
pickupCollider.enabled = true;
pickupCollider.isTrigger = true;
}
if (physicsCollider != null)
{
physicsCollider.enabled = true;
physicsCollider.isTrigger = false;
}
// 물리 설정
if (rb != null)
{
rb.useGravity = true;
rb.isKinematic = false;
rb.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
}
}
private void Update()
{
if (playerTransform == null || pickupUI == null) return;
float distance = Vector3.Distance(transform.position, playerTransform.position);
pickupUI.SetActive(distance <= uiDisplayRange);
}
/// <summary>
/// [MODIFIED] PlayerInteraction에서 'E' 키를 눌렀을 때 호출
/// 기존: SwapArrow(gameObject) → 변경: SetCurrentArrow(ArrowData)
/// </summary>
public void Pickup(PlayerAttack playerAttack)
{
if (playerAttack == null) return;
// ArrowData를 패키징하여 PlayerAttack에 전달
ArrowData data = GetArrowData();
playerAttack.SetCurrentArrow(data);
Debug.Log($"[{arrowName}] 화살 습득! 속성: {elementType}");
// 아이템 제거
Destroy(gameObject);
}
/// <summary>
/// 몬스터 드롭 시 화살 정보 설정 (기존 함수 유지)
/// </summary>
public void SetArrowData(string name, float dmg, float spd, float rng)
{
arrowName = name;
baseDamage = dmg;
}
/// <summary>
/// [NEW] 속성 정보까지 포함한 전체 세팅 함수
/// </summary>
public void SetArrowDataFull(
string name,
ArrowElementType element,
float baseDmg,
float elemDmg,
float elemDur,
GameObject particlePrefab)
{
arrowName = name;
elementType = element;
baseDamage = baseDmg;
elementDamage = elemDmg;
elementDuration = elemDur;
projectilePrefab = particlePrefab;
}
/// <summary>
/// 바닥 충돌 시 속도 감쇠 (기존 로직 유지)
/// </summary>
private void OnCollisionEnter(Collision collision)
{
if (rb != null && collision.gameObject.CompareTag("Ground"))
{
rb.velocity *= 0.5f;
rb.angularVelocity *= 0.5f;
}
}
#region
private void OnDrawGizmosSelected()
{
if (pickupCollider != null && pickupCollider.enabled)
{
Gizmos.color = Color.green;
if (pickupCollider is SphereCollider sphere)
{
Gizmos.DrawWireSphere(transform.position + sphere.center, sphere.radius);
}
}
if (physicsCollider != null && physicsCollider.enabled)
{
Gizmos.color = Color.blue;
if (physicsCollider is BoxCollider box)
{
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawWireCube(box.center, box.size);
}
}
// [NEW] 속성 색상 표시
switch (elementType)
{
case ArrowElementType.Fire: Gizmos.color = Color.red; break;
case ArrowElementType.Ice: Gizmos.color = Color.cyan; break;
case ArrowElementType.Poison: Gizmos.color = new Color(0.5f, 1f, 0f); break;
case ArrowElementType.Lightning: Gizmos.color = Color.yellow; break;
default: Gizmos.color = Color.white; break;
}
Gizmos.DrawWireSphere(transform.position, 0.3f);
}
#endregion
}