화살 스킬

Eunho Bae·2022년 5월 24일

목표

화살은 움직이기도 하고 어떤 물체에 닿으면 사라지며 데미지를 입히는 효과를 적용시켜야 하기 때문에 컨트롤러가 필요하다.
그래서 ArrowController를 만들고 Arrow 스프라이트에 붙여주었다.

UpdateAnimation() 함수 재정의

CreatureController에서 가상함수로 정의된 UpdateAnimation이 있었다. 플레이어만 쓸 수 있는 화살 애니메이션을 추가해줘야 하기 때문에 PlayerController에서 override하여 재정의해준다.

이번에는 화살 스킬 하나 밖에 없기 때문에 간단하게 클래스 멤버변수로 _rangeSkill = false로 선언해주었다.
(나중에 스킬이 많아질 때는 어떤 스킬에 어떤 애니메이션을 재생할지는 스킬 관련 데이터시트로 따로 빼주어서 관리하게 된다.)

_rangeSkill은 펀치할 때 호출하는 코루틴 함수에서 false로, 화살 쏠때 호출하는 코루틴 함수에서 true로 맞춰준다.

override된 UpdateAnimation 함수는 다음과 같이 바꿔주었다.

 else if (_state == CreatureState.Skill)
        {
            switch (_lastDir)
            {
                case MoveDir.Up:
                    _animator.Play(_rangeSkill ? "ATTACK_WEAPON_BACK" : "ATTACK_BACK");
                    _sprite.flipX = false;
                    break;
                case MoveDir.Down:
                    _animator.Play(_rangeSkill ? "ATTACK_WEAPON_FRONT" : "ATTACK_FRONT");
                    _sprite.flipX = false;
                    break;
                case MoveDir.Left:
                    _animator.Play(_rangeSkill ? "ATTACK_WEAPON_RIGHT" : "ATTACK_RIGHT");
                    _sprite.flipX = true;
                    break;
                case MoveDir.Right:
                    _animator.Play(_rangeSkill ? "ATTACK_WEAPON_RIGHT" : "ATTACK_RIGHT");
                    _sprite.flipX = false;
                    break;
            }
        }

소스

아래는 별 설명없이 넘어가겠다.

PlayerController

    IEnumerator CoStartShootArrow()
    {
        GameObject go = Managers.Resource.Instantiate("Creature/Arrow");
        ArrowController ac = go.GetComponent<ArrowController>();
        ac.Dir = _lastDir;
        ac.CellPos = CellPos;

        _rangeSkill = true; 
        yield return new WaitForSeconds(0.3f);
        State = CreatureState.Idle;
        _coSkill = null;
    }

ArrowController

public class ArrowController : CreatureController
{
    protected override void Init()
    {
        switch(_lastDir)
        {
            case MoveDir.Up:
                transform.rotation = Quaternion.Euler(0, 0, 0);
                break;
            case MoveDir.Down:
                transform.rotation = Quaternion.Euler(0, 0, -180);
                break;
            case MoveDir.Left:
                transform.rotation = Quaternion.Euler(0, 0, 90);
                break;
            case MoveDir.Right:
                transform.rotation = Quaternion.Euler(0, 0, -90);
                break;
        }

        base.Init();
    }

    protected override void UpdateAnimation() {}

    protected override void UpdateIdle()
    {
        if (_dir != MoveDir.None) // 유닛 한칸 이동 끝날때까지 입력 못받게
        {
            Vector3Int destPos = CellPos;
            switch (Dir)
            {
                case MoveDir.Up:
                    destPos += Vector3Int.up;
                    break;
                case MoveDir.Down:
                    destPos += Vector3Int.down;
                    break;
                case MoveDir.Left:
                    destPos += Vector3Int.left;
                    break;
                case MoveDir.Right:
                    destPos += Vector3Int.right;
                    break;
            }

            State = CreatureState.Moving;

            if (Managers.Map.CanGo(destPos))
            {
                GameObject go = Managers.Obj.Find(destPos);
                if (go == null)
                {
                    CellPos = destPos;
                }
                else
                {
                    Debug.Log($"hits {go.name}");
                    Managers.Resource.Destroy(gameObject);
                }
            }
            else
            {
                Managers.Resource.Destroy(gameObject);
            }
        }
    }
}

참고

  • MMORPG를 만들때 클라이언트에서 화살을 움직이게 하거나 피격 처리를 하는게 아닌 서버에서 해당 작업을 처리한다.
profile
개인 공부 정리

0개의 댓글