Unity / C#
Beginner
Unity 2021.3+ / Unity 6
2D 패럴랙스 스크롤링(Parallax Scrolling) 다중 배경과 무한 루프 재배치
카메라 이동량에 따른 Z-깊이별 레이어 상대 속도 연산, 뷰포트 경계를 벗어난 타일 배경의 무한 랩핑(Infinite Wrapping) 구현.
#Unity #2D #Parallax #Background #Camera #Environment
핵심 개념2D 횡스크롤 게임에서 입체감을 부여하는 가장 효율적인 방법은 원거리 배경(산, 구름)은 천천히 움직이고 근경(가로등, 풀숲)은 빠르게 움직이게 하는 패럴랙스 스크롤링(Parallax Scrolling)입니다. 스프라이트의 가로 폭을 측정해 카메라가 지나갈 때마다 위치를 스냅해 주면 무한 맵 배경이 완성됩니다.
1. 무한 패럴랙스 레이어 스크립트
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.99 | 0.98 | Background_Sky |
| 원거리 (먼 산, 빌딩 숲) | 0.70 ~ 0.85 | 0.50 | Background_Distant |
| 중거리 (나무, 울타리) | 0.40 ~ 0.60 | 0.20 | Background_Mid |
| 플레이어 활동 지형 | 0.00 (직접 이동) | 0.00 | Default / Ground |
| 근경 (전방 풀숲, 가로등) | -0.20 ~ -0.40 | -0.10 | Foreground |
3. 렌더링 최적화 팁
Draw Mode = Tiled활용: 텍스처 임포트 설정에서Wrap Mode = Repeat로 설정하고 SpriteRenderer의Draw Mode를Tiled로 지정하면 단일 스프라이트로 넓은 영역을 깔끔하게 채울 수 있습니다.LateUpdate필수: 패럴랙스 연산을Update에서 실행하면 카메라 추적과 프레임 타이밍이 어긋나 배경 스프라이트 경계면에 1픽셀짜리 검은 틈새가 벌어지는 현상이 발생합니다.