진행한 것들

플레이어 공격

플레이어 공격 애니메이션은 다른 것들처럼 믹사모에서 가져왔다.

플레이어의 AttackState에서의 Update문인데 AnimationController의 AttackType의 이름으로 현재 애니메이션의 Clip 이름과 비교하여 같은 상황에서 Attack 입력을 감지하면 AttackCombo 애니메이션 파라미터가 증가하게 만들어 다음 연속 동작으로 이어갈 수 있게끔 구현하였다.

또한 animator.GetCurrentClipInfo()[0]을 가져왔는데 왜 0번을 가져왔냐면 -> ClipInfo가 배열 타입으로 들어있는데 transition할 때는 2개안 할때는 1개라서 기본적으로 0번을 가져와 비교한 것이다.

public override void UpdateState()
{
    base.UpdateState();

    if (animationController.CheckCurrentClipEnded(animationController.AttackType))
    {
        stateMachine.ChangeState(stateMachine.MoveState);
    }
    else
    {
        if (animationController.IsAttackInputted && animationController.CheckCurrentClipEqual(animationController.AttackType))
        {
            animationController.SetAttackInputted(false);
            animationController.IncreaseAttackCombo();
            animationController.SetNextAttackType();
            animationController.PlayAnimation(animationsData.AttackComboHash, animationController.AttackCombo);
        }
    }
}
public bool CheckCurrentClipEnded(AttackType attackType, int layerIndex = 0)
{
    var clipInfo = animator.GetCurrentAnimatorClipInfo(layerIndex);
    if (clipInfo[0].clip.name.Equals(attackType.ToString()))
    {
        var stateInfo = animator.GetCurrentAnimatorStateInfo(layerIndex);

        if (stateInfo.normalizedTime >= animationNormalizeEndedTime)
            return true;
    }

    return false;
}

public bool CheckCurrentClipEqual(AttackType attackType, int layerIndex = 0)
{
    var clipInfo = animator.GetCurrentAnimatorClipInfo(layerIndex);
    Debug.Log($"clipInfo[0].clip.name : {clipInfo[0].clip.name}\nattackType : {attackType}");

    if (clipInfo[0].clip.name.Equals(attackType.ToString()))
        return true;
    else
        return false;
}

 

 

오늘의 이슈 / 내일 할 것

어제 이슈 : 패트롤 비동기

Async에서 동작하는 것이 아닌 Coroutine으로 동작할 수 있게끔 하여 내가 시작과 끝을 제어할 수 있게끔 수정하였다.

목표 지점에 다다랐다면 멈춰서서 순찰 애니메이션을 지정한 시간만큼 실행하고 다시 패트롤 상태로 돌입할 수 있게끔 재귀로 구성하였다.

public void CheckArrived()
{
    _currentEnumerator = CheckArrivedTargetPos();
    EnemyController.ExcuteCoroutine(_currentEnumerator);
}

public void StopCheckingArrived()
{
    EnemyController.TerminateCoroutine(_currentEnumerator);
}

private IEnumerator CheckArrivedTargetPos()
{
    if (IsTracing)
        yield break;

    CalculateDirection();

    bool isFar = true;

    while (isFar)
    {
        isFar = Direction.x < 0 ?
        _targetXPos <= EnemyController.transform.position.x : _targetXPos >= EnemyController.transform.position.x;
        yield return null;
    }

    SetDirection(Vector2.zero);

    yield return new WaitForSeconds(EnemyController.MovementData.WaitPatrolTime);

    CheckArrived();
}

private void CalculateDirection()
{
    float randomXPos = UnityEngine.Random.Range(_tileXPos - _tilehalfPowLength, _tileXPos + _tilehalfPowLength);

    Debug.Log($"_tileXPos - _tileHalfLength {_tileXPos} - {_tileHalfLength}");

    randomXPos = Mathf.Clamp(randomXPos, _tileXPos - _tileHalfLength, _tileXPos + _tileHalfLength);

    bool isLeft = EnemyController.transform.position.x > randomXPos;

    _targetXPos = randomXPos;

    int directionX = isLeft ? -1 : 1;

    SetDirection(directionX);
}

 

 

오늘 이슈

1. 플레이어 공격에서 현재 클립에 대한 정보를 얻기 어려웠다.

animator.GetCurrentAnimatorClipInfo() 메서드를 이용하여 현재 클립의 이름을 가져오고 애니메이션의 이름을 담은 enum 타입의 AttackType을 String한 값과 비교하여 같은지 비교하여 해결하였다.

 

2. <테스트 후 알게된 내용>

animator.GetCurrentState().fullPathHash의 예 : Animator.StringToHash("Base Layer.@Attack.Attack1")

* Base Layer의 띄어쓰기도 포함이다.

animator.GetCurrentState().shortNameHash의 예 : Animator.StringToHash("Attack1")

 

3. 공격 중에 점프, 구르기, 이동할 때 공격이 취소되거나 계속 움직일 수 있는데 이것은 내일 해결할 것이다.

 

 

내일 할 것

1. 공격 중에 점프, 구르기 이동 막기 (이동은 처음 공격 시 방향 전환만 적용)

2. 맵 정보를 받아와서 적이 플레이어 추적하고 공격할 수 있도록 하기

 

 

오늘의 회고

  오늘은 연속 공격을 구현했다. 굉장히 머리 아픈 작업이었는데 계속 테스트 해보고 여러 방법을 시도하다보니 좋은 방법을 찾은 것 같다. 내일은 맵에서 적과 상호작용 하면서 전체적으로 플레이어와 적이 잘 동작하는지 확인하고 완성도를 높일 생각이다. 내일도 파이팅!

 

+ Recent posts