마우스 왼쪽 버튼을 누를 시 플레이어가 공격을 하는 기능을 만드려고 한다
PlayerManager.cs 에서 inputSystem을 통해 Attack 입력을 받고 PlayerInteractHandler.cs에서 해당 Attack 처리를 해준다
{...}
void Update()
{
Graviry, Ground Check
Move
****************************
if (_input.IsAttack())
{
interactHandler.Attack();
_input.AttackInput(false);
}
*****************************
}
{...}
public class PlayerInteractHandler : MonoBehaviour
{
private Animator animator;
private int animIDAttack;
private void Awake()
{
animator = GetComponentInChildren<Animator>();
animIDAttack = Animator.StringToHash("Attack");
}
public void Attack()
{
animator.SetTrigger(animIDAttack);
}
}
이제 애니메이터로 가서 Attack 설정을 해줘야 하는데 연속 공격이 가능한가 확인하기 위해 Attack 애니메이션을 2개 추가 해 줬다
애니메이터 파라미터에 Attack 파라미터 Trigger 형태로 선언하고 Attack이 눌렸을 시 이 Trigger를 활성화 해준다
Has Exit Time은 꺼줘야한다. 그래야지 Idle이든 Move 상태에서 Attack시 애니메이션이 즉시 실행되기 때문
연속 공격의 구현을 우선 간단히 isAttacking 파라미터를 이용했다
isAttacking은 즉 현재 공격중인가? 를 판별한다
콤보 공격을 이 isAttacking 대신 isCanCombo? 같은 것으로 대처 할 예정이다
게임에서 콤보는 공격 시작과 공격 끝남 그 사이에 가능하다는 것 보다는 언제 클릭해야 다음 공격이 나가는지 그 콤보 타이밍이 있기 때문이다
public class AnimationEventHandler : MonoBehaviour
{
private PlayerInteractHandler interactHandler;
private Animator animator;
private int animIDIsAttacking;
void Awake()
{
animator = GetComponent<Animator>();
animIDIsAttacking = Animator.StringToHash("isAttacking");
}
// 이 두가지 함수를 Attack1,2 애니메이션에 추가 해준다
public void EnableAttacking()
{
animator.SetBool(animIDIsAttacking, true);
}
public void DisableAttacking()
{
animator.SetBool(animIDIsAttacking, false);
}
}
공격이 끝이나게 되면 Idle Walk Run Blend로 Transition 할 수 있게 해준다
이 역시 Has Exit Time을 체크해제 해줘야 한다
플레이어 공격 도중 WASD 움직임이 가능해진다
➡️ PlayerManager.cs의 canMove를 AnimationEventHandler.cs 이벤트 함수에서 관리하기
{...}
public void EnableAttacking()
{
// 프로퍼티 Get Set
playerManager.CanMove = false;
animator.SetBool(animIDIsAttacking, true);
}
public void DisableAttacking()
{
playerManager.CanMove = true;
animator.SetBool(animIDIsAttacking, false);
}
{...}
PlayerManager.cs
void Update()
{
{...}
if (canMove)
{
playerMovement.Move();
}
#region Attack
if (_input.IsAttack())
{
interactHandler.Attack();
_input.AttackInput(false);
}
#endregion
{,,,}
}
클릭을 매우 빠르게 할 시 공격이 끝났음에도 한번 더 트리거가 돼서 공격한다
이는 AnimationEventHandler.cs의 DisableAttacking()함수에서 Attack에 대해 Reset Trigger을 해준다
public void DisableAttacking()
{
playerManager.CanMove = true;
animator.SetBool(animIDIsAttacking, false);
animator.ResetTrigger(
}
근데 AnimationEventHandler에서 Attack Trigger에 대해 접근하는데 PlayerInteractHandler.cs에서도 Attack Trigger에 접근한다
그래서 PlayerInteractHandler.cs는 AnimationEventHandler를 통해 Attack 기능을 처리 할 수 있도록 한다 ( 그래서 이름을 그냥 AnimationHandler로 바꿈 )
public class PlayerInteractHandler : MonoBehaviour
{
private AnimationEventHandler animationHandler;
private void Awake()
{
animationHandler = GetComponentInChildren<AnimationEventHandler>();
}
public void Attack()
{
animationHandler.Attack();
}
}
public class AnimationEventHandler : MonoBehaviour
{
private PlayerManager playerManager;
private Animator animator;
private int animIDIsAttacking;
private int animIDAttack;
void Awake()
{
playerManager = GetComponentInParent<PlayerManager>();
animator = GetComponent<Animator>();
animIDIsAttacking = Animator.StringToHash("isAttacking");
animIDAttack = Animator.StringToHash("Attack");
}
public void Attack()
{
animator.SetTrigger(animIDAttack);
}
public void EnableAttacking()
{
playerManager.CanMove = false;
animator.SetBool(animIDIsAttacking, true);
}
public void DisableAttacking()
{
playerManager.CanMove = true;
animator.SetBool(animIDIsAttacking, false);
animator.ResetTrigger(animIDAttack);
}
}
공격 도중 움직이지않고 공격 빠르게 해도 마우스 클릭이 뒤늦게 Trigger 되지 않음
Idle의 애니메이션이 Move 애니메이션과 부자연스러워서 Idle 애니메이션 적합한거 찾기
애니메이션 파라미터에 canCombo를 추가하고 AnimationHandler 함수를 통해 각 공격 애니메이션 마다 이벤트를 추가해서 좀 더 게임성 있는 공격 콤보를 구현하기
공격 시 앞으로 조금 이동하기
공격 시 일정시간 동안 카메라가 바라보는 방향으로 공격 방향을 바꿀 수 있게 하기
전투 시 조작감의 편의성, 게임성이 더 오를 것으로 예상