TOOLS GAMES DEVLOG DOCS ABOUT CONTACT
HOME > DOCS > Unity / C# > 2D 패럴랙스 스크롤링(Parallax Scrolling) 다중 배경과 무한 루프 재배치
Unity / C# Beginner Unity 2021.3+ / Unity 6

2D 패럴랙스 스크롤링(Parallax Scrolling) 다중 배경과 무한 루프 재배치

카메라 이동량에 따른 Z-깊이별 레이어 상대 속도 연산, 뷰포트 경계를 벗어난 타일 배경의 무한 랩핑(Infinite Wrapping) 구현.

#Unity #2D #Parallax #Background #Camera #Environment
핵심 개념2D 횡스크롤 게임에서 입체감을 부여하는 가장 효율적인 방법은 원거리 배경(산, 구름)은 천천히 움직이고 근경(가로등, 풀숲)은 빠르게 움직이게 하는 패럴랙스 스크롤링(Parallax Scrolling)입니다. 스프라이트의 가로 폭을 측정해 카메라가 지나갈 때마다 위치를 스냅해 주면 무한 맵 배경이 완성됩니다.

1. 무한 패럴랙스 레이어 스크립트

ParallaxLayer.cs
using UnityEngine;

public class ParallaxLayer : MonoBehaviour
{
    [Tooltip("0 = 카메라와 완전 동기화(먼 배경), 1 = 완전히 정지")]
    [SerializeField] private Vector2 parallaxEffectMultiplier = new Vector2(0.5f, 0.1f);
    [SerializeField] private bool infiniteHorizontal = true;

    private Transform _cameraTransform;
    private Vector3 _lastCameraPosition;
    private float _textureUnitSizeX;

    private void Start()
    {
        if (Camera.main != null)
            _cameraTransform = Camera.main.transform;

        _lastCameraPosition = _cameraTransform.position;

        // 스프라이트 렌더러의 가로 크기 측정
        SpriteRenderer sprite = GetComponent<SpriteRenderer>();
        if (sprite != null)
        {
            _textureUnitSizeX = sprite.bounds.size.x;
        }
    }

    private void LateUpdate()
    {
        if (_cameraTransform == null) return;

        Vector3 deltaMovement = _cameraTransform.position - _lastCameraPosition;

        // 카메라 이동량에 효과 배율 적용
        transform.position += new Vector3(
            deltaMovement.x * parallaxEffectMultiplier.x,
            deltaMovement.y * parallaxEffectMultiplier.y,
            0f
        );

        _lastCameraPosition = _cameraTransform.position;

        // 무한 가로 루프 처리
        if (infiniteHorizontal && _textureUnitSizeX > 0f)
        {
            float offsetFromCamera = _cameraTransform.position.x - transform.position.x;

            if (Mathf.Abs(offsetFromCamera) >= _textureUnitSizeX)
            {
                float offsetPositionX = (offsetFromCamera > 0) ? _textureUnitSizeX : -_textureUnitSizeX;
                transform.position = new Vector3(transform.position.x + offsetPositionX, transform.position.y, transform.position.z);
            }
        }
    }
}

2. 다중 레이어 깊이 권장 계수

레이어 종류X 패럴랙스 계수Y 패럴랙스 계수스프라이트 Sorting Layer
초원거리 (달, 먼 하늘)0.95 ~ 0.990.98Background_Sky
원거리 (먼 산, 빌딩 숲)0.70 ~ 0.850.50Background_Distant
중거리 (나무, 울타리)0.40 ~ 0.600.20Background_Mid
플레이어 활동 지형0.00 (직접 이동)0.00Default / Ground
근경 (전방 풀숲, 가로등)-0.20 ~ -0.40-0.10Foreground

3. 렌더링 최적화 팁

  • Draw Mode = Tiled 활용: 텍스처 임포트 설정에서 Wrap Mode = Repeat로 설정하고 SpriteRenderer의 Draw Mode를 Tiled로 지정하면 단일 스프라이트로 넓은 영역을 깔끔하게 채울 수 있습니다.
  • LateUpdate 필수: 패럴랙스 연산을 Update에서 실행하면 카메라 추적과 프레임 타이밍이 어긋나 배경 스프라이트 경계면에 1픽셀짜리 검은 틈새가 벌어지는 현상이 발생합니다.

참고자료 & 관련 링크