게임 개발 일지/유니티 엔진 공부

30. 유니티 2D 종스크롤 슈팅 - 무한 배경 만들기

인텔리킴 2024. 6. 3. 18:57

준비

나란히 정렬

먼저 무한맵처럼 보이기 위해 나란히 Y축으로 정렬

 

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

public class Background : MonoBehaviour
{
    public float speed;
    void Update()
    {
        Vector3 curPos = transform.position;
        Vector3 nextPos = Vector3.down * speed * Time.deltaTime;
        transform.position = curPos + nextPos;
    }
}

기본적인 이동 구현 : 방향 * 스피드 * 델타타임

 

카메라 인스펙터

* Camera View 높이 = Size * 2

 

카메라에서 벗어난 배경을 다시 맨 위로 올려서 재활용하는 방식으로 무한맵 구현

= 스크롤링 기법

스크롤링 기법

void Awake()
{
    viewHeight = Camera.main.orthographicSize * 2;    
}
void Update()
{
    Vector3 curPos = transform.position;
    Vector3 nextPos = Vector3.down * speed * Time.deltaTime;
    transform.position = curPos + nextPos;

    if (sprites[endIndex].position.y < viewHeight * (-1))
    {
        //스프라이트 재활용
        //맨 위에 있는 스프라이트 인덱스 위치
        Vector3 backSpritePos = sprites[startIndex].localPosition;
        //맨 밑에 있는 스프라이트 인덱스 위치
        Vector3 frontSpritePos = sprites[endIndex].localPosition;
        //맨 밑에 있는 스프라이트를 맨 위로 올림
        sprites[endIndex].transform.localPosition = backSpritePos + Vector3.up * viewHeight;

        // 커서 인덱스 체인지
        int startIndexSave = startIndex;
        //
        startIndex = endIndex;
        //배열을 넘어가지 않도록 예외처리
        endIndex = (startIndexSave -1 == -1) ? sprites.Length-1 : startIndexSave - 1;
    }
}

* localPosiotion : 부모의 Position을 기준으로 삼은 지역 포지션

EndIndex 스프라이트를 StartIndex 뒤로 이동

* orthographicSize : orthographic 카메라 Size

orthographicSize * 2 = 카메라의 실제 높이(사이즈)

이동이 완료되면 EndIndex, StartIndex를 갱신해야함

 

* 후위 연산자는 해당 라인이 끝난 후에 연산 적용하므로 사용 x

 

패럴랙스

원근감을 살리기

 

Parallax : 멀리있는것은 느리게, 가까이 있는것은 빠르게 움직이게 하는 기술

 

서로 속도 다르게 적용

 

이 기법은 플랫포머에서도 많이 사용함

 

서로 다른 속도로 스크롤링

 

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

public class Background : MonoBehaviour
{
    public float speed;
    public int startIndex;
    public int endIndex;
    public Transform[] sprites;

    float viewHeight;
    void Awake()
    {
        viewHeight = Camera.main.orthographicSize * 2;    
    }
    void Update()
    {
        Move();
        Scrolling();
    }

    void Move()
    {
        Vector3 curPos = transform.position;
        Vector3 nextPos = Vector3.down * speed * Time.deltaTime;
        transform.position = curPos + nextPos;
    }

    void Scrolling()
    {
        if (sprites[endIndex].position.y < viewHeight * (-1))
        {
            //스프라이트 재활용
            //맨 위에 있는 스프라이트 인덱스 위치
            Vector3 backSpritePos = sprites[startIndex].localPosition;
            //맨 밑에 있는 스프라이트 인덱스 위치
            Vector3 frontSpritePos = sprites[endIndex].localPosition;
            //맨 밑에 있는 스프라이트를 맨 위로 올림
            sprites[endIndex].transform.localPosition = backSpritePos + Vector3.up * viewHeight;

            // 커서 인덱스 체인지
            int startIndexSave = startIndex;
            //
            startIndex = endIndex;
            //배열을 넘어가지 않도록 예외처리
            endIndex = (startIndexSave - 1 == -1) ? sprites.Length - 1 : startIndexSave - 1;
        }
    }
}

함수로 나눠서 코드 적용