김김김의 게임개발
  • 유니티 게임 개발 - 2D애니메이션
    2023년 09월 22일 21시 04분 08초에 업로드 된 글입니다.
    작성자: noun06

    플랫포머 게임을 만들어보면서 2D애니메이션 실습을 진행하였다. 

     

    시작하기 전에 준비해야할 것은 애니메이션을 만들 재료인 스프라이트다. 

    하지만 보통 스프라이트 리소스는 여러 이미지들이 합쳐진 스프라이트 시트로 이루어져있다.

    그러므로 바로 사용할 수 있도록 각각의 스프라이트로 쪼개고 위치를 맞추는 작업을 먼저 진행해야 한다.

    1) 스프라이트 시트의 Sprite Mode를 Multiple로 변경한다.

    2) Sprite Editor에 들어가서 크기에 맞춰 Slice를 한다. 나는 Grid By Cell Size 옵션으로 크기를 따로 지정하였다.

    3) 스프라이트 시트의 크기를 Pixel Per Unit을 조절하여 세팅한다.

    4) 스프라이트가 흐리게 보이는 경우, Filter Mode는 Point(no filter), Compression은 None으로 설정하고 apply한다.

     

    이 때, 스프라이트의 중심이 원하지 않는 위치에 설정되어 있을 수도 있다.

    Sprite Editor에서 설정해 줄 수도 있지만 너무 비효율적이다.

    다른 방법이 있다.

    플레이어 오브젝트에 바로 SpriteRenderer 컴포넌트를 넣어주는 것이 아닌 자식 오브젝트를 만들어서 SpriteRender 컴포넌트를 넣어주고 나중에 Animator도 그곳에 넣어줄 것이다.

    그리고 이제 자식 오브젝트의 위치만 잘 조절하여 스프라이트의 중심을 맞출 수 있다.

     

    그 다음 준비해야하는 것은 Animator Controller이다.

    나는 Player_AC라는 이름의 Animator Controller를 프로젝트 창에 하나 만들고 플레이어의 스프라이트가 들어있는 오브젝트에 넣어줬다.

    그러면 자동적으로 Animator라는 컴포넌트가 생성된다. 

     

    이제 실제로 움직이는 애니메이션을 만들 차례이다.

    Animation 창에서 Animator가 붙어있는 오브젝트를 클릭한다.

    그리고 Create New Clip을 눌러 Animation Clip을 생성한다.

    첫번째로 player_idle을 만들 것이다.

    이제 애니메이션에 쓰일 스프라이트 다섯개를 드래그 앤 드롭을 한다.

    간격이 너무 짧아 Sample Rate를 10으로 설정하였다. 

    동일한 방식으로 player_move도 만들었다.

     

    이제 두 애니메이션 동작을 상황에 맞게 바뀌도록 연결해주어야한다. 

    Animator 창에 가서 player_idle 스테이트 박스와 player_move 스테이트 박스를  make transition을 통해 서로를 지정한다.

    그리고 bool 파라미터 IsMoving을 하나 만들어준다. 

    transition 화살표에서 Conditions 탭에 IsMoving를 추가하고 상태를 지정한다. idle -> move 는 true, move -> idle은 false.

    또한 옵션에서 Has Exit Time 체크 해제, Transition Duration을 0으로 세팅하여 빠른 전환이 가능하도록 만든다.

     

    이제 스크립트에 적용할 차례이다.

    간단하게 실습을 할 스크립트인 Player.cs 스크립트는 현재 Player 오브젝트에 붙어있고 좌우 이동 및 점프 기능이 있다.

    우선 private Animator 변수 anim을 선언하고 Start()메서드에서 자식 오브젝트의 Animator 컴포넌트를 가져온다.

    private Animator anim;
    
    void Start()
        {
            rb = GetComponent<Rigidbody2D>();
            anim = GetComponentInChildren<Animator>();

     

    새로운 메서드 AnimatorControllers()를 만들고 안에 SetBool() 메서드를 통해 상황에 맞는 애니메이션을 지정한다.

    isMoving은 x축 속도가 0이 아닐 때, 즉 플레이어가 움직이고 있을 때만 true값이 된다.

    private void AnimatorControllers()
        {
            bool isMoving = rb.velocity.x != 0;
    
            anim.SetBool("IsMoving", isMoving);
        }

     

    이제 다음으로 점프와 낙하 애니메이션을 추가해볼 것이다.

    각각의 애니메이션을 만들어서 추가할 수도 있지만 Blend Tree라는 기능을 사용할 것이다.

    점프와 낙하 애니메이션은 완전히 상호작용하는 애니메이션이기 때문에 하나의 Blend Tree로 표현이 가능하다.

    우선 각자의 애니메이션 클립을 만든다. 

    그리고 Animator 창에 있는 Jump랑 Fall을 지우고 Blend Tree 스테이트를 하나 만들어 이름을 JumpFall이라고 짓는다.

    YVelocity라는 int 형 파라미터를 하나 만든다.

    Blend Tree는 int 값을 통해 각각의 상태를 지정할 수 있는데 y값이 0일때 정지, -1일때 낙하, 1일때 점프를 하게 할것이다.

    만들어 놓앗던 jump, fall 클립들을 Motion에 추가하고 Threshold를 각각 1, -1로 설정한다.

    이제 다시 Base Layer로 돌아와서 AnyState -> JumpFall, JumpFall -> player_idle과 같이 transition을 세팅한다. 

    IsGrounded라는 파라미터를 추가해서 각 화살표에 알맞게 상태를 추가한다.

     

    스크립트로 돌아와서 AnimatorControllers() 메서드에 다음과 같이 상태를 추가한다.

    private void AnimatorControllers()
        {
            bool isMoving = rb.velocity.x != 0;
    
            anim.SetFloat("YVelocity", rb.velocity.y);
            anim.SetBool("IsMoving", isMoving);
            anim.SetBool("IsGrounded", isGrounded);
        }

     

    댓글