2026-03-20 : 8방향 대시

This commit is contained in:
2026-03-20 02:57:53 +09:00
parent 086034de23
commit 4c0c1b6b41
74 changed files with 10009 additions and 304 deletions

View File

@@ -2,6 +2,7 @@
using System.Threading;
using Unity.Cinemachine;
using Unity.VisualScripting;
using UnityEditor.Experimental.GraphView;
using UnityEditorInternal;
using UnityEngine;
using static Unity.Cinemachine.CinemachineSplineDolly;
@@ -42,8 +43,10 @@ public class PlayerCharacterController : MonoBehaviour
//대쉬
[SerializeField] private AnimationCurve _dodgeCurve; // 변속용 커브
[SerializeField] private float _dodgeDistance = 5f; // 총 대쉬 거리
[SerializeField] private float _dodgeDuration = 0.5f; // 대쉬 지속 시간 (무적시간)
[SerializeField] private float _dodgeDuration = 0.5f; // 대쉬 지속 시간
private float _dodgeTimer = 0f; // 대쉬 진행 측정용
private float _inertiaTimer = 0f; // 관성 타이머
private float _inertiaTime = 0f;
private Vector3 _dodgeDir; // 대쉬 시작 시점의 방향 고정
//카메라 전환
@@ -70,6 +73,7 @@ public enum PlayerRotationMode {CameraCoupled, CameraDecoupled}
//캐릭터 관련
public CharacterIdentity PlayerCharacterIdentity { get; set; }
public PlayerStat PlayerCharacterStat{ get; set; }
private Renderer[] _renderers;
//무기
//[SerializeField] private Weapon _weapon;
@@ -100,6 +104,8 @@ private void Awake()
_stateMachine = GetComponent<PlayerStateMachine>();
PlayerCharacterIdentity = GetComponent<CharacterIdentity>();
PlayerCharacterStat = GetComponent<PlayerStat>();
_renderers = GetComponentsInChildren<Renderer>();
}
private void Start()
@@ -136,6 +142,26 @@ private void PlayerDebug()
#region
private void StateUpdate()
{
if (_stateMachine.CurrentState == PlayerState.Inertia && _inertiaTimer > 0f)
return; // 관성상태면 상태변환 안함
else if(_stateMachine.CurrentState == PlayerState.Inertia && _inertiaTimer <= 0f)
{
_inertiaTime = 0f;
if (_moveInput.sqrMagnitude < Mathf.Epsilon )
{
_stateMachine.ChangeState(PlayerState.Idle);
_currentSpd = 0f;
}
else
{
_stateMachine.ChangeState(_stateMachine.IsRunInputPressed ? PlayerState.Run : PlayerState.Walk);
_currentSpd = _walkSpdRatio * _spdCoefficient;
}
}
if (_stateMachine.CurrentState == PlayerState.Dodge) return;
// 땅에서 추락할때
if (!_stateMachine.IsGrounded && _velocityY.y < 0f && _stateMachine.CurrentState != PlayerState.Attack && _stateMachine.CurrentState != PlayerState.Charge)
{
@@ -207,22 +233,26 @@ private void WorkGravity()
#region
private void Movement()
{
if (_stateMachine.CurrentState == PlayerState.Inertia) return;
//구르기중일때 전용 로직
if (_stateMachine.CurrentState == PlayerState.Dodge)
{
Debug.Log("구르기중");
float normalizedTime = (_dodgeDuration - _dodgeTimer) / _dodgeDuration; // 0 ~ 1 사이의 진행률
if (normalizedTime >= 1f)
{
Debug.Log("구르기 끝남");
// 구르기 종료 -> 원래상태로 복귀 로직
_stateMachine.ChangeState(PlayerState.Idle);
// 구르기 종료 -> 관성 로직
_stateMachine.ChangeState(PlayerState.Inertia);
_moveTargetDir = _moveTargetDir * 0.3f;
_inertiaTimer = _inertiaTime;
return;
}
// 커브에서 현재 시점의 '속도 배율'을 가져옴
// 그래프의 전체 넓이는 1
_anim.GetInteger("DodgeAnimType");
float curveValue = _dodgeCurve.Evaluate(normalizedTime);
// 최종 속도 = (전체 거리 / 시간) * 커브 배율 ??
@@ -336,21 +366,16 @@ public void RecenterPlayer(float damping = 0)
#region
private void OnAnimatorMove()
{
// 애니메이션이 가고 싶은 값
/*
if(StateMachine.CurrentState == PlayerState.Roll)
if(_stateMachine.CurrentState == PlayerState.Dodge)
{
_rootMotionVelocity = _anim.deltaPosition / Time.deltaTime;
}
*/
}
private void ApplyMove()
{
//지상이동이 가능한 상황이 아니고, 공중이동도 가능한 상황이 아니라면, 또한 대쉬중도 아니라면
if (!_stateMachine.CanMove() && !_stateMachine.CanControlInAir() && !_stateMachine.CanDodge())
//지상에서 지상이동이 가능한 상황이 아니고, 공중에서 공중이동도 가능한 상황이 아니라면, 또한 대쉬중도 아니라면, 관성 상태도 아니라면
if (!_stateMachine.CanMove() && !_stateMachine.CanControlInAir() && _stateMachine.CurrentState != PlayerState.Dodge && _stateMachine.CurrentState != PlayerState.Inertia)
{
Debug.Log("aaaaaaaaaaaaaaaa");
_moveTargetDir.x = 0f;
_moveTargetDir.z = 0f;
}
@@ -376,6 +401,7 @@ private void TickTimer()
if (_jumpReadyCoolTimer > 0) _jumpReadyCoolTimer -= Time.deltaTime; if (_jumpReadyCoolTimer < 0) _jumpReadyCoolTimer = 0f;
if (_moveCutTimer > 0) _moveCutTimer -= Time.deltaTime; if (_moveCutTimer < 0) _moveCutTimer = 0f;
if(_dodgeTimer > 0) _dodgeTimer -= Time.deltaTime; ; if (_dodgeTimer < 0) _dodgeTimer = 0f;
if (_inertiaTimer > 0) _inertiaTimer -= Time.deltaTime;if (_inertiaTimer < 0) _inertiaTimer = 0f;
}
#endregion
@@ -435,33 +461,35 @@ public void DodgeInput(InputState inputState)
}
else if(angle >= 22.5f && angle < 67.5f)
{
dodgeAnimType = 0; //우상 : Fwd 애니메이션
dodgeAnimType = 1; //우상 : Fwd 애니메이션
}
else if(angle >= 67.5f && angle < 112.5f)
{
dodgeAnimType = 1; //우 : Right 애니메이션
dodgeAnimType = 2; //우 : Right 애니메이션
}
else if (angle >= 112.5f && angle < 157.5f)
{
dodgeAnimType = 1; //우하 : Right 애니메이션
dodgeAnimType = 3; //우하 : Right 애니메이션
}
else if(angle >= 157.5f && angle < 202.5f)
{
dodgeAnimType = 2; //하 : Back 애니메이션
dodgeAnimType = 4; //하 : Back 애니메이션
}
else if (angle >= 202.5f && angle < 247.5f)
{
dodgeAnimType = 3; //좌하 : Left 애니메이션
dodgeAnimType = 5; //좌하 : Left 애니메이션
}
else if(angle >= 247.5f && angle < 292.5f)
{
dodgeAnimType = 3; //좌 : Left 애니메이션
dodgeAnimType = 6; //좌 : Left 애니메이션
}
else if(angle >= 292.5f && angle < 337.5f)
{
dodgeAnimType = 0; //좌상 : Fwd 애니메이션
dodgeAnimType = 7; //좌상 : Fwd 애니메이션
}
_inertiaTime = 0.5f;
//각도 따라 다른 애니메이션 재생
_anim.SetInteger("DodgeAnimType", dodgeAnimType);
_anim.SetTrigger("DodgeTrigger");
@@ -494,6 +522,39 @@ public void LookInput(Vector2 lookInput)
}
#endregion
#region
public void HideCharacter(int flag)
{
if (flag == 0)
{
foreach(Renderer rd in _renderers)
{
foreach(Material m in rd.materials)
{
if(m.HasProperty("_DissolvePower"))
m.SetFloat("_DissolvePower", 0);
}
}
}
else if (flag == 1)
{
foreach (Renderer rd in _renderers)
{
foreach (Material m in rd.materials)
{
if (m.HasProperty("_DissolvePower"))
m.SetFloat("_DissolvePower", 1);
}
}
}
}
public void HideCharacterTrueDelay(float delay)
{
_ = Util.RunDelayed(delay, ()=>HideCharacter(1), default);
}
#endregion
#region
public void SetCursorLockState(bool isLocked)
{

View File

@@ -1 +1 @@
public enum PlayerState { Idle, Walk, Run, Dodge, Jump, Fall, Attack, Charge, Hit, Dead, None }
public enum PlayerState { Idle, Walk, Run, Dodge, Jump, Fall, Attack, Charge, Hit, Dead, Inertia, None }

View File

@@ -57,13 +57,13 @@ public void SetMaxJumpCount(int maxCount)
#region
//지상 이동이 가능한가?
public bool CanMove() => IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run);
public bool CanMove() => IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run) && (CurrentState != PlayerState.Inertia);
//점프가 가능한 상태인가?
public bool CanJump()
{
bool jumpAlreadyMax = (_maxJumpCount <= _jumpCount);
return IsGrounded && !IsMoveCut && !jumpAlreadyMax && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run);
return IsGrounded && !IsMoveCut && !jumpAlreadyMax && (CurrentState == PlayerState.Idle || CurrentState == PlayerState.Walk || CurrentState == PlayerState.Run) && (CurrentState != PlayerState.Inertia);
}
//대쉬가 가능한 상태인가?
public bool CanDodge()
@@ -78,6 +78,7 @@ public bool CanDodge()
if (CurrentState == PlayerState.Hit || CurrentState == PlayerState.Dead) return false;
if (IsMoveCut) return false;
if (CurrentState == PlayerState.Inertia) return false;
// 스태미나 시스템이 있다면 체크
// if (CurrentStamina < DodgeCost) return false;
@@ -85,7 +86,7 @@ public bool CanDodge()
return true;
}
//공중에서 조작 가능한 상태인가?
public bool CanControlInAir() => !IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Jump || CurrentState == PlayerState.Fall);
public bool CanControlInAir() => !IsGrounded && !IsMoveCut && (CurrentState == PlayerState.Jump || CurrentState == PlayerState.Fall) && (CurrentState != PlayerState.Inertia);
//공격이 가능한 상태인가?
public bool CanAttack()
{
@@ -97,6 +98,9 @@ public bool CanAttack()
if (CurrentState == PlayerState.Hit || CurrentState == PlayerState.Dead)
return false;
if (CurrentState == PlayerState.Dodge || CurrentState == PlayerState.Inertia)
return false;
// (Idle, Walk, Run, Jump, Fall 상태에서 공격 가능)
return true;
}