Unity - 2D 종스크롤 슈팅 : 플레이어 이동 구현하기

TXMAY·2023년 9월 20일
0

Unity 튜토리얼

목록 보기
21/33
post-thumbnail

학교에서 계속 시간을 보내던 찰나, 당장 아무것도 하는 게 없어 뭐라도 해야겠다고 생각했다.
그래서 원래는 예전에 GMS2로 만들었던 MO/VE라는 게임을 유니티로 리메이크해 보려 했다.
마침 유니티는 에셋 스토어도 있어서 그래픽적인 부분도 더 개선할 수 있다고 생각하여 쓸만한 에셋을 찾고 있었는데

이전에 봤던 골드메탈님의 강의 중 종 스크롤 2D 슈팅 에셋 팩을 보았다.
마침 MO/VE의 장르도 2D 탄막 게임이라(횡 스크롤이긴 하지만) 이걸 사용해볼까 했는데

마침 강좌 영상도 있었다.
전에 플랫포머 게임 강좌를 보면서 만들어 봤지만, 아직 유니티 실력이 좋지는 않기 때문에 이번에도 강좌를 보면서 학습한 후 MO/VE를 리메이크해 보려 한다.


준비하기

우선 에셋 스토어에서 에셋을 받은 다음 'Player' 스프라이트를 다음과 같이 설정한다. (대부분은 기본적으로 설정이 될 테지만, 에디터 버전이나 예외로 설정이 다를 수 있다)

  • Sprite Mode : Multiple
  • Pixels Per Unit : 24
  • Filter Mode : Point (no filter)
  • Compression : None

그리고 스프라이트 에디터에 들어가서 다음과 같이 설정한다. (이것 또한 기본적으로 설정이 되어 있다)

  • Type : Grid By Cell Size
  • Pixel Size : 24
  • Padding : 1

설정한 후, 스프라이트를 드래그하여 배치한다.

플레이어 이동

'Player.cs' 파일을 생성한 후, 다음과 같이 코드를 작성한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    public float speed;

    void Update()
    {
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");
        Vector3 curPos = transform.position;
        Vector3 nextPos = new Vector3(h, v, 0) * speed * Time.deltaTime;

        transform.position = curPos + nextPos;
    }
}

플레이어 오브젝트에 파일을 놓고 speed를 설정한 후, 실행하면 방향키로 움직일 수 있다.

해상도 조절

종스크롤 게임을 하기에는 지금 창은 너무 가로로 크다.
그렇기에 해상도를 변경해 주겠다.
Game창에 가면 'Free Aspect'라는 창이 있다.
Free Aspect : 자유 비율 (카메라 크기 = Game 뷰 크기)
창을 클릭한 후, 아래에 +버튼을 눌러 다음과 같이 작성하고 추가한다.

  • Label : Mobile
  • Type : Aspect Ratio
  • Width & Height : 9/16

그러면 게임 창이 9:16의 비율로 고정되게 된다.

경계 설정

플레이어를 이동하면 카메라 밖으로도 나갈 수 있다.
밖으로 나가지 못하게 경계를 설정하겠다.
빈 오브젝트를 생성하고 이름을 'Border'로 바꿔준다.
그리고 똑같이 빈 하위 오브젝트 4개를 생성하고 Box Collider 2D를 넣어준다.
그리고 길이를 조절해 상하좌우 한 방향씩 카메라 경계에 배치한다.
플레이어 오브젝트에 Box Collider 2D와 Rigidbody 2D를 추가하고 Gravity Scale을 0으로 설정한다.
Border 하위 오브젝트들도 Rigidbody 2D를 추가하고 Rigidbody 2D의 'Body Type'을 'Static'으로 설정한다.
플레이어를 이동하면 설정한 경계 밖으로 나가지는 않지만 떨림이 심하다.
transform 이동 + 물리 충돌은 떨림 현상이 발생한다.

경계 충돌 로직

그렇기에 코드로 경계를 구현하겠다.
Player.cs에 다음과 같이 코드를 추가한다.

...

public bool isTouchTop;
public bool isTouchBottom;
public bool isTouchLeft;
public bool isTouchRight;

void Update()
{
    ...
    
    if ((isTouchRight && h == 1) || (isTouchLeft && h == -1))
    {
        h = 0;
    }
    ...
    
    if ((isTouchTop && v == 1) || (isTouchBottom && v == -1))
    {
        v = 0;
    }
    ...
    
}

void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.gameObject.tag == "Border")
    {
        switch (collision.gameObject.name)
        {
            case "Top":
                isTouchTop = true;
                break;
            case "Bottom":
                isTouchBottom = true;
                break;
            case "Left":
                isTouchLeft = true;
                break;
            case "Right":
                isTouchRight = true;
                break;
        }
    }
}
void OnTriggerExit2D(Collider2D collision)
{
    if (collision.gameObject.tag == "Border")
    {
        switch (collision.gameObject.name)
        {
            case "Top":
                isTouchTop = false;
                break;
            case "Bottom":
                isTouchBottom = false;
                break;
            case "Left":
                isTouchLeft = false;
                break;
            case "Right":
                isTouchRight = false;
                break;
        }
    }
}

그리고 하위 오브젝트에 'Border'라는 태그를 추가하고 Player 오브젝트에 Is Trigger를 활성화한다.
그러면 떨림 현상 없이 경계가 잘 작동한다.

애니메이션

지난 플랫포머 강좌와 똑같이 애니메이션을 추가하고 다음과 같이 코드를 추가한다.

Animator anim;

void Awake()
{
    anim = GetComponent<Animator>();
}

void Update()
{
    ...
    
    if(Input.GetButtonDown("Horizontal")||Input.GetButtonUp("Horizontal"))
    {
        anim.SetInteger("Input", (int)h);
    }
}
...

그리고 이미지 파일 중 'Background Grid'를 추가한다.


오랜만에 해보는 거라 걱정됐지만 처음보다는 나름 능숙해진 것 같다.

profile
게임 개발 공부하는 고양이

0개의 댓글