플레이어 관련 수정

힘 수치 관련 제거
This commit is contained in:
윤기주_playm 2026-02-08 23:20:23 +09:00
parent 4fbeb8d675
commit 9128200125
8 changed files with 42 additions and 125 deletions

View File

@ -345,7 +345,7 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
optimizationDistance: 40 optimizationDistance: 40
maxHP: 100 maxHP: 5
attackDamage: 10 attackDamage: 10
expReward: 10 expReward: 10
moveSpeed: 3.5 moveSpeed: 3.5

View File

@ -1,17 +1,12 @@
using System.Collections; using UnityEngine;
using System.Collections.Generic;
using UnityEngine;
public class RandomStatCardInstance public class RandomStatCardInstance
{ {
private RandomStatCardData data; private RandomStatCardData data;
private StatType statType; private StatType statType;
private int value; private int value;
private bool isConfirmed = false; private bool isConfirmed = false;
private Stats stats;
private Stats stats; // ⭐ 대상 Stats
public RandomStatCardInstance(RandomStatCardData data, Stats stats) public RandomStatCardInstance(RandomStatCardData data, Stats stats)
{ {
@ -19,7 +14,6 @@ public class RandomStatCardInstance
this.stats = stats; this.stats = stats;
} }
// 🔍 미리보기용 랜덤
public void RollPreview() public void RollPreview()
{ {
statType = data.possibleStats[Random.Range(0, data.possibleStats.Length)]; statType = data.possibleStats[Random.Range(0, data.possibleStats.Length)];
@ -27,23 +21,19 @@ public class RandomStatCardInstance
isConfirmed = false; isConfirmed = false;
} }
// UI 표시용
public string GetText() public string GetText()
{ {
string sign = value >= 0 ? "+" : ""; string sign = value >= 0 ? "+" : "";
return $"{statType} {sign}{value}"; return $"{statType} {sign}{value}";
} }
// ✅ 선택 시 호출
public void Confirm() public void Confirm()
{ {
if (isConfirmed) return; if (isConfirmed) return;
ApplyStat(); ApplyStat();
isConfirmed = true; isConfirmed = true;
} }
// ⭐ 실제 스탯 적용
private void ApplyStat() private void ApplyStat()
{ {
if (stats == null) return; if (stats == null) return;
@ -58,13 +48,11 @@ public class RandomStatCardInstance
stats.AddMoveSpeed(value); stats.AddMoveSpeed(value);
break; break;
case StatType.Strength: // ✨ [제거] case StatType.Strength 삭제됨
stats.AddStrength(value);
break;
case StatType.Damage: case StatType.Damage:
stats.AddAttackDamage(value); stats.AddAttackDamage(value);
break; break;
} }
} }
} }

View File

@ -9,13 +9,13 @@ public class EquippableItem : MonoBehaviour
[SerializeField] private float lv1Mult = 1.0f; [SerializeField] private float lv1Mult = 1.0f;
[SerializeField] private float lv2Mult = 1.5f; [SerializeField] private float lv2Mult = 1.5f;
[SerializeField] private float lv3Mult = 2.5f; [SerializeField] private float lv3Mult = 2.5f;
[SerializeField] private float strengthBonusFactor = 0.02f; // [제거] strengthBonusFactor 변수 삭제
private Rigidbody _rb; private Rigidbody _rb;
private Collider _col; private Collider _col;
private bool _isThrown; private bool _isThrown;
private int _chargeLevel; private int _chargeLevel;
private Stats _thrower; // 던진 사람의 정보 private Stats _thrower;
private Vector3 _originalWorldScale; private Vector3 _originalWorldScale;
private void Awake() private void Awake()
@ -29,16 +29,13 @@ public class EquippableItem : MonoBehaviour
{ {
_isThrown = false; _isThrown = false;
transform.SetParent(hand); transform.SetParent(hand);
transform.localScale = new Vector3( transform.localScale = new Vector3(
_originalWorldScale.x / hand.lossyScale.x, _originalWorldScale.x / hand.lossyScale.x,
_originalWorldScale.y / hand.lossyScale.y, _originalWorldScale.y / hand.lossyScale.y,
_originalWorldScale.z / hand.lossyScale.z _originalWorldScale.z / hand.lossyScale.z
); );
transform.localPosition = Vector3.zero; transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity; transform.localRotation = Quaternion.identity;
if (_rb) _rb.isKinematic = true; if (_rb) _rb.isKinematic = true;
if (_col) _col.enabled = false; if (_col) _col.enabled = false;
} }
@ -48,7 +45,6 @@ public class EquippableItem : MonoBehaviour
_isThrown = false; _isThrown = false;
transform.SetParent(null); transform.SetParent(null);
transform.localScale = _originalWorldScale; transform.localScale = _originalWorldScale;
if (_rb) if (_rb)
{ {
_rb.isKinematic = false; _rb.isKinematic = false;
@ -63,11 +59,9 @@ public class EquippableItem : MonoBehaviour
{ {
_isThrown = true; _isThrown = true;
_chargeLevel = lv; _chargeLevel = lv;
_thrower = s; // 던진 사람(플레이어)을 기억합니다. _thrower = s;
transform.SetParent(null); transform.SetParent(null);
transform.localScale = _originalWorldScale; transform.localScale = _originalWorldScale;
if (_rb) if (_rb)
{ {
_rb.isKinematic = false; _rb.isKinematic = false;
@ -80,31 +74,20 @@ public class EquippableItem : MonoBehaviour
private void OnCollisionEnter(Collision collision) private void OnCollisionEnter(Collision collision)
{ {
if (!_isThrown) return; if (!_isThrown) return;
if (_thrower != null && collision.gameObject == _thrower.gameObject) return;
// ⭐ [자폭 방지 핵심 로직]
// 부딪힌 대상이 나를 던진 사람(Stats를 가진 오브젝트)이라면 데미지를 주지 않고 무시합니다.
if (_thrower != null && collision.gameObject == _thrower.gameObject)
{
return;
}
if (collision.gameObject.TryGetComponent<IDamageable>(out var target)) if (collision.gameObject.TryGetComponent<IDamageable>(out var target))
{ {
float mult = _chargeLevel == 3 ? lv3Mult : (_chargeLevel == 2 ? lv2Mult : lv1Mult); float mult = _chargeLevel == 3 ? lv3Mult : (_chargeLevel == 2 ? lv2Mult : lv1Mult);
float strengthBonus = 1f + (_thrower.Strength * strengthBonusFactor);
float finalDamage = (_thrower.BaseAttackDamage + (config.BaseDamage * strengthBonus)) * mult; // ✨ [수정] 힘 보너스 로직 제거. (플레이어 기본 공격력 + 무기 대미지) * 차지 배율
float finalDamage = (_thrower.BaseAttackDamage + config.BaseDamage) * mult;
target.TakeDamage(finalDamage); target.TakeDamage(finalDamage);
Debug.Log($"<color=orange>[투척 적중]</color> {collision.gameObject.name}에게 {finalDamage:F1} 데미지!"); Debug.Log($"<color=orange>[투척 적중]</color> {collision.gameObject.name}에게 {finalDamage:F1} 데미지!");
// ⭐ 적에게 맞은 경우 공격 판정을 즉시 종료 (관통을 원하면 이 줄을 지우세요)
_isThrown = false; _isThrown = false;
} }
// 벽이나 바닥에 부딪힌 경우에도 공격 판정 종료 if (collision.gameObject.layer != LayerMask.NameToLayer("Player")) _isThrown = false;
if (collision.gameObject.layer != LayerMask.NameToLayer("Player"))
{
_isThrown = false;
}
} }
} }

View File

@ -16,45 +16,29 @@ public class PlayerInteraction : MonoBehaviour
Collider[] hits = Physics.OverlapSphere(transform.position, interactRange, itemLayer); Collider[] hits = Physics.OverlapSphere(transform.position, interactRange, itemLayer);
foreach (var hit in hits) foreach (var hit in hits)
{ {
// 🏹 [새로 추가] 화살 아이템 습득
if (hit.TryGetComponent<ArrowItem>(out var arrowItem)) if (hit.TryGetComponent<ArrowItem>(out var arrowItem))
{ {
PickupArrow(arrowItem); PickupArrow(arrowItem);
break; break;
} }
// 기존 무기 습득
if (hit.TryGetComponent<EquippableItem>(out var item)) if (hit.TryGetComponent<EquippableItem>(out var item))
{ {
if (playerStats.Strength >= item.Config.RequiredStrength) // ✨ [수정] 힘 제한 없이 무조건 습득 가능하도록 변경
{ EquipWeapon(item);
EquipWeapon(item); break;
break;
}
else { CinemachineShake.Instance?.ShakeNoNo(); continue; }
} }
// 기존 포션/제단
if (hit.TryGetComponent<HealthPotion>(out var potion)) { potion.Use(GetComponent<PlayerHealth>()); break; } if (hit.TryGetComponent<HealthPotion>(out var potion)) { potion.Use(GetComponent<PlayerHealth>()); break; }
if (hit.TryGetComponent<HealthAltar>(out var altar)) { altar.Use(GetComponent<PlayerHealth>()); break; } if (hit.TryGetComponent<HealthAltar>(out var altar)) { altar.Use(GetComponent<PlayerHealth>()); break; }
} }
} }
// 🏹 [새 함수] 화살 습득 처리
private void PickupArrow(ArrowItem arrowItem) private void PickupArrow(ArrowItem arrowItem)
{ {
if (arrowItem == null) return; if (arrowItem == null) return;
// PlayerAttack 찾아서 화살 교체
PlayerAttack playerAttack = GetComponent<PlayerAttack>(); PlayerAttack playerAttack = GetComponent<PlayerAttack>();
if (playerAttack != null) if (playerAttack != null) arrowItem.Pickup(playerAttack);
{
arrowItem.Pickup(playerAttack);
}
else
{
Debug.LogWarning("PlayerAttack 컴포넌트를 찾을 수 없습니다!");
}
} }
private void EquipWeapon(EquippableItem item) private void EquipWeapon(EquippableItem item)
@ -66,10 +50,9 @@ public class PlayerInteraction : MonoBehaviour
if (playerStats != null) if (playerStats != null)
{ {
playerStats.weaponDamage = item.Config.BaseDamage; playerStats.weaponDamage = item.Config.BaseDamage;
playerStats.UpdateWeaponWeight(item.Config.RequiredStrength); // ✨ [제거] UpdateWeaponWeight 호출 삭제
} }
// ⭐ 무기 장착 즉시 UI 갱신
FindObjectOfType<PlayerStatsUI>()?.UpdateStatTexts(); FindObjectOfType<PlayerStatsUI>()?.UpdateStatTexts();
} }
@ -79,9 +62,7 @@ public class PlayerInteraction : MonoBehaviour
if (playerStats != null) if (playerStats != null)
{ {
playerStats.weaponDamage = 0; playerStats.weaponDamage = 0;
playerStats.ResetWeight(); // ✨ [제거] ResetWeight 호출 삭제
// ⭐ 무기 제거 즉시 UI 갱신
FindObjectOfType<PlayerStatsUI>()?.UpdateStatTexts(); FindObjectOfType<PlayerStatsUI>()?.UpdateStatTexts();
} }
} }

View File

@ -32,56 +32,31 @@ public class PlayerLevelSystem : MonoBehaviour
} }
} }
private void OnEnable() private void OnEnable() { MonsterClass.OnMonsterKilled += GainExp; UpdateExpUI(); }
{ private void OnDisable() { MonsterClass.OnMonsterKilled -= GainExp; }
MonsterClass.OnMonsterKilled += GainExp;
UpdateExpUI();
}
private void OnDisable()
{
MonsterClass.OnMonsterKilled -= GainExp;
}
void GainExp(int amount) void GainExp(int amount)
{ {
currentExp += amount; currentExp += amount;
while (currentExp >= RequiredExp) while (currentExp >= RequiredExp) { currentExp -= RequiredExp; LevelUp(); }
{
currentExp -= RequiredExp;
LevelUp();
}
UpdateExpUI(); UpdateExpUI();
} }
void LevelUp() void LevelUp()
{ {
if (level >= expTable.Length + 1) { currentExp = 0; return; } if (level >= expTable.Length + 1) { currentExp = 0; return; }
level++; level++;
Debug.Log($"🎉 [LevelSystem] 레벨 업! 현재 레벨: {level}");
// 1. 기초 스탯 먼저 상승 (체력 +1000, 힘 +100 - 유저님 설정값) // ✨ 힘 대신 공격력(+10) 증가
if (stats != null) stats.AddBaseLevelUpStats(1000f, 100f); if (stats != null) stats.AddBaseLevelUpStats(1000f, 10f);
// 2. ⭐ [핵심] 늘어난 스탯으로 피 채우고 UI 즉시 갱신 함수 호출 if (pHealth != null) pHealth.RefreshHealthUI();
if (pHealth != null)
{
pHealth.RefreshHealthUI();
}
else
{
Debug.LogError("[LevelSystem] pHealth 참조가 비어있습니다! 인스펙터에 PlayerHealth를 드래그해서 넣어주세요.");
}
// 3. 1.5초 대기 후 카드 선택 UI 팝업
StartCoroutine(DelayedCardPopup()); StartCoroutine(DelayedCardPopup());
} }
private IEnumerator DelayedCardPopup() private IEnumerator DelayedCardPopup()
{ {
yield return new WaitForSeconds(1.5f); yield return new WaitForSeconds(1.5f);
Debug.Log("1.5초 경과: 카드 UI 팝업 실행");
OnLevelUp?.Invoke(); OnLevelUp?.Invoke();
} }

View File

@ -1,63 +1,56 @@
using System.Collections; using UnityEngine;
using System.Collections.Generic;
using UnityEngine;
public class Stats : MonoBehaviour public class Stats : MonoBehaviour
{ {
[Header("--- 기본 능력치 ---")] [Header("--- 기본 능력치 ---")]
[SerializeField] private float baseMaxHealth = 100f; [SerializeField] private float baseMaxHealth = 100f;
[SerializeField] private float baseMoveSpeed = 5f; [SerializeField] private float baseMoveSpeed = 5f;
[SerializeField] private float baseStrength = 10f;
[SerializeField] private float baseAttackDamage = 10f; [SerializeField] private float baseAttackDamage = 10f;
[Header("--- 보너스 능력치 ---")] [Header("--- 보너스 능력치 ---")]
public float bonusMaxHealth; public float bonusMaxHealth;
public float bonusMoveSpeed; public float bonusMoveSpeed;
public float bonusStrength;
public float bonusAttackDamage; public float bonusAttackDamage;
[Header("--- 장착 장비 ---")] [Header("--- 장착 장비 ---")]
public float weaponDamage; // ⭐ 추가: 무기의 순수 공격력 public float weaponDamage;
[Header("--- 밸런스 설정 ---")] [Header("--- 밸런스 설정 ---")]
[SerializeField] private float weightToSpeedPenalty = 0.1f;
[SerializeField] private float runSpeedMultiplier = 1.5f; [SerializeField] private float runSpeedMultiplier = 1.5f;
private float _weightPenalty = 0f;
// ⭐ [추가] 현재 적용 중인 무게 페널티 수치를 외부(UI)에 공개합니다.
public float WeightPenalty => _weightPenalty;
/* ========================= /* =========================
* *
* ========================= */ * ========================= */
public float MaxHealth => baseMaxHealth + bonusMaxHealth; public float MaxHealth => baseMaxHealth + bonusMaxHealth;
public float Strength => baseStrength + bonusStrength;
public float BaseAttackDamage => baseAttackDamage + bonusAttackDamage; public float BaseAttackDamage => baseAttackDamage + bonusAttackDamage;
public float TotalAttackDamage => BaseAttackDamage + weaponDamage; public float TotalAttackDamage => BaseAttackDamage + weaponDamage;
public float CurrentMoveSpeed => Mathf.Max(1f, baseMoveSpeed + bonusMoveSpeed - _weightPenalty); // ✨ [수정] 이제 무게 페널티 없이 순수 속도만 계산합니다.
public float CurrentMoveSpeed => baseMoveSpeed + bonusMoveSpeed;
public float CurrentRunSpeed => CurrentMoveSpeed * runSpeedMultiplier; public float CurrentRunSpeed => CurrentMoveSpeed * runSpeedMultiplier;
private void Update() private void Update()
{ {
finalMaxHealth = MaxHealth; finalMaxHealth = MaxHealth;
finalMoveSpeed = CurrentMoveSpeed; finalMoveSpeed = CurrentMoveSpeed;
finalStrength = Strength;
finalAttackDamage = TotalAttackDamage; finalAttackDamage = TotalAttackDamage;
} }
public void AddBaseLevelUpStats(float hpAdd, float strAdd) { baseMaxHealth += hpAdd; baseStrength += strAdd; } // ✨ [수정] 레벨업 시 체력과 공격력을 올려주도록 변경
public void AddBaseLevelUpStats(float hpAdd, float dmgAdd)
{
baseMaxHealth += hpAdd;
baseAttackDamage += dmgAdd;
}
public void AddMaxHealth(float value) => bonusMaxHealth += value; public void AddMaxHealth(float value) => bonusMaxHealth += value;
public void AddMoveSpeed(float value) => bonusMoveSpeed += value; public void AddMoveSpeed(float value) => bonusMoveSpeed += value;
public void AddStrength(float value) => bonusStrength += value;
public void AddAttackDamage(float value) => bonusAttackDamage += value; public void AddAttackDamage(float value) => bonusAttackDamage += value;
public void UpdateWeaponWeight(float requiredStrength) => _weightPenalty = requiredStrength * weightToSpeedPenalty; // ✨ [제거] 무게 및 힘 관련 함수들(UpdateWeaponWeight, ResetWeight)이 삭제되었습니다.
public void ResetWeight() => _weightPenalty = 0f;
[Header("--- 최종 능력치 (Read Only) ---")] [Header("--- 최종 능력치 (Read Only) ---")]
[SerializeField] private float finalMaxHealth; [SerializeField] private float finalMaxHealth;
[SerializeField] private float finalMoveSpeed; [SerializeField] private float finalMoveSpeed;
[SerializeField] private float finalStrength;
[SerializeField] private float finalAttackDamage; [SerializeField] private float finalAttackDamage;
} }

View File

@ -24,7 +24,7 @@ public class RandomStatCardData : CardData
{ {
case StatType.Health: stats.AddMaxHealth(value); break; case StatType.Health: stats.AddMaxHealth(value); break;
case StatType.Speed: stats.AddMoveSpeed(value); break; case StatType.Speed: stats.AddMoveSpeed(value); break;
case StatType.Strength: stats.AddStrength(value); break; // case StatType.Strength: stats.AddStrength(value); break;
case StatType.Damage: stats.AddAttackDamage(value); break; case StatType.Damage: stats.AddAttackDamage(value); break;
} }
} }

View File

@ -11,7 +11,7 @@ public class PlayerStatsUI : MonoBehaviour
[Header("--- 텍스트 UI ---")] [Header("--- 텍스트 UI ---")]
[SerializeField] private TextMeshProUGUI maxHealthText; [SerializeField] private TextMeshProUGUI maxHealthText;
[SerializeField] private TextMeshProUGUI strengthText; // [제거] strengthText 변수는 인스펙터에서 비워두거나 삭제하세요.
[SerializeField] private TextMeshProUGUI damageText; [SerializeField] private TextMeshProUGUI damageText;
[SerializeField] private TextMeshProUGUI speedText; [SerializeField] private TextMeshProUGUI speedText;
@ -33,14 +33,11 @@ public class PlayerStatsUI : MonoBehaviour
if (playerStats == null) return; if (playerStats == null) return;
maxHealthText.text = $"MaxHP: {playerStats.MaxHealth}"; maxHealthText.text = $"MaxHP: {playerStats.MaxHealth}";
strengthText.text = $"Strength: {playerStats.Strength}"; // ✨ [수정] 힘 텍스트 업데이트 로직 삭제
// ⭐ 데미지: 최종합 (+무기보너스)
damageText.text = $"Damage: {playerStats.TotalAttackDamage} (+{playerStats.weaponDamage})"; damageText.text = $"Damage: {playerStats.TotalAttackDamage} (+{playerStats.weaponDamage})";
// ⭐ [수정] 스피드: 현재속도 (-무게페널티) 형태로 표기합니다. // ✨ [수정] 무게 페널티 없이 현재 속도만 깔끔하게 표기
// 페널티가 0보다 클 때만 빨간색 느낌으로 괄호 수치를 띄워줍니다. speedText.text = $"Speed: {playerStats.CurrentMoveSpeed:F1}";
string penaltyText = playerStats.WeightPenalty > 0 ? $" (-{playerStats.WeightPenalty:F1})" : "";
speedText.text = $"Speed: {playerStats.CurrentMoveSpeed:F1}{penaltyText}";
} }
} }