진행한 것들
플레이어 더블 점프
JumpCountHandler에서 JumpCount를 관리하고
public class JumpCountHandler
{
public JumpCountHandler(int maxJumpCount)
{
SetJumpCount(maxJumpCount);
}
public int JumpCount { get; private set; }
public void DecreaseJumpCount()
{
JumpCount--;
}
public void SetJumpCount(int count)
{
JumpCount = count;
}
}
PlayerJumpState에서 Jump 상태 변경을 관리한다.
using UnityEngine;
public class PlayerJumpState : PlayerAirState
{
private void Jump()
{
if (jumpCountSetter.JumpCount > 0)
{
animationController.ReStartIfAnimationIsPlaying(animationsData.JumpParameterHash);
jumpCountSetter.DecreaseJumpCount();
Vector3 velocity = rigid.velocity;
velocity.y = playerController.StatHandler.Data.JumpForce;
rigid.velocity = velocity;
}
}
}
마지막으로 자연스러운 더블점프 동작을 위해 현재 점프 상태이고 또 점프가 들어오면 처음부터 애니메이션을 다시 재생하도록 했다.
using UnityEngine;
public class AnimationController : MonoBehaviour
{
[field: SerializeField] public PlayerAnimationsData AnimationData { get; private set; }
private Animator _animator;
public void ReStartIfAnimationIsPlaying(int animationParameterHash, int layerIndex = 0)
{
if (_animator.GetCurrentAnimatorStateInfo(layerIndex).shortNameHash.Equals(animationParameterHash))
_animator.Play(animationParameterHash);
}
}
플레이어 구르기
구르기에서는 무적, 쿨타임, 구르기 시 움직임 제한 기능이 필요했다.
먼저 PlayerRollState에서 구르기 애니메이션과 구르기 끝났는지를 체크하고
public class PlayerRollState : PlayerStateBase
{
private void CheckRollingEnded()
{
if (animationController.CheckAnimationEnded(animationsData.RollParameterHash))
{
stateMachine.RollDataHandler.SetIsRolling(false);
if (stateMachine.IsGrounded)
stateMachine.ChangeState(stateMachine.MovementState);
else
stateMachine.ChangeState(stateMachine.FallState);
}
}
}
RollDataHandler에서 구르기 수행 시 무적과 쿨타임을 계산한다.
using UnityEngine;
public class RollDataHandler
{
public bool CanRoll { get; private set; }
public bool IsInvincible { get; private set; }
public bool IsRolling { get; private set; }
private float _rollingCoolTime;
private float _currentRollingElapsedTime;
private float _invincibleTime;
public RollDataHandler(float rollingCoolTime, float invincibleTime)
{
SetRollingCoolTime(rollingCoolTime);
_currentRollingElapsedTime = rollingCoolTime;
_invincibleTime = invincibleTime;
CanRoll = true;
}
public void SetRollingCoolTime(float rollingCoolTime)
{
_rollingCoolTime = rollingCoolTime;
}
public void ResetCurrentRollingElapsedTime()
{
CanRoll = false;
_currentRollingElapsedTime = 0f;
IsInvincible = true;
}
public void CalculateCoolTime()
{
if (_currentRollingElapsedTime >= _rollingCoolTime)
{
CanRoll = true;
return;
}
_currentRollingElapsedTime += Time.deltaTime;
_currentRollingElapsedTime =
_currentRollingElapsedTime > _rollingCoolTime ?
_rollingCoolTime : _currentRollingElapsedTime;
CalculateInvincible();
}
public void SetIsRolling(bool isRolling)
{
IsRolling = isRolling;
}
private void CalculateInvincible()
{
if (_currentRollingElapsedTime < _invincibleTime)
return;
IsInvincible = false;
}
}
오늘의 이슈 / 내일 할 것
더블 점프 구현을 위한 JumpCount 이슈
문제점 : JumpCount를 IsGronded일 때 JumpCountMax로 초기화를 해줬으나 Debug.Log를 찍어보면 초기화가 안 되는 이슈, PlayerJumpState에서의 문제인 줄 알고 PlayerAirState에 옮겼으나 결과는 같았음
원인 : 호출 스택을 살펴보니 PlayerFallState 부모의 PlayerAirState에서만 초기화되는 경우였음 (PlayerJumpState JumpCount != PlayerFallState JumpCount)
해결 : 공통적으로 참조하는 StateMachine에서 JumpCount를 관리하기로 함
** 또한 IsGrounded도 같은 이슈여서 StateMachine에서 관리하는 것으로 처리
플레이어가 날라가는 이슈
문제점 : 플레이어 날아가는 이슈
원인 : 점프 값에도 Speed가 곱해져 날라가던 것이었다.
해결 : 이동에만 Speed를 곱해주니 해결
내일 할 것 : 구르기 시 이동 입력 받기, 빌드
오늘의 회고
오늘은 캐릭터 더블 점프와 구르기를 구현했다. 더블 점프에 상태머신이 겹쳐서 참조 변수를 각각 따로 참조하게 되는 실수를 저질렀는데 이후에 호출 스택을 보고 처리하길 잘했던 것 같다. 그리고 구르기 시 Input을 받지 않는 작업은 InputSystem의 Interaction Hold 부분을 좀 더 공부해보고 적용해봐야겠다. 내일도 파이팅!
'스파르타 Unity 1기' 카테고리의 다른 글
DevLog - 이그라엘(IGRAL) 적 상태머신 (0) | 2023.10.31 |
---|---|
DevLog - 이그라엘(IGRAL) 빌드와 이동 버그 수정 (1) | 2023.10.30 |
DevLog - 이그라엘(IGRAL) 플레이어 이동 애니메이션과 상태머신 (1) | 2023.10.26 |
DevLog - 이그라엘(IGRAL) 플레이어 이동과 회전 (0) | 2023.10.25 |
DevLog - 이그라엘(IGRAL) 기획과 플레이어 데이터 (0) | 2023.10.24 |