[Unity][2D-Game] Undead Survivor (2)

suhan0304·2023년 11월 3일
0
post-thumbnail
post-custom-banner

preview Link : https://velog.io/@suhan0304/Unity2D-GameUndead-Survivor-1
gitHub Link : https://github.com/suhan0304/Undead-Survivor


Review

직전 개발을 어떤 작업을 했는지 리뷰를 한 후 개발을 진행하겠다.

  • 기본적으로 유니티 프로젝트를 먼저 생성을 진행했고 개발에서 사용할 package를 import 했다.
  • 스프라이트들의 드로우 콜이 여러번 발생하는 것을 방지하기위해 스프라이트 파일들을 하나의 파일로 묶어 성능 낭비를 줄이는 스프라이트 아틀라스라는 방식을 사용했다.
  • 픽셀 아트로 게임을 개발하기 위해서 스프라이트 사전 설정을 진행했다.
  • Multiple Mode의 스프라이트를 Sprite Editor를 사용해 사이즈별로 슬라이싱을 진행했다.
  • 슬라이싱 된 스프라이트를 사용해 "Player"라는 게임 오브젝트를 생성해주었으며 "Shadow"라는 스프라이트를 자식 오브젝트로 추가해주었다.
    - 그림자가 플레이어의 뒤에 오도록 Order in Layer을 수정했다.

자세한 개발 내용은 이전 게시글을 참고


강의영상 (2) - 플레이어 이동 구현하기


개발

스크립트 생성

플레이어 이동을 구현하기 위해 Assets/Undead Survivor/Codes/ 안에 Player 스크립트를 하나 생성해주었다.

스크립트 생성하고 바로 스크립트를 열면 스크립트가 고장나서 나중에 컴포넌트로 추가할 수가 없다. 오른쪽 아래의 로딩이 끝날 때까지 기다렸다가 미리보기가 된다면 그 이후에 스크립트를 작성한다.

기본적인 게임 오브젝트는 MonoBehaviour을 상속받는데 이는 게임 로직 구성에 필요한 것들을 가진 클래스이다. 해당 클래스 안에 추후에 사용할 함수, 속성이 모두 포함되어있다.

	public class Player : MonoBehaviour

    void Update()
    {
        inputVec.x = Input.GetAxis("Horizontal");
        inputVec.y = Input.GetAxis("Vertical");
    }

이 때 버튼을 누르고 있어야만 점차 1까지 증가하는데 이는 나중에 움직임을 구현할 때 속도가 일정하지 않고 천천히 증가, 감소하게 되는 현상 또는 미끄러지는 느낌이 발생한다. 개발중인 게임은 키를 얼마나 눌렀는지에 상관없이 항상 정해진 속도로 출발해서 멈춰야하기 때문에 0 또는 1로만 받고 싶다. 따라서 GetAxisRaw 함수를 사용해서 키를 입력하면 1, 키를 입력하지 않으면 0으로만 받도록 할 수 있다.

    void Update()
    {
        inputVec.x = Input.GetAxisRaw("Horizontal");
        inputVec.y = Input.GetAxisRaw("Vertical");
    }

키보드 입력 받기

    public Vector2 inputVec;

다음과 같이 Update 안에 Input으로 키를 입력받아서 GetAxis의 매개변수로 넘겨주는 이름의 축을 기준으로 버튼의 작용을 inputVec에 설정해줄 수 있다.

  • Positive 버튼 : 누르고 있으면 x, y가 1까지 설정됨
  • Negative 버튼 : 누르고 있으면 x, y가 -1까지 설정
Update()는 한 프레임마다 실행되는 함수

Edit > Project Settings > Input Manager 를 통해 어떤 키가 어떤 이름의 축에 적용되는 버튼인지를 확인할 수 있다.

  • Horizontal 축에 왼쪽 방향키가 Negative Button, 오른쪽 방햐키가 Positive Button으로 작동하고 있음을 알 수 있다.

오브젝트 이동하기

물체의 물리적 작용을 당담하는 Rigidbody 2D를 선언해준 후 Awake 안에서 초기화 시켜준다.

Awake는 시작할 때 한번만 실행되는 생명주기 함수
	void Awake()
    {
        rigid = GetComponent<Rigidbody2D>();
    }

다음과 같이 GetComponont로 이전에 추가시켜놨더 Rigidbody2D를 가져와 rigid 변수에 연결시켜준다. 이제 rigid를 이용해 Player의 Rigidbody2D를 사용할 수 있다. 이 때 물리 연산은 FixedUpdate 안에 구현해준다.

FixedUpdate는 물리 연산 프레임마다 호출되는 생명주기 함수

이동하는 방법은 총 크게 3가지로 다음과 같다.

  • 물리적인 힘을 준다
rigid.AddForce(inputVec);
  • 속도를 직접 제어한다
rigid.velocity = inputVec;
  • 해당하는 위치로 바로 이동시킨다.
rigid.MovePosition(rigid.position + inputVec); 

실제 개발 중인 게임에서는 위치 이동 방식으로 플레이어 오브젝트를 이동시킬 것이다. 이 때 따라서 FixedUpdate의 코드는 아래와 같다.

Rigidbody2D rigid;
        
void Awake()
{
	rigid = GetComponent<Rigidbody2D>();
}

void FixedUpdate()
{
	rigid.MovePosition(rigid.position + inputVec);

개선

위의 코드 중 Update와 FixedUpdate는 결국 프레임 단위로 실행되는 함수이며 이는 사용자의 컴퓨터 성능에 따라서 프레임이 높으면 높을수록 더 많이 실행되어 더 빠르게 이동할 것이고 프레임이 낮으면 더 적게 실행되어 더 느리게 이동하는 문제가 발생한다.
따라서 다른 프레임 완경에도 이동 거리는 같아야 한다.
임시적으로 속도 값 조정을 위해 nextVec을 생성한다.
nextVec의 값은 다음과 같이 설정된다.

Vector2 nextVec = inputVec.normalized * speed * Time.fixedDeltaTime;
  • normalized : 벡터 값의 크기가 1이 되도록 좌표를 수정
  • speed : 따로 속도를 지정해줄 변수
  • fixedDeltaTime : 물리 프레임 하나가 소비한 시간
    - DeltaTime : Update 안에서는 fixedDeltaTime 대신 DeltaTime을 사용

위와 같은 과정을 통해 다른 프레임 환경에서도 플레이어 오브젝트가 항상 일정한 속도로 이동할 수 있도록 작성했다.


결과물

profile
Be Honest, Be Harder, Be Stronger
post-custom-banner

0개의 댓글