DEG-94 [FEAT] 회피 행동 추가

This commit is contained in:
Jay 2025-04-24 14:27:46 +09:00
parent 9f7a29e7d5
commit b378d51f73
7 changed files with 142 additions and 31 deletions

BIN
Assets/JAY/Animation/Attack04.anim (Stored with Git LFS)

Binary file not shown.

View File

@ -0,0 +1,53 @@
using UnityEngine;
public class PlayerActionDash : IPlayerAction
{
private PlayerController player;
private float duration = 0.25f;
private float timer;
private Vector3 direction;
private float dashSpeedMultiplier = 3f; // 기본 이동 속도의 n배
private float dashSpeed;
public bool IsActive { get; private set; }
public void StartAction(PlayerController player)
{
this.player = player;
IsActive = true;
timer = 0f;
direction = player.GetMoveDirectionOrForward().normalized;
dashSpeed = player.moveSpeed * dashSpeedMultiplier;
// player.PlayerAnimator.SetTrigger("Roll");
}
public void UpdateAction()
{
if (!IsActive) return;
DoDash();
}
private void DoDash()
{
timer += Time.deltaTime;
if (timer < duration)
{
player.CharacterController.Move(direction * dashSpeed * Time.deltaTime);
}
else
{
EndAction();
}
}
public void EndAction()
{
IsActive = false;
player = null;
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: eceb0c738c2c4690b8b4dd02e10c7df4
timeCreated: 1745459840

View File

@ -17,18 +17,20 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
private GameObject weapon; private GameObject weapon;
private WeaponController _weaponController; private WeaponController _weaponController;
private IPlayerState CurrentStateClass { get; set; } private IPlayerState _currentStateClass { get; set; }
private IPlayerAction currentAction; private IPlayerAction _currentAction;
public IPlayerAction CurrentAction => _currentAction;
// 상태 관련 // 상태 관련
private PlayerStateIdle _playerStateIdle; private PlayerStateIdle _playerStateIdle;
private PlayerStateMove _playerStateMove; private PlayerStateMove _playerStateMove;
// 행동 관련 // 행동 관련
private PlayerActionAttack attackAction; private PlayerActionAttack _attackAction;
private PlayerActionDash _actionDash;
// 외부에서도 사용하는 변수 // 외부에서도 사용하는 변수
public FixedJoystick joystick { get; private set; } public FixedJoystick Joystick { get; private set; }
public PlayerState CurrentState { get; private set; } public PlayerState CurrentState { get; private set; }
private Dictionary<PlayerState, IPlayerState> _playerStates; private Dictionary<PlayerState, IPlayerState> _playerStates;
public Animator PlayerAnimator { get; private set; } public Animator PlayerAnimator { get; private set; }
@ -38,9 +40,9 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
{ {
PlayerAnimator = GetComponent<Animator>(); PlayerAnimator = GetComponent<Animator>();
_characterController = GetComponent<CharacterController>(); _characterController = GetComponent<CharacterController>();
if (joystick == null) if (Joystick == null)
{ {
joystick = FindObjectOfType<FixedJoystick>(); Joystick = FindObjectOfType<FixedJoystick>();
} }
} }
@ -58,7 +60,8 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
{ PlayerState.Move, _playerStateMove }, { PlayerState.Move, _playerStateMove },
}; };
attackAction = new PlayerActionAttack(); _attackAction = new PlayerActionAttack();
_actionDash = new PlayerActionDash();
PlayerInit(); PlayerInit();
} }
@ -70,20 +73,23 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
_playerStates[CurrentState].Update(); _playerStates[CurrentState].Update();
} }
// 현재 액션이 활성화 되어 있으면 Update 호출 // 대시 우선 입력 처리
if (currentAction != null && currentAction.IsActive) { if (Input.GetKeyDown(KeyCode.Space))
currentAction.UpdateAction(); {
StartDashAction();
return;
} }
// 공격 입력 처리 // 공격 입력 처리
if (Input.GetKeyDown(KeyCode.X) && (currentAction == null || !currentAction.IsActive)) { if (Input.GetKeyDown(KeyCode.X) && (_currentAction == null || !_currentAction.IsActive)) {
StartAttackAction(); StartAttackAction();
} }
}
public void StartAttackAction() { // 액션 업데이트
currentAction = attackAction; if (_currentAction != null && _currentAction.IsActive)
currentAction.StartAction(this); {
_currentAction.UpdateAction();
}
} }
#region #region
@ -109,6 +115,8 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
#endregion #endregion
#region ,
public void SetState(PlayerState state) public void SetState(PlayerState state)
{ {
if (CurrentState != PlayerState.None) if (CurrentState != PlayerState.None)
@ -116,10 +124,36 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
_playerStates[CurrentState].Exit(); _playerStates[CurrentState].Exit();
} }
CurrentState = state; CurrentState = state;
CurrentStateClass = _playerStates[state]; _currentStateClass = _playerStates[state];
CurrentStateClass.Enter(this); _currentStateClass.Enter(this);
} }
public void StartAttackAction() {
_currentAction = _attackAction;
_currentAction.StartAction(this);
}
public void StartDashAction()
{
// 만약 공격 중이면 강제로 공격 종료
if (_currentAction == _attackAction && _attackAction.IsActive)
{
_attackAction.EndAction(); // 애니메이션도 중단
}
// 기존 대시 중이면 중복 실행 안 함
if (_actionDash.IsActive)
return;
_currentAction = _actionDash;
_actionDash.StartAction(this);
}
#endregion
#region
public void SwitchBattleMode() public void SwitchBattleMode()
{ {
_isBattle = !_isBattle; _isBattle = !_isBattle;
@ -130,19 +164,39 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
public void SetAttackComboTrue() { public void SetAttackComboTrue() {
if (_weaponController.IsAttacking) return; // 이미 공격 중이면 실행 안함 if (_weaponController.IsAttacking) return; // 이미 공격 중이면 실행 안함
if (currentAction == attackAction) { if (_currentAction == _attackAction) {
attackAction.EnableCombo(); _attackAction.EnableCombo();
_weaponController.AttackStart(); _weaponController.AttackStart();
} }
} }
public void SetAttackComboFalse() { public void SetAttackComboFalse() {
if (currentAction == attackAction) { if (_currentAction == _attackAction) {
attackAction.DisableCombo(); _attackAction.DisableCombo();
_weaponController.AttackEnd(); _weaponController.AttackEnd();
} }
} }
#endregion
#region
public Vector3 GetMoveDirectionOrForward()
{
Vector3 dir = new Vector3(Joystick.Horizontal, 0, Joystick.Vertical);
return dir.sqrMagnitude > 0.01f ? dir.normalized : transform.forward;
}
public void DashButtonPressed()
{
if (!_actionDash.IsActive)
{
StartDashAction();
}
}
#endregion
#region IObserver #region IObserver
public void OnNext(GameObject value) public void OnNext(GameObject value)

View File

@ -22,6 +22,7 @@ public class PlayerControllerEditor : Editor
EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.BeginVertical(EditorStyles.helpBox);
EditorGUILayout.LabelField("현재 상태", playerController.CurrentState.ToString(), EditorStyles.boldLabel); EditorGUILayout.LabelField("현재 상태", playerController.CurrentState.ToString(), EditorStyles.boldLabel);
EditorGUILayout.LabelField("현재 행동", playerController.CurrentAction != null ? playerController.CurrentAction.ToString() : "-", EditorStyles.boldLabel);
EditorGUILayout.EndVertical(); EditorGUILayout.EndVertical();

View File

@ -11,8 +11,8 @@ public class PlayerStateIdle : IPlayerState
public void Update() public void Update()
{ {
float inputHorizontal = _playerController.joystick.Horizontal; float inputHorizontal = _playerController.Joystick.Horizontal;
float inputVertical = _playerController.joystick.Vertical; float inputVertical = _playerController.Joystick.Vertical;
// 이동 // 이동
if (inputHorizontal != 0 || inputVertical != 0) if (inputHorizontal != 0 || inputVertical != 0)

View File

@ -14,8 +14,8 @@ public class PlayerStateMove : IPlayerState
public void Update() public void Update()
{ {
float inputHorizontal = _playerController.joystick.Horizontal; float inputHorizontal = _playerController.Joystick.Horizontal;
float inputVertical = _playerController.joystick.Vertical; float inputVertical = _playerController.Joystick.Vertical;
// 이동 // 이동
if (inputHorizontal != 0 || inputVertical != 0) if (inputHorizontal != 0 || inputVertical != 0)
@ -36,8 +36,8 @@ public class PlayerStateMove : IPlayerState
private void HandleMovement() private void HandleMovement()
{ {
float inputHorizontal = _playerController.joystick.Horizontal; float inputHorizontal = _playerController.Joystick.Horizontal;
float inputVertical = _playerController.joystick.Vertical; float inputVertical = _playerController.Joystick.Vertical;
Vector3 moveDir = new Vector3(inputHorizontal, 0, inputVertical); Vector3 moveDir = new Vector3(inputHorizontal, 0, inputVertical);
Vector3 move = moveDir.normalized * _playerController.moveSpeed; Vector3 move = moveDir.normalized * _playerController.moveSpeed;