From f60a22aa264f013804702ba11926d75d459d44d0 Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 25 Apr 2025 10:33:28 +0900 Subject: [PATCH 1/5] =?UTF-8?q?DEG-108=20[Feat]=20=EB=8D=98=EC=A0=84=20?= =?UTF-8?q?=EC=B2=B4=EB=A0=A5=20UI=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/JAY/Scripts/WeaponController.cs | 8 ++++-- Assets/KSH/DungeonLogic.cs | 35 ++++++++++++++++------- Assets/KSH/DungeonPanelController.cs | 31 ++++++++++++++++++++ Assets/KSH/DungeonPanelController.cs.meta | 11 +++++++ Assets/KSH/DungeonTestScene.unity | 4 +-- Assets/Scripts/Character/CharacterBase.cs | 8 ++++-- 6 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 Assets/KSH/DungeonPanelController.cs create mode 100644 Assets/KSH/DungeonPanelController.cs.meta diff --git a/Assets/JAY/Scripts/WeaponController.cs b/Assets/JAY/Scripts/WeaponController.cs index 199dbe04..e5dea921 100644 --- a/Assets/JAY/Scripts/WeaponController.cs +++ b/Assets/JAY/Scripts/WeaponController.cs @@ -49,7 +49,11 @@ public class WeaponController : MonoBehaviour, IObservable _playerController = GetComponent(); if (_playerController == null) { - _playerController = GameObject.FindGameObjectWithTag("Player").GetComponent(); + var player = GameObject.FindGameObjectWithTag("Player"); + if (player != null) + { + _playerController = player.GetComponent(); + } } _previousPositions = new Vector3[_triggerZones.Length]; @@ -106,7 +110,7 @@ public class WeaponController : MonoBehaviour, IObservable if (hit.collider.gameObject.CompareTag("Enemy")) { var enemyController = hit.transform.GetComponent(); - if (enemyController != null) + if (enemyController != null && _playerController != null) { enemyController.TakeDamage(AttackPower * _playerController.attackPower); } diff --git a/Assets/KSH/DungeonLogic.cs b/Assets/KSH/DungeonLogic.cs index 3a8bccc6..834eec9e 100644 --- a/Assets/KSH/DungeonLogic.cs +++ b/Assets/KSH/DungeonLogic.cs @@ -5,6 +5,8 @@ using UnityEngine; public class DungeonLogic : MonoBehaviour { + [SerializeField] private DungeonPanelController _dungeonPanelController; + [NonSerialized] public bool isCompleted = false; // 던전 클리어 여부 [NonSerialized] public bool isFailed = false; // 던전 실패 여부 @@ -24,19 +26,35 @@ public class DungeonLogic : MonoBehaviour // 죽음 이벤트 구독 if (_player != null) { + _player.OnGetHit += OnPlayerGetHit; _player.OnDeath += OnPlayerDeath; } if (_enemy != null) { + _enemy.OnGetHit += OnEnemyGetHit; _enemy.OnDeath += OnEnemyDeath; } } - // 플레이어 사망 처리 - private void OnPlayerDeath(CharacterBase player) + private void OnPlayerGetHit(CharacterBase player) + { + var result = _dungeonPanelController.SetPlayerHealth(); + if (!result) // 하트 모두 소모 + { + player.Die(); + } + } + + private void OnEnemyGetHit(CharacterBase enemy) + { + Debug.Log("Enemy HP: " + enemy.currentHP); + _dungeonPanelController.SetBossHealthBar(enemy.currentHP); + } + + // 플레이어 사망 처리 + private void OnPlayerDeath() { - Debug.Log("player name:" + player.characterName); if (!isFailed) // 중복 실행 방지 { FailDungeon(); @@ -44,9 +62,8 @@ public class DungeonLogic : MonoBehaviour } // 적 사망 처리 - private void OnEnemyDeath(CharacterBase enemy) + private void OnEnemyDeath() { - Debug.Log("enemy name:" + enemy.characterName); if (!isCompleted) // 중복 실행 방지 { CompleteDungeon(); @@ -62,7 +79,7 @@ public class DungeonLogic : MonoBehaviour isCompleted = true; OnDungeonSuccess?.Invoke(); - // 성공 UI 표시 ?? 강화 표기 + _player.SetState(PlayerState.Win); // TODO: 강화 시스템으로 넘어가고 일상 맵으로 이동 } } @@ -76,10 +93,8 @@ public class DungeonLogic : MonoBehaviour isFailed = true; OnDungeonFailure?.Invoke(); - // 죽음 애니메이션 + 실패 UI 표시 ? - // GameManager.Instance.ChangeToHomeScene(); - - StartCoroutine(DelayedSceneChange()); // 테스트를 위해 3초 대기 후 전환 + _player.SetState(PlayerState.Dead); + StartCoroutine(DelayedSceneChange()); // 3초 대기 후 전환 } } diff --git a/Assets/KSH/DungeonPanelController.cs b/Assets/KSH/DungeonPanelController.cs new file mode 100644 index 00000000..800e4690 --- /dev/null +++ b/Assets/KSH/DungeonPanelController.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +public class DungeonPanelController : MonoBehaviour +{ + [SerializeField] private Slider _bossHealthBar; // 0~1 value + [SerializeField] private Image[] _playerHealthImages; // color 값 white / black 로 조정 + private int _countHealth = 0; + + public void SetBossHealthBar(float hp) // hp: 0~100 + { + float normalizedHp = hp / 100f; // 0~1 사이 값으로 조정 + _bossHealthBar.value = normalizedHp; + } + + // false 반환 시 사망 처리 + public bool SetPlayerHealth() + { + if (_countHealth > _playerHealthImages.Length - 1) // out of index error 방지 + { + return false; + } + + _playerHealthImages[_countHealth].color = Color.black; + _countHealth++; + return _countHealth <= _playerHealthImages.Length - 1; + } +} diff --git a/Assets/KSH/DungeonPanelController.cs.meta b/Assets/KSH/DungeonPanelController.cs.meta new file mode 100644 index 00000000..5f53a9f2 --- /dev/null +++ b/Assets/KSH/DungeonPanelController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75caf6a3958eb0745a00749003e12d73 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/KSH/DungeonTestScene.unity b/Assets/KSH/DungeonTestScene.unity index b8ce1c3e..ecfbe121 100644 --- a/Assets/KSH/DungeonTestScene.unity +++ b/Assets/KSH/DungeonTestScene.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a3f988deb686f35d4ca0aeb90dcf4d726ccff34a27d1b5f0e020b0ceeb008606 -size 185731 +oid sha256:ee7536d36b114bd9488ea8f43600194c288f7bb6a77bbb0ba1247b8486a6dd78 +size 236615 diff --git a/Assets/Scripts/Character/CharacterBase.cs b/Assets/Scripts/Character/CharacterBase.cs index 4a35b463..fdf5a623 100644 --- a/Assets/Scripts/Character/CharacterBase.cs +++ b/Assets/Scripts/Character/CharacterBase.cs @@ -1,3 +1,4 @@ +using System; using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -17,7 +18,8 @@ public abstract class CharacterBase : MonoBehaviour [Header("상태 이상")] public List statusEffects = new List(); - public event System.Action OnDeath; // 사망 이벤트 + public event Action OnDeath; // 사망 이벤트 + public event Action OnGetHit; // 피격 이벤트 protected virtual void Start() { @@ -34,13 +36,15 @@ public abstract class CharacterBase : MonoBehaviour { Die(); } + + OnGetHit?.Invoke(this); } public virtual void Die() { Debug.Log($"{characterName}이 사망했습니다."); // TODO: 사망 처리 - OnDeath?.Invoke(this); + OnDeath?.Invoke(); } // 상태이상 추가 메서드 From 7539b84a1f58a3232102c39a67fa08b2c1ccc612 Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 25 Apr 2025 14:52:49 +0900 Subject: [PATCH 2/5] =?UTF-8?q?DEG-108=20[Fix]=20=EC=96=B4=EB=8A=90=20?= =?UTF-8?q?=ED=95=9C=20=EC=AA=BD=20=EC=82=AC=EB=A7=9D=EC=8B=9C=20=EB=8D=94?= =?UTF-8?q?=EC=9D=B4=EC=83=81=20=EA=B3=B5=EA=B2=A9=20=EC=95=88=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/JAY/Scripts/PlayerController.cs | 6 +++++- Assets/JAY/Scripts/WeaponController.cs | 1 - Assets/KSH/DungeonLogic.cs | 12 +++++++++++- Assets/KSH/DungeonPanelController.cs | 7 +++++++ Assets/KSH/DungeonTestScene.unity | 2 +- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/Assets/JAY/Scripts/PlayerController.cs b/Assets/JAY/Scripts/PlayerController.cs index 2c841575..902a4a36 100644 --- a/Assets/JAY/Scripts/PlayerController.cs +++ b/Assets/JAY/Scripts/PlayerController.cs @@ -88,6 +88,7 @@ public class PlayerController : CharacterBase, IObserver // 공격 입력 처리 if (Input.GetKeyDown(KeyCode.X) && (_currentAction == null || !_currentAction.IsActive)) { + Debug.Log("X 버튼 Down 됨"); StartAttackAction(); } @@ -171,6 +172,7 @@ public class PlayerController : CharacterBase, IObserver if (_weaponController.IsAttacking) return; // 이미 공격 중이면 실행 안함 if (_currentAction == _attackAction) { + Debug.Log($"Attack True"); _attackAction.EnableCombo(); _weaponController.AttackStart(); } @@ -178,8 +180,10 @@ public class PlayerController : CharacterBase, IObserver public void SetAttackComboFalse() { if (_currentAction == _attackAction) { + Debug.Log($"Attack False"); + // 이벤트 중복 호출? 공격 종료 시 SetAttackComboFalse가 아니라 ~True로 끝나서 오류 발생. (공격 안하는 상태여도 공격으로 판정됨) _attackAction.DisableCombo(); - _weaponController.AttackEnd(); + _weaponController.AttackEnd(); // IsAttacking = false로 변경 } } diff --git a/Assets/JAY/Scripts/WeaponController.cs b/Assets/JAY/Scripts/WeaponController.cs index e5dea921..e8803f2f 100644 --- a/Assets/JAY/Scripts/WeaponController.cs +++ b/Assets/JAY/Scripts/WeaponController.cs @@ -106,7 +106,6 @@ public class WeaponController : MonoBehaviour, IObservable { _hitColliders.Add(hit.collider); - Debug.Log("hit.collider.name: " + hit.collider.name); if (hit.collider.gameObject.CompareTag("Enemy")) { var enemyController = hit.transform.GetComponent(); diff --git a/Assets/KSH/DungeonLogic.cs b/Assets/KSH/DungeonLogic.cs index 834eec9e..a1db7b27 100644 --- a/Assets/KSH/DungeonLogic.cs +++ b/Assets/KSH/DungeonLogic.cs @@ -39,6 +39,8 @@ public class DungeonLogic : MonoBehaviour private void OnPlayerGetHit(CharacterBase player) { + if (isFailed || isCompleted) return; // 어느 한 쪽 사망시 더이상 피격 X + var result = _dungeonPanelController.SetPlayerHealth(); if (!result) // 하트 모두 소모 { @@ -48,7 +50,8 @@ public class DungeonLogic : MonoBehaviour private void OnEnemyGetHit(CharacterBase enemy) { - Debug.Log("Enemy HP: " + enemy.currentHP); + if (isFailed || isCompleted) return; + _dungeonPanelController.SetBossHealthBar(enemy.currentHP); } @@ -78,6 +81,8 @@ public class DungeonLogic : MonoBehaviour Debug.Log("던전 공략 성공~!"); isCompleted = true; OnDungeonSuccess?.Invoke(); + + _dungeonPanelController.SetBossHealthBar(0.0f); // 보스 체력 0 재설정 _player.SetState(PlayerState.Win); // TODO: 강화 시스템으로 넘어가고 일상 맵으로 이동 @@ -94,6 +99,11 @@ public class DungeonLogic : MonoBehaviour OnDungeonFailure?.Invoke(); _player.SetState(PlayerState.Dead); + + // enemy가 더이상 Trace 하지 않도록 처리 + _player.gameObject.layer = LayerMask.NameToLayer("Ignore Raycast"); + _enemy.SetState(EnemyState.Idle); + StartCoroutine(DelayedSceneChange()); // 3초 대기 후 전환 } } diff --git a/Assets/KSH/DungeonPanelController.cs b/Assets/KSH/DungeonPanelController.cs index 800e4690..6614ec03 100644 --- a/Assets/KSH/DungeonPanelController.cs +++ b/Assets/KSH/DungeonPanelController.cs @@ -19,6 +19,8 @@ public class DungeonPanelController : MonoBehaviour // false 반환 시 사망 처리 public bool SetPlayerHealth() { + StartCoroutine(WaitForOneSecond()); + if (_countHealth > _playerHealthImages.Length - 1) // out of index error 방지 { return false; @@ -28,4 +30,9 @@ public class DungeonPanelController : MonoBehaviour _countHealth++; return _countHealth <= _playerHealthImages.Length - 1; } + + IEnumerator WaitForOneSecond() + { + yield return new WaitForSeconds(1.0f); + } } diff --git a/Assets/KSH/DungeonTestScene.unity b/Assets/KSH/DungeonTestScene.unity index ecfbe121..5c48dbf7 100644 --- a/Assets/KSH/DungeonTestScene.unity +++ b/Assets/KSH/DungeonTestScene.unity @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee7536d36b114bd9488ea8f43600194c288f7bb6a77bbb0ba1247b8486a6dd78 +oid sha256:7b994f0db1a78d57442ff714bbde098d085ed1ac985def8e2890bcee787c2d72 size 236615 From 59625fa8ff8463514c7f762cf29ad1236712cdca Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 25 Apr 2025 15:48:11 +0900 Subject: [PATCH 3/5] =?UTF-8?q?DEG-108=20[Fix]=20OnNext=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EA=B3=B5=EA=B2=A9=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/JAY/Scripts/PlayerController.cs | 12 ++++++++++++ Assets/JAY/Scripts/WeaponController.cs | 10 ---------- Assets/KSH/DungeonPanelController.cs | 7 ++----- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Assets/JAY/Scripts/PlayerController.cs b/Assets/JAY/Scripts/PlayerController.cs index 902a4a36..0dd9e277 100644 --- a/Assets/JAY/Scripts/PlayerController.cs +++ b/Assets/JAY/Scripts/PlayerController.cs @@ -70,6 +70,8 @@ public class PlayerController : CharacterBase, IObserver _actionDash = new PlayerActionDash(); PlayerInit(); + + SwitchBattleMode(); } private void Update() @@ -211,6 +213,16 @@ public class PlayerController : CharacterBase, IObserver public void OnNext(GameObject value) { + float playerAttackPower = _weaponController.AttackPower * attackPower; + + if (value.CompareTag("Enemy")) // 적이 Enemy일 때만 공격 처리 + { + var enemyController = value.transform.GetComponent(); + if (enemyController != null) + { + enemyController.TakeDamage(playerAttackPower); + } + } } public void OnError(Exception error) diff --git a/Assets/JAY/Scripts/WeaponController.cs b/Assets/JAY/Scripts/WeaponController.cs index e8803f2f..6a86b8d6 100644 --- a/Assets/JAY/Scripts/WeaponController.cs +++ b/Assets/JAY/Scripts/WeaponController.cs @@ -105,16 +105,6 @@ public class WeaponController : MonoBehaviour, IObservable if (!_hitColliders.Contains(hit.collider)) { _hitColliders.Add(hit.collider); - - if (hit.collider.gameObject.CompareTag("Enemy")) - { - var enemyController = hit.transform.GetComponent(); - if (enemyController != null && _playerController != null) - { - enemyController.TakeDamage(AttackPower * _playerController.attackPower); - } - } - Notify(hit.collider.gameObject); } } diff --git a/Assets/KSH/DungeonPanelController.cs b/Assets/KSH/DungeonPanelController.cs index 6614ec03..952bad9e 100644 --- a/Assets/KSH/DungeonPanelController.cs +++ b/Assets/KSH/DungeonPanelController.cs @@ -20,11 +20,8 @@ public class DungeonPanelController : MonoBehaviour public bool SetPlayerHealth() { StartCoroutine(WaitForOneSecond()); - - if (_countHealth > _playerHealthImages.Length - 1) // out of index error 방지 - { - return false; - } + // out of index error 방지 + if (_countHealth > _playerHealthImages.Length - 1) return false; _playerHealthImages[_countHealth].color = Color.black; _countHealth++; From d3948bc577ea3fdff7306f130490b67096ea09a7 Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 25 Apr 2025 15:59:57 +0900 Subject: [PATCH 4/5] =?UTF-8?q?DEG-108=20[Fix]=20=EA=B3=B5=EA=B2=A9=20?= =?UTF-8?q?=EC=A0=9C=ED=95=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/JAY/Scripts/PlayerController.cs | 3 ++- Assets/KSH/DungeonLogic.cs | 4 ++++ Assets/Scripts/Character/CharacterBase.cs | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Assets/JAY/Scripts/PlayerController.cs b/Assets/JAY/Scripts/PlayerController.cs index 0dd9e277..ca3fceb2 100644 --- a/Assets/JAY/Scripts/PlayerController.cs +++ b/Assets/JAY/Scripts/PlayerController.cs @@ -89,7 +89,8 @@ public class PlayerController : CharacterBase, IObserver } // 공격 입력 처리 - if (Input.GetKeyDown(KeyCode.X) && (_currentAction == null || !_currentAction.IsActive)) { + if (Input.GetKeyDown(KeyCode.X) && (_currentAction == null || !_currentAction.IsActive) + && (CurrentState != PlayerState.Win && CurrentState != PlayerState.Dead)) { Debug.Log("X 버튼 Down 됨"); StartAttackAction(); } diff --git a/Assets/KSH/DungeonLogic.cs b/Assets/KSH/DungeonLogic.cs index a1db7b27..e5b66d8f 100644 --- a/Assets/KSH/DungeonLogic.cs +++ b/Assets/KSH/DungeonLogic.cs @@ -41,6 +41,8 @@ public class DungeonLogic : MonoBehaviour { if (isFailed || isCompleted) return; // 어느 한 쪽 사망시 더이상 피격 X + // TODO: 플레이어 피격 효과음 + var result = _dungeonPanelController.SetPlayerHealth(); if (!result) // 하트 모두 소모 { @@ -52,6 +54,8 @@ public class DungeonLogic : MonoBehaviour { if (isFailed || isCompleted) return; + // TODO: 에너미 피격 효과음 + _dungeonPanelController.SetBossHealthBar(enemy.currentHP); } diff --git a/Assets/Scripts/Character/CharacterBase.cs b/Assets/Scripts/Character/CharacterBase.cs index fdf5a623..b0f4e2ea 100644 --- a/Assets/Scripts/Character/CharacterBase.cs +++ b/Assets/Scripts/Character/CharacterBase.cs @@ -28,6 +28,8 @@ public abstract class CharacterBase : MonoBehaviour public virtual void TakeDamage(float damage) { + if (currentHP <= 0) return; + float actualDamage = Mathf.Max(0, damage - defensePower); currentHP -= Mathf.RoundToInt(actualDamage); Debug.Log($"{characterName}이 {actualDamage}의 피해를 입었습니다. 현재 체력: {currentHP}"); @@ -35,6 +37,7 @@ public abstract class CharacterBase : MonoBehaviour if (currentHP <= 0) { Die(); + return; } OnGetHit?.Invoke(this); From fe79e0d3ae27782f1b6a5789052070c50e2ba2a6 Mon Sep 17 00:00:00 2001 From: Sehyeon Date: Fri, 25 Apr 2025 16:48:16 +0900 Subject: [PATCH 5/5] =?UTF-8?q?DEG-108=20[Fix]=20=EC=9E=90=EB=8F=99=20?= =?UTF-8?q?=EA=B3=B5=EA=B2=A9=20=EC=A4=91=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/JAY/Scripts/WeaponController.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Assets/JAY/Scripts/WeaponController.cs b/Assets/JAY/Scripts/WeaponController.cs index 6a86b8d6..10ec8aa5 100644 --- a/Assets/JAY/Scripts/WeaponController.cs +++ b/Assets/JAY/Scripts/WeaponController.cs @@ -69,12 +69,26 @@ public class WeaponController : MonoBehaviour, IObservable } _isAttacking = true; _hitColliders.Clear(); + + StopAllCoroutines(); + StartCoroutine(AutoEndAttack()); // 자동 공격 종료 for (int i = 0; i < _triggerZones.Length; i++) { _previousPositions[i] = transform.position + transform.TransformVector(_triggerZones[i].position); } } + + private IEnumerator AutoEndAttack() + { + yield return new WaitForSeconds(0.6f); // 0.6초 가량 대기 + + if (_isAttacking) // 아직 공격 중이면 + { + Debug.Log("공격 자동 종료 - 타임아웃"); + AttackEnd(); + } + } public void AttackEnd() {