본문 바로가기
2D 콘텐츠 제작/[언데드 서바이벌] 제작 일지

[언데드 서바이벌 01] 게임오브젝트 생성, 애니메이션 제작, 이동 구현

by 잰쟁 2023. 9. 13.
728x90

 

1. 게임오브젝트 생성

 

유튜버 골드메탈님께서 만드신 교육용 게임개발 강좌이기 때문에 친절히 에셋도 다운 받을 수 있다!

 

에셋 다운받기

https://assetstore.unity.com/packages/2d/undead-survivor-assets-pack-238068

 

Undead Survivor Assets Pack | 2D | Unity Asset Store

Get the Undead Survivor Assets Pack package from Goldmetal and speed up your game development process. Find this & other 2D options on the Unity Asset Store.

assetstore.unity.com

 

 

에셋을 다운받아 열어보니 플레이어(Farmer)와 몬스터(Enemy)의 스프라이트 시트가

아래와 같이 이미 다 뜯어져있는 상태였다..

이미 다 분리되어 있는 스프라이트들

 

 


 

2. 애니메이션 제작

 

보니까 몬스터(Enemy)의 경우는 애니메이션도 이미 다 만들어져 있어서 플레이어(Farmer)의 애니메이션만 만들어보았다.

 

방법 : 애니메이션을 만들 게임오브젝트를 선택 -> Window -> Animation -> Animation 클릭

-> Create 누르고 이름지정 후 생성

Idle 애니메이션 생성

 

Animation 창에 선택한 게임오브젝트의 스프라이트들을 옮긴 후 간격을 조절하면

아래와 같이 동작하며 완성된다.

 

Idle 상태 애니메이션 완성

 

같은 방법으로 Run, Dead 애니메이션들도 만들어줬다.

플레이어(Farmer) 애니메이션들

 

 


 

3. 이동 구현

 

Scripts 폴더를 생성한 후 폴더 안에 Player 스크립트 생성

 

(아직 Joystick으로 인풋을 받기 전에 화살표 키보드로 Player를 이동시켜보았다.)

 

 

[이동시 구현할 것]

- 화살표 키보드를 인풋으로 받아 상하좌우로 이동

- 이동시 Run 애니메이션도 함께 실행, 이동을 멈추면 Idle 애니메이션 실행

- 오른쪽 화살을 누르면 오른쪽을 바라보며 오른쪽으로 이동,

왼쪽 화살을 누르면 왼쪽을 바라보며 왼쪽으로 이동(방향전환)

 


 

 

01.  화살표 키보드 인풋받아 상하좌우 이동

 

Player 스크립트

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Player : MonoBehaviour
{
    private float moveSpeed = 5f;
    
    void Start()
    {
    
    }

    void Update()
    {
        //상하, 좌우 인풋값 받기
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        //방향 설정
        Vector3 dir = new Vector3(h, v, 0).normalized;
        //이동
        this.transform.Translate(dir * this.moveSpeed * Time.deltaTime);
        Debug.Log(dir);
    }
}

이동만 하는 모습

 

 

**의문

Q : Player 스크립트에 애니메이션을 지정하지 않았는데 Idle하는 이유?

A : Player Animator Controller를 보면 idle 상태가 Default State로 설정되어 있어서

 

 

 


 

02. 애니메이션 함께 실행

 

나는 Player 애니메이션이 많지 않아서 Parameters를 int로 설정하고 이름은 "State"로 만들어서 관리하였다.

- 정지 상태(Idle) : State = 0

- 이동 상태(Run) : State = 1

 

Player 스크립트

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Player : MonoBehaviour
{
    private Animator anim;
    private float moveSpeed = 5f;
    
    void Start()
    {
        this.anim = this.GetComponent<Animator>();
    }

    void Update()
    {
        //상하, 좌우 인풋값 받기
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        //방향 설정
        Vector3 dir = new Vector3(h, v, 0).normalized;
        //이동
        this.transform.Translate(dir * this.moveSpeed * Time.deltaTime);
        Debug.Log(dir);

        //이동을 하지 않고 있다면
        if (dir == Vector3.zero)
        {
        	//Idle
            this.anim.SetInteger("State", 0);
        }
        else
        {
        	//Run
            this.anim.SetInteger("State", 1);
        }
    }
}

 

 

위와 같이 애니메이션을 설정하고 스크립트를 작성했을때 아래와 같이 동작한다.

 

애니메이션 적용하여 이동하는 모습

 

 


 

03. 방향전환 시키기

 

방향전환은 localScale을 사용!

 

transform.localScale = new Vector3(1,1,1) => 오른쪽 방향

transform.localScale = new Vector3(-1,1,1) => 왼쪽 방향

 

오류발생

이동중일때 방향을 전환시키면 될 것 같아서 아래와 같이 스크립트를 작성하였는데..

Player 스크립트 中

좌우로는 잘 가는데 상하로 갈 때 게임오브젝트가 없어지는 오류가 생겼다..

.

.

.

 

여러 고민을 한 결과

x축 방향을 결정하는 h 의 값은 -1,0,1인데,방향전환을 받는 값은 -1,1 뿐이여서

h = 0 일때 localScale로 인해 크기가 0이 되어서 안 보이는 것 같다.

(그냥 가만히 서 있을때는 Vector3.zero 상태이므로 Idle 애니메이션을 하는 것 같다.)

 

따라서 아래와 같이 if문을 만들어 'h != 0' 인 조건을 추가하여 그 안에 방향전환을 넣어준 결과 잘 동작하였다!!

 

Player 스크립트

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Player : MonoBehaviour
{
    private Animator anim;
    private float moveSpeed = 5f;
    
    void Start()
    {
        this.anim = this.GetComponent<Animator>();
    }

    void Update()
    {
        //상하, 좌우 인풋값 받기
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        //방향 설정
        Vector3 dir = new Vector3(h, v, 0).normalized;
        //이동
        this.transform.Translate(dir * this.moveSpeed * Time.deltaTime);
        Debug.Log(dir);

        //이동을 하지 않고 있다면
        if (dir == Vector3.zero)
        {
            //Idle
            this.anim.SetInteger("State", 0);
        }
        else
        {
            //Run
            this.anim.SetInteger("State", 1);
            //h의 값이 0이 아니면
            if(h != 0)
            {
                //방향전환
                this.transform.localScale = new Vector3(h, 1, 1);
            }
        }
    }
}

방향전환까지 하여 동작하는 모습

 

 

+느낀점

: 아직 스크립트 작성하는 것도 미흡하긴 하지만 이제는 문제가 발생했을때 '생각'이라는 것을 조금씩 하는 것 같아 기분 좋았다.. 생각하는 것이 정말 중요하구나를 여실히 느꼈다.. 내일도 아잣잣