Unity - 2D 환경 개발

땡구의 개발일지·2025년 5월 22일

Unity마스터

목록 보기
34/78
post-thumbnail

2D 개요

  • 유니티로 2D 게임을 만드는 것도 가능하다. 3D 환경에서 썼던 컴포넌트들이 대부분 2D 전용으로 따로 있다
  • 간단하게 플랫포머 게임을 구현해보면서 기능들을 익혀보자

Unity 2D

  • UI를 통해서 이미 2D를 접했었다. 평면 상에서 각 오브젝트들의 정렬 우선순위를 설정해서 렌더링 여부를 정할 수 있기 때문에 UGUI를 구성할 때와 비슷하다
  • 추가로 3D 공간이 아닌 평면에서의 각종 기능들을 위해 3D에서 지원했던 기능들이 2D 전용으로 있기도 하다

2D 프로젝트 생성

  • 3D 프로젝트처럼 2D 프로젝트(빌트인 렌더파이프라인)를 생성한다
  • 까먹고 2D 프로젝트로 생성하지 않았으면 패키지 매니저에서 2D 관련 패키지들을 다운 받고, 위와같이 에디터 모드2D 모드로 변경하면 된다

2D 그래픽

구현 원리

  • 기본적으로 스프라이트로 구현된다
  • 2D 프로젝트에는 라이트가 없다. 그래서 3D 오브젝트를 추가해도 입체감이 없다
  • 입체감이 없는 것은 2D인 것이라 당연하겠지만, Perspective 카메라가 아닌 orthographic 카메라를 쓰는 것도 이유다

2D에서의 카메라

  • 이와같이 2D 오브젝트를 생성 해본다
  • 원근감이 없다. 멀리 떨어져 있어도 같은 크기로 보인다. orthographic 카메라이기 때문

라이트

  • 현업에서도 2D 프로젝트에서는 라이트를 쓰지 않는다. 특히 Directional Light 즉, 전역 라이트를 안쓴다
  • 보통 프리 렌더링된 것을 스프라이트 애니메이션으로 만들거나, 포인트 라이트, 스팟 라이트를 활용한다

귀신의 집같은 어두운 배경에 캐릭터 주위만, 또는 주변이 밝은 것은 사실 밝게 하고자 하는 것들을 제외하고 나머지는 어두운 반투명한 텍스쳐를 하나 전체적으로 씌워서 어둡게 하는 것이다

  • 역으로 이런식으로 활용할 수도 있다. 주변의 숨겨진 부분들을 밝히는 방법

  • 이는 카메라 설정에서 원근감이 없는 Orthographic으로 투사하기 때문이다
  • 스카이 박스가 기본적으로 없다
  • 라이트를 쓰려면 2D 라이트를 써야 한다. 최적화를 잘 생각하고 써야 한다

2D 물리처리

  • 리지드바디, 콜라이더2D로 해야 된다
  • 기존의 2D가 안 붙은, 3D용 리지드바디 및 콜라이더를 넣어도 동작은 한다. 다만, 비효율적이기 때문에 2D 전용으로 쓰는 것이 좋다

콜라이더

  • 2D 콜라이더들의 종류다

Polygon collider

  • 2D에만 있는 콜라이더. 폴리곤으로 콜라이더를 적용할 수 있다. 편집이 자유롭다

Composite collider

  • 하나의 상위 오브젝트에 이 콜라이더를 추가하고, 자식이 될 게임 오브젝트들의 콜라이더 옵션에서 Used By Composite를 체크한다
  • 콜라이더를 이제 하위 오브젝트가 아닌 상위 오브젝트에서 다루게 되고, 겹칠 경우 위와 같이 콜라이더가 합체한다
  • 하위에 만들어진 콜라이더들을 하나로 관리하고자 할 때 사용한다

Edge collider

  • 만들면 콜라이더를 만들기 위한 이 하나 나온다. 선의 중간 부분 중 아무데나 원하는 지점에서 끌어가면서 콜라이더를 만들 수 있다
  • 열린 콜라이더로 구덩이 같은 곳에 적용 시킬 수 있다

Custom collider

  • Custom Shape Count, Custom Vertex Count 에 의해 조절되는 콜라이더다. Sprite Shape Controller에 의해서 조절이 가능하며, 정교한 콜라이더를 구현하고자 할 때 사용한다
  • 근데 사용하기 매우 까다로운 편이라, 보통은 Polygon collider를 쓰는 편이라고 한다

세부 기능 설명

  • Auto Tiling : 타일 맵에서 쓰는 기능이다. 주변의 콜라이더들과 자동으로 합쳐준다
  • Used By Effector : 이펙터를 사용하는 경우 체크해야된다
  • Used By Composite : 컴포지트 콜라이더를 사용할 때 체크한다

플레이어 구현

PlayerController

  • 이동과 점프를 구현한다
public class PlayerController : MonoBehaviour
{
    [field: Header("Set Value")]
    [field: SerializeField] private float moveSpeed { get; set; }
    [field: SerializeField] private float jumpPower { get; set; }
    
    // 연속점프를 막기 위한 상태 패턴
    private enum PlayerState { Ground, Air }
    private PlayerState playerState { get; set; }

    // 리지드바디2D 사용
    private Rigidbody2D rig;
    // 인풋은 Vector2면 충분
    private float inputX;
    // 점프 구현

    private void Start()
    {
        rig = GetComponent<Rigidbody2D>();
        inputX = 0f;
        playerState = PlayerState.Ground;
    }
    private void Update()
    {
        PlayerInput();
    }
    private void FixedUpdate()
    {
        PlayerMove();
    }
    private void PlayerInput()
    {
        // 2D 환경에서도 position은 Vector3로 나온다
        inputX = Input.GetAxis("Horizontal");

        if (Input.GetKeyDown(KeyCode.UpArrow) && playerState == PlayerState.Ground)
        {
            PlayerJump();
        }
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.layer == 6)
        {
            playerState = PlayerState.Ground;
        }
    }
    private void PlayerMove()
    {
        rig.velocity = new Vector2(inputX * moveSpeed, rig.velocity.y);
    }
    private void PlayerJump()
    {
        // Vector2와 ForceMode2D를 잊지말고 써줘야 한다
        rig.AddForce(Vector2.up * jumpPower, ForceMode2D.Impulse);
        playerState = PlayerState.Air;
    }
}

  • transform 자체는 2D 환경에서도 Vector3들로 이루어져 있기 때문에, transform.positionVector3로 나온다. 사용하려면 Vector2로 변환해주는 과정이 필요하다

이펙터 2D

  • 플랫폼 또는 장애물로 사용하고자 하는 게임 오브젝트에 물리적인 속성을 부여한다
  • 단독으로 사용 되지는 않고, 콜라이더와 함께 사용된다

플랫폼 이펙터

  • 말 그대로 플랫폼으로 사용되는 오브젝트에 사용하는 이펙터다. 설정으로 다른 오브젝트들이 충돌을 할 수 있는 경우들을 설정해줄 수 있다
  • 이렇게 아래에서는 점프해도 위로 가지 못하는 오브젝트에 플랫폼 이펙터를 추가해본다
  • Use One Way에 체크한다
  • Use One Way : 한 곳에서만 통과가 되게 설정 가능
  • Rotationl Offset : 입장 구역의 각도 조절이 가능
  • Surface Arc : 입장 가능한 각도 조절 가능
  • Sides 에서 Side Arc를 설정하면, 사이드에서도 충돌 처리가 가능해진다
  • 콜라이더에서는 Used By Effector를 체크 해줘야 한다
  • 이렇게 입장(충돌)이 가능한 각도가 표기된다
  • 한 쪽에서만 입장(충돌)이 가능해졌다

서페이스 이펙터

  • 공장의 레일을 깔아줄 수 있다. 탄젠트 포스로 구현된다
  • Force Scale : 1로 맞춰두는 것을 추천한다
  • 실행해도 플레이어는 위에서 움직이지 않는다. PlayerController 스크립트 때문. 입력이 없을 경우 rigidbody.velocity.magnitude = 0 이기 때문이다
  • 어떻게 이펙터에서 오는 힘을 플레이어 스피드에 적용하는 방법은 고민이 필요하다

포인트 이펙터

  • 자성을 띈다. 중력처럼 사용할 수 있다
  • 콜라이더의 Is Trigger에 체크를 해줘야 한다
  • Force Magnitude : 가해지는 힘의 크기(뉴턴단위). 양수면 밀어내기, 음수면 끌어당기기
  • Force Variation : 랜덤 힘 변화. 음수면 반대 방향의 힘도 줌
  • Distance Scale : Distance Scale/거리 형식으로 힘의 크기가 줄어든다. 즉, 거리가 멀 수록 힘이 줄어든다

자세한 설명

  • F = Force Magnitude ×(1distance)DistanceScale\times (\frac{1}{distance})^{Distance Scale}

  • Distance Scale = 0: 거리와 무관하게 힘이 일정 (즉, 거리에 영향을 안 받음)

  • Distance Scale = 1: 힘이 1거리\frac{1}{거리}로 줄어듬 (기본적인 감쇠)

  • Distance Scale = 2: 힘이 (1거리)2(\frac{1}{거리})^2로 멀 수록 더 빠르게 줄어듬

  • Distance Scale > 1: 가까울수록 훨씬 강한 힘, 멀수록 훨씬 약한 힘

  • Distance Scale < 1: 멀리까지도 비교적 강한 힘을 유지

예시

  • Force Magnitude = 100
  • Distance Scale = 2
  • 거리 = 2 (units)
  • 힘 = 100×122=100×0.25=25N100 \times \frac{1}{2}^2 = 100 \times 0.25 = 25N

  • 이펙터의 영향을 받으려면, 이펙터의 콜라이더 안에 들어와야 한다

에이리어 이펙터

  • 바람이 분다라고 생각 하면 된다. 부유하는 지역으로 만들 수 있다
  • Is Trigger 체크를 해줘야 한다
  • Force Angle : 바람이 적용되는 각도다. 90이 윗 방향이다

부오얀시 이펙터

  • 부표. 바다 위에 있는 듯한 느낌을 만들어 줄 수 있다
  • Density : 물의 밀도
  • Surface Level : 해수면
  • Flow Angle : 물이 흐르는 각도. 90이면 위로 흐른다
  • Flow Magnitude : 흐르는 세기. 해류 속도

주의

  • 콜라이더 안쪽에서만 힘이 작용하기 때문에, 콜라이더를 크게 잡고 그 안에 해수면 높이를 위치 시키는 것이 좋다

참고

  • 두 개 이상의 이펙터를 같은 오브젝트에 달 수는 없다. 만약, 적용하고 싶다면 빈 오브젝트를 만들어서 기존 오브젝트의 콜라이더와 동일한 크기의 콜라이더를 만들고, 겹쳐서 새로 이펙터를 달자

씨네머신 활용

  • 2D 플랫포머 게임처럼 카메라가 플레이어를 따라 다니게 해보자. 화면의 가장자리에서 더 이상 움직이지 않게 할 수도 있다
  • 가상 카메라로 플레이어를 Follow 할 경우, 위와 같이 맵의 끝에서도 플레이어가 중심에 있다. 맵의 끝에서는 더이상 카메라가 스크롤 되지 않게 해보자

가상 카메라

  • 가상 카메라 추가 후 follow에 플레이어를 참조

Confiner

  • 카메라가 움직일 수 있는 범위를 바운딩을 해 줘야 한다. 가상 카메라에서 Add Extension을 눌러 Confiner 2D를 추가한다

  • Bounding Shape 2D에는 Polygon Collider 2D, Composite Collider 2D 둘 중 하나가 들어가야 한다

바운드 추가

  • Composite Collider 2D로 바운딩을 해보자

  • 먼저 빈 오브젝트를 추가한다. 이름은 Bound로 한다. 컴포넌트로 Composite Collider 2D를 추가한다. Rigidbody 2D가 자동으로 추가된다

  • Gravity Scale이 1 이라서 바운드 설정한 것을 넣고, 실행하면 카메라가 중력의 영향을 받아 밑으로 떨어진다. 0으로 바꾸기 보다 Constraints를 설정하자

  • 리지드바디는 Constraints 설정, 콜라이더는 Is Trigger를 체크, Geometry TypePolygons로 변경해준다

Geometry Type

  • 폴리곤은 물리 계산 시 이점이 있다
  • 아웃라인은 벽타기, 경계이동, 타일맵, 지형을 만드는 경우에 이점이 있다

  • 하위 오브젝트로 빈 오브젝트를 추가, Box Collider 2D를 추가한다. Used By Composite를 체크한다
  • 그리고 맵의 크기만큼 콜라이더 크기를 키운다
  • 이제 완성된 바운드를 가상 카메라컨파이너에 참조시킨다
  • 가상 카메라가 제한이 된 것을 볼 수 있다
  • 지정한 바운드 이상은 카메라가 따라오지 않는다

플레이어 위치 변경

  • 플레이어를 카메라 상에서 왼쪽 아래로 배치하려면 아래와 같이 설정한다
  • Tracked Object Offset을 변경해주면 된다
  • 위의 설정을 통해 플레이어를 카메라가 따라가는 타이밍을 정해줄 수 있다
profile
개발 박살내자

0개의 댓글