기본적인 움직임을 모두 만들었으니 기본 공격과 기본 공격 애니메이션을 만들 차례이다.
기본 공격은 총 세개의 콤보 형태로 만들 예정이다.
만약 첫번째 공격이 끝나기 전에 한번 더 클릭하면 두번째 콤보로 이어지고 여기서 한번 더 클릭하면 마지막 콤보로 이어지는 식
먼저 플레이어의 공격을 관리하는 PlayerAttackController.cs를 만들어준다.
AttackController의 역할은 Update에서 사거리 내의 가장 가까운 적을 찾고, 그것을 Target에 넣는것이다.
public TestEnemy CurrentTarget;
public void SetTarget()
{
int numColliders = Physics.OverlapSphereNonAlloc(transform.position, 15f, _hitColliders, _enemyLayer);
TestEnemy closestEnemy = null;
for (int i = 0; i < numColliders; i++)
{
Collider enemyColl = _hitColliders[i];
if (enemyColl != null)
{
float distance = Vector3.Distance(transform.position,
enemyColl.ClosestPoint(transform.position));
if (distance < _targetRange)
{
closestEnemy = enemyColl.GetComponent<TestEnemy>();
}
}
}
if (closestEnemy != null)
{
float minDistance = Vector3.Distance(transform.position, closestEnemy.transform.position);
if (minDistance > _stopRange)
{
CurrentTarget = closestEnemy;
}
}
else
{
CurrentTarget = null;
}
}
이제 공격 State들을 만들어줄 차례인데, AttackController에서 찾은 타겟이 없다면 그냥 전방으로 짧은 돌진을 하며 공격을 하게 할것이고 타겟이 있다면 그 타겟을 바라보고 타겟에게 돌진하는 공격을 만드려고 한다.
일단 타겟 없는 공격부터 제작.
public class PlayerGroundedState : State
{
public override void EnterState()
{
base.EnterState();
_owner.InputReader.BasicAttackEvent += AttackHandle;
_owner.InputReader.DodgeEvent += DodgeHandle;
}
public override void ExitState()
{
base.ExitState();
_owner.InputReader.BasicAttackEvent -= AttackHandle;
_owner.InputReader.DodgeEvent -= DodgeHandle;
}
private void AttackHandle()
{
if (_owner.CanAttack)
_stateMachine.ChangeState(StateTypeEnum.BasicAttack);
}
}
일단 InputReader에서 좌클릭이 감지됐다면 BasicAttackState로 이동. (CanAttack이 true일때만 이동)
public override void EnterState()
{
base.EnterState();
_owner.StopImmediately();
_owner.CanMove = false;
_owner.Dash(_owner.AnimatorCompo.transform.forward,
_dashDelay, _dashTime, _dashSpeed, DashTypeEnum.AttackDash);
_owner.AnimatorCompo.SetAttackCount(_owner.CurrentComboCounter);
_owner.AnimatorCompo.SetAttackAnimation(true);
_owner.CurrentComboCounter++;
_owner.CanAttack = false;
}
BasicAttackState에 진입 시 먼저 움직임을 멈춰주고 좌우상하로 움직이는 키를 잠궈준다.
그리고 PlayerController.cs에 있는 대쉬 기능으로 전방으로 살짝 돌진한다.
애니메이션 쪽은 콤보 공격이기 때문에 SetBool과 SetInteger를 사용하여 애니메이터에서 콤보를 부여받는다.
PlayerAnimator.cs의 SetAttackCount에 int값을 넣어 콤보를 넣어주고, SetAttackAnimation을 true로 해주어 애니메이션을 실행한다.
여기서 int값은 0이므로 첫번째 콤보 애니메이션 실행.
애니메이션 구조는 이렇게 되어있다.
애니메이션을 실행하고 바로 CanAttack을 false로 바꿔주는데, 공격을 하고 바로 그 다음공격을 못하게 잠시 딜레이를 주는 것이다.
공격 애니메이션에서 다음 콤보랑 부드럽게 이어질만한 부분에서 Animation Event를 사용해 CanAttack을 true로 바꿔준다.
공격 애니메이션이 끝나는 부분엔 CanAttack을 다시 false로 바꿔준다.
개발한 시스템을 요약해서 설명하면,
좌클릭으로 첫번째 공격을 하고, 끝나가기 전에 또다시 좌클릭을 하면 다음 콤보로 넘어가 공격을 한다. (콤보는 0~2 총 세개)
공격을 하고 좌클릭을 하지 않으면 공격은 종료되고 콤보는 다시 0으로 돌아간다.
여기서 방금 PlayerAttackController.cs에서 찾은 Target이 존재하고 그 타겟이 사거리 안에 있다면,
공격을 했을 때 타겟을 바라보고 돌진하는 기능을 만들것이다.
BasicAttackState에 진입할 때 타겟이 있는지 체크하는 조건문을 추가했다. 만약 Target이 있다면 PlayerAttackController.cs의 RotateToTarget을 실행해주고 Dash의 매개변수를 달리 주어 더 빠르게 돌진하게 한다.
public void RotateToTarget()
{
var destRotation = Quaternion.LookRotation(CurrentTarget.transform.position - transform.position);
transform.rotation = destRotation;
}
PlayerAttackController.cs의 RotateToTarget이다. 타겟 방향으로 바로 회전한다.
'Unity > 개인프로젝트' 카테고리의 다른 글
[Unity] 갠프(2) - 플레이어 움직임 & 애니메이션 (1) | 2024.07.07 |
---|---|
[Unity] 갠프(1) - 프로젝트 시작, 에셋 적용 (0) | 2024.07.06 |