업그레이드 한 부분
public class AnimationHandler : MonoBehaviour
{
{....}
private bool playingComboAttack;
{....}
public void Attack()
{
animator.SetTrigger(animIDAttack);
}
public void EnableAttacking()
{
***************************************************************
// Attack 활성화 하려는데 이미 활성화 돼있으면 콤보어택 중인 것
if (playerManager.IsAttacking)
{
playingComboAttack = true;
}
***************************************************************
playerManager.IsAttacking = true;
animator.SetBool(animIDIsAttacking, true);
// 다음 동작으로 넘어갈테니 콤보 가능한 구간을 초기화 해줘야 함
animator.SetBool(animIDCombo, false);
}
public void DisableAttacking()
{
***************************************************************
// 콤보 도중이면 AttackDisable 하지 못하게
if (!playingComboAttack)
{
animator.ResetTrigger(animIDAttack);
playerManager.IsAttacking = false;
animator.SetBool(animIDIsAttacking, false);
animator.SetBool(animIDCombo, false);
}
***************************************************************
}
{....}
public void DisableCombo()
{
animator.SetBool(animIDCombo, false);
***************************************************************
playingComboAttack = false;
***************************************************************
}
이미 isAttacking이 활성화가 돼 있는 상태에서
모든 공격 애니메이션의 첫 프레임 이벤트, EnableAttacking()이 또 호출 되면 콤보 공격 상황으로 간 것
그래서 AnimationHandler.cs에 bool형 playingComboAttack을 선언하고 true로 바꿔줬다
앞서 말한 오류가 일어나는 이유는 다음 공격애니메이션으로 넘어갔는데도 이전 공격 애니메이션에서 DisableAttacking 이벤트를 실행했기 때문이었다
그래서 만약에 공격 콤보로 넘어갔다면 해당 이벤트는 실행하지 않게끔 해준다
그리고 공격 콤보를 false로 다시 해주는 것은 일정 타이밍을 놓쳐 더 이상 다음 공격으로 이어지는 콤보가 불가능 할때 해주면 된다
우선 공격 방향을 카메라가 바라보는 방향으로 구하려고 한다
그 구하는 위치는 AttackInput이 활성화 됐을때가 적절하다
PlayerManager에서 input을 통해 AttackInput을 받아오고 true일때 PlayerInteractionHandler.cs의 Attack 함수를 호출하는 구조
{...}
public void Attack()
{
attackRotation = Quaternion.Euler(0, _mainCamera.transform.eulerAngles.y, 0);
dir = _mainCamera.transform.forward;
// y에는 영향을 주면 안됨
dir = new Vector3(dir.x, 0, dir.z).normalized;
animationHandler.Attack();
}
public void RotateAttackDir()
{
transform.rotation = Quaternion.Lerp(transform.rotation, attackRotation, attackRotationSpeed * Time.deltaTime);
}
public void MoveAttack()
{
characterController.Move(dir * Time.deltaTime);
}
{...}
void Update()
{
#region Gravity, Ground
gravityGroundController.GroundedCheck();
gravityGroundController.ApplyGravity();
#endregion
#region Move
if (canMove)
{
playerMovement.Move();
}
#endregion
#region Attack
if (_input.IsAttack())
{
interactHandler.Attack();
_input.AttackInput(false);
}
if (isAttacking)
{
canMove = false;
interactHandler.RotateAttackDir();
if (canAttackMove)
interactHandler.MoveAttack();
}
else
{
canMove = true;
}
#endregion
{...}
여기서 canAttackMove를 통해 MoveAttack을 하는 부분이 있는데
canAttackMove는 애니메이션 이벤트를 통해 true,false가 결정 된다
솔직히 그냥 안해도되는데 공격이 시작했다고 앞으로 이동을 바로 시작하는게 좀 부자연스러워 보여서 특정 애니메이션 프레임 구간에서만 앞으로 이동 가능하게 했다
public void ActivateMove()
{
playerManager.CanAttackMove = true;
}
public void DeActivateMove()
{
playerManager.CanAttackMove = false;
}
첫번째 공격 시 조금 앞으로 이동하는 것을 볼 수 있다
회전 또한 카메라 방향으로 하는 것을 볼 수 있다