110 lines
3.6 KiB
C#
110 lines
3.6 KiB
C#
using UnityEngine;
|
|
|
|
public class EquippableItem : MonoBehaviour
|
|
{
|
|
[SerializeField] private WeaponConfig config;
|
|
public WeaponConfig Config => config;
|
|
|
|
[Header("--- 데미지 밸런스 ---")]
|
|
[SerializeField] private float lv1Mult = 1.0f;
|
|
[SerializeField] private float lv2Mult = 1.5f;
|
|
[SerializeField] private float lv3Mult = 2.5f;
|
|
[SerializeField] private float strengthBonusFactor = 0.02f;
|
|
|
|
private Rigidbody _rb;
|
|
private Collider _col;
|
|
private bool _isThrown;
|
|
private int _chargeLevel;
|
|
private Stats _thrower; // 던진 사람의 정보
|
|
private Vector3 _originalWorldScale;
|
|
|
|
private void Awake()
|
|
{
|
|
_rb = GetComponent<Rigidbody>();
|
|
_col = GetComponent<Collider>();
|
|
_originalWorldScale = transform.lossyScale;
|
|
}
|
|
|
|
public void OnPickedUp(Transform hand)
|
|
{
|
|
_isThrown = false;
|
|
transform.SetParent(hand);
|
|
|
|
transform.localScale = new Vector3(
|
|
_originalWorldScale.x / hand.lossyScale.x,
|
|
_originalWorldScale.y / hand.lossyScale.y,
|
|
_originalWorldScale.z / hand.lossyScale.z
|
|
);
|
|
|
|
transform.localPosition = Vector3.zero;
|
|
transform.localRotation = Quaternion.identity;
|
|
|
|
if (_rb) _rb.isKinematic = true;
|
|
if (_col) _col.enabled = false;
|
|
}
|
|
|
|
public void OnDropped(Vector3 throwDir)
|
|
{
|
|
_isThrown = false;
|
|
transform.SetParent(null);
|
|
transform.localScale = _originalWorldScale;
|
|
|
|
if (_rb)
|
|
{
|
|
_rb.isKinematic = false;
|
|
Vector3 force = (throwDir + Vector3.up * 0.5f).normalized * 5f;
|
|
_rb.AddForce(force, ForceMode.Impulse);
|
|
_rb.AddTorque(Random.insideUnitSphere * 3f, ForceMode.Impulse);
|
|
}
|
|
if (_col) _col.enabled = true;
|
|
}
|
|
|
|
public void OnThrown(Vector3 dir, float force, int lv, Stats s)
|
|
{
|
|
_isThrown = true;
|
|
_chargeLevel = lv;
|
|
_thrower = s; // 던진 사람(플레이어)을 기억합니다.
|
|
|
|
transform.SetParent(null);
|
|
transform.localScale = _originalWorldScale;
|
|
|
|
if (_rb)
|
|
{
|
|
_rb.isKinematic = false;
|
|
_rb.AddForce(dir * force, ForceMode.Impulse);
|
|
_rb.AddTorque(transform.right * 10f, ForceMode.Impulse);
|
|
}
|
|
if (_col) _col.enabled = true;
|
|
}
|
|
|
|
private void OnCollisionEnter(Collision collision)
|
|
{
|
|
if (!_isThrown) return;
|
|
|
|
// ⭐ [자폭 방지 핵심 로직]
|
|
// 부딪힌 대상이 나를 던진 사람(Stats를 가진 오브젝트)이라면 데미지를 주지 않고 무시합니다.
|
|
if (_thrower != null && collision.gameObject == _thrower.gameObject)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (collision.gameObject.TryGetComponent<IDamageable>(out var target))
|
|
{
|
|
float mult = _chargeLevel == 3 ? lv3Mult : (_chargeLevel == 2 ? lv2Mult : lv1Mult);
|
|
float strengthBonus = 1f + (_thrower.Strength * strengthBonusFactor);
|
|
float finalDamage = (_thrower.BaseAttackDamage + (config.BaseDamage * strengthBonus)) * mult;
|
|
|
|
target.TakeDamage(finalDamage);
|
|
Debug.Log($"<color=orange>[투척 적중]</color> {collision.gameObject.name}에게 {finalDamage:F1} 데미지!");
|
|
|
|
// ⭐ 적에게 맞은 경우 공격 판정을 즉시 종료 (관통을 원하면 이 줄을 지우세요)
|
|
_isThrown = false;
|
|
}
|
|
|
|
// 벽이나 바닥에 부딪힌 경우에도 공격 판정 종료
|
|
if (collision.gameObject.layer != LayerMask.NameToLayer("Player"))
|
|
{
|
|
_isThrown = false;
|
|
}
|
|
}
|
|
} |