[Unity]2D게임 Background Scroll(배경 스크롤)

728x90

2D 화면 상 배경 이미지 스크롤 방법

2D 게임을 진행하다보면 배경이 무한 스크롤되는 것을 종종 확인할 수 있다. 유니티에서는 다음 방법으로 배경 스크롤을 간단하게 구현할 수 있다.

배경으로 쓸 2D 소스들을 임포트해주었다. 총 7개의 배경이 간격을 두고 겹쳐보이게 한 후 한쪽 방향으로 흐르게 만들 것이다.

Material을 7개 생성하고 Shader는 Unlit/Transparent로 변경 후 임포트한 배경 Texture을 매핑해주었다. 그리고 씬 뷰에서 Quad를 7개 만들고 Materials에 각각 연결해 준 뒤 하늘 - 구름 - 산 - 돌 순으로 위치를 조정(Z값 이동)해주어 게임 뷰에서는 겹쳐보이도록 만들었다. 그리고 BGScroller라는 빈 오브젝트를 생성 후 7개의 배경을 자식화한 뒤 BGScroller 스크립트를 생성해주었다.

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

[System.Serializable]
public class BGScrollData
{
    public Renderer RenderForScroll;
    public float Speed;
    public float OffsetX;
}

public class BGScroller : MonoBehaviour
{
    [SerializeField]
    BGScrollData[] ScrollDatas;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        UpdateScroll();
    }
    void UpdateScroll()
    {
        for(int i = 0; i < ScrollDatas.Length; i++)
        {
            SetTextureOffset(ScrollDatas[i]);
        }
    }
    void SetTextureOffset(BGScrollData scrollData)
    {
        scrollData.OffsetX += (float)(scrollData.Speed) * Time.deltaTime;
        if (scrollData.OffsetX > 1)
            scrollData.OffsetX = scrollData.OffsetX%1.0f;

        Vector2 Offset = new Vector2(scrollData.OffsetX, 0);

        scrollData.RenderForScroll.material.SetTextureOffset("_MainTex", Offset);
    }
}

BGCScrollData라는 직렬화용 Serializable 클래스를 생성하고 프로그램에 사용할 변수들(Renderer/Speed/OffsetX)을 Public으로 선언해주었다. 그리고 스크립트 직렬화(SerializeField를 통해 외부에서는 접근하지 못하되 인스펙터에서는 접근 가능하도록 ScrollDatas 배열을 생성해주었다. 이 때문에 인스펙터 창에 Scroll Datas가 생겼고 7개의 Element를 생성할 수 있게 되었다. 2D 환경이기 때문에 Vector2에서 x값의 이동되도록, Ofloat형식으로 변환한 ScrollData의 속도에 매 프레임 간 이동(Time.deltaTime)을 곱하여 OffsetX 값을 계산해주었다.  

 

foreach문을 사용해도 되지만 연산량이 많아 효율이 떨어질 수 있다는 단점이 있어 for문을 사용해 background 소스 7개가 전부 UpdateScroll() 되도록 하였다. 약간의 시간차를 두고 각 배경들이 움직이도록 하기 위해 Public으로 선언된 Speed 값을 다음과 같이 설정해주었고, 실행하면 된다.

 

 

 

728x90