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 WeaponController _weaponController;
private IPlayerState CurrentStateClass { get; set; }
private IPlayerAction currentAction;
private IPlayerState _currentStateClass { get; set; }
private IPlayerAction _currentAction;
public IPlayerAction CurrentAction => _currentAction;
// 상태 관련
private PlayerStateIdle _playerStateIdle;
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; }
private Dictionary<PlayerState, IPlayerState> _playerStates;
public Animator PlayerAnimator { get; private set; }
@ -38,9 +40,9 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
{
PlayerAnimator = GetComponent<Animator>();
_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 },
};
attackAction = new PlayerActionAttack();
_attackAction = new PlayerActionAttack();
_actionDash = new PlayerActionDash();
PlayerInit();
}
@ -70,20 +73,23 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
_playerStates[CurrentState].Update();
}
// 현재 액션이 활성화 되어 있으면 Update 호출
if (currentAction != null && currentAction.IsActive) {
currentAction.UpdateAction();
// 대시 우선 입력 처리
if (Input.GetKeyDown(KeyCode.Space))
{
StartDashAction();
return;
}
// 공격 입력 처리
if (Input.GetKeyDown(KeyCode.X) && (currentAction == null || !currentAction.IsActive)) {
if (Input.GetKeyDown(KeyCode.X) && (_currentAction == null || !_currentAction.IsActive)) {
StartAttackAction();
}
}
public void StartAttackAction() {
currentAction = attackAction;
currentAction.StartAction(this);
// 액션 업데이트
if (_currentAction != null && _currentAction.IsActive)
{
_currentAction.UpdateAction();
}
}
#region
@ -108,7 +114,9 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
}
#endregion
#region ,
public void SetState(PlayerState state)
{
if (CurrentState != PlayerState.None)
@ -116,10 +124,36 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
_playerStates[CurrentState].Exit();
}
CurrentState = state;
CurrentStateClass = _playerStates[state];
CurrentStateClass.Enter(this);
_currentStateClass = _playerStates[state];
_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()
{
_isBattle = !_isBattle;
@ -130,19 +164,39 @@ public class PlayerController : CharacterBase, IObserver<GameObject>
public void SetAttackComboTrue() {
if (_weaponController.IsAttacking) return; // 이미 공격 중이면 실행 안함
if (currentAction == attackAction) {
attackAction.EnableCombo();
if (_currentAction == _attackAction) {
_attackAction.EnableCombo();
_weaponController.AttackStart();
}
}
public void SetAttackComboFalse() {
if (currentAction == attackAction) {
attackAction.DisableCombo();
if (_currentAction == _attackAction) {
_attackAction.DisableCombo();
_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
public void OnNext(GameObject value)

View File

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

View File

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

View File

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