193 lines
5.7 KiB
C#
193 lines
5.7 KiB
C#
using UnityEngine;
|
|
|
|
// 왼쪽 끝으로 이동한 배경을 오른쪽 끝으로 재배치하는 스크립트
|
|
[ExecuteAlways]
|
|
public class BackgroundLoop : MonoBehaviour {
|
|
public Sprite[] backgroundSprites; // 순서대로 교체할 공항 배경 스프라이트
|
|
public bool useResourceBackground = true; // Resources 폴더의 맵 배경을 자동으로 사용
|
|
public string resourceBackgroundPath = ""; // 맵 데이터가 없을 때 사용할 Resources 배경
|
|
public int startSpriteIndex = 0; // 이 배경 오브젝트가 시작할 스프라이트 번호
|
|
public int spriteAdvanceOnLoop = 2; // 배경 오브젝트가 두 장이므로 재배치될 때 두 칸씩 진행
|
|
|
|
private static string activeResourceBackgroundPath = "";
|
|
|
|
private float width; // 배경의 가로 길이
|
|
private int currentSpriteIndex; // 현재 표시 중인 스프라이트 번호
|
|
private SpriteRenderer spriteRenderer; // 배경을 표시하는 스프라이트 렌더러
|
|
private BoxCollider2D backgroundCollider; // 루프 폭 계산용 콜라이더
|
|
private Sprite[] originalBackgroundSprites; // 맵 배경 리소스가 없을 때 되돌릴 기본 배경
|
|
private bool originalBackgroundSpritesCached = false;
|
|
|
|
public static void ApplyResourceBackground(string resourcePath) {
|
|
activeResourceBackgroundPath = resourcePath;
|
|
|
|
BackgroundLoop[] backgroundLoops = FindObjectsByType<BackgroundLoop>(FindObjectsSortMode.None);
|
|
for(int i = 0; i < backgroundLoops.Length; i++)
|
|
{
|
|
if(backgroundLoops[i] != null)
|
|
{
|
|
backgroundLoops[i].InitializeBackground();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Awake() {
|
|
InitializeBackground();
|
|
}
|
|
|
|
private void OnEnable() {
|
|
InitializeBackground();
|
|
}
|
|
|
|
private void OnValidate() {
|
|
InitializeBackground();
|
|
}
|
|
|
|
private void Update() {
|
|
if(!Application.isPlaying)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 현재 위치가 원점에서 왼쪽으로 width 이상 이동했을때 위치를 리셋
|
|
if(transform.position.x <= -width)
|
|
{
|
|
Reposition();
|
|
}
|
|
}
|
|
|
|
private void InitializeBackground() {
|
|
CacheComponents();
|
|
CacheOriginalBackgroundSprites();
|
|
EnsureResourceBackground();
|
|
|
|
currentSpriteIndex = NormalizeSpriteIndex(startSpriteIndex);
|
|
ApplyBackgroundSprite(currentSpriteIndex);
|
|
SyncColliderSize();
|
|
RefreshWidth();
|
|
}
|
|
|
|
private void CacheComponents() {
|
|
if(spriteRenderer == null)
|
|
{
|
|
spriteRenderer = GetComponent<SpriteRenderer>();
|
|
}
|
|
|
|
if(backgroundCollider == null)
|
|
{
|
|
backgroundCollider = GetComponent<BoxCollider2D>();
|
|
}
|
|
}
|
|
|
|
private void EnsureResourceBackground() {
|
|
if(!useResourceBackground)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string finalResourcePath = !string.IsNullOrEmpty(activeResourceBackgroundPath)
|
|
? activeResourceBackgroundPath
|
|
: resourceBackgroundPath;
|
|
|
|
if(string.IsNullOrEmpty(finalResourcePath))
|
|
{
|
|
backgroundSprites = originalBackgroundSprites;
|
|
return;
|
|
}
|
|
|
|
Sprite resourceSprite = Resources.Load<Sprite>(finalResourcePath);
|
|
if(resourceSprite == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(backgroundSprites != null && backgroundSprites.Length == 1 && backgroundSprites[0] == resourceSprite)
|
|
{
|
|
return;
|
|
}
|
|
|
|
backgroundSprites = new Sprite[] { resourceSprite };
|
|
}
|
|
|
|
private void CacheOriginalBackgroundSprites() {
|
|
if(originalBackgroundSpritesCached)
|
|
{
|
|
return;
|
|
}
|
|
|
|
originalBackgroundSprites = backgroundSprites;
|
|
originalBackgroundSpritesCached = true;
|
|
}
|
|
|
|
private void RefreshWidth() {
|
|
if(spriteRenderer != null && spriteRenderer.sprite != null)
|
|
{
|
|
width = spriteRenderer.bounds.size.x;
|
|
return;
|
|
}
|
|
|
|
if(backgroundCollider != null)
|
|
{
|
|
width = backgroundCollider.size.x * Mathf.Abs(transform.lossyScale.x);
|
|
return;
|
|
}
|
|
|
|
width = 0f;
|
|
}
|
|
|
|
private void SyncColliderSize() {
|
|
if(spriteRenderer == null || spriteRenderer.sprite == null || backgroundCollider == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector2 spriteSize = spriteRenderer.sprite.bounds.size;
|
|
backgroundCollider.size = spriteSize;
|
|
backgroundCollider.offset = Vector2.zero;
|
|
backgroundCollider.isTrigger = true;
|
|
}
|
|
|
|
// 위치를 리셋하는 메서드
|
|
private void Reposition() {
|
|
Vector2 offset = new Vector2(width * 2f, 0);
|
|
transform.position = (Vector2) transform.position + offset;
|
|
|
|
currentSpriteIndex = NormalizeSpriteIndex(currentSpriteIndex + spriteAdvanceOnLoop);
|
|
ApplyBackgroundSprite(currentSpriteIndex);
|
|
SyncColliderSize();
|
|
RefreshWidth();
|
|
}
|
|
|
|
private int NormalizeSpriteIndex(int index) {
|
|
if(backgroundSprites == null || backgroundSprites.Length == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int normalizedIndex = index % backgroundSprites.Length;
|
|
|
|
if(normalizedIndex < 0)
|
|
{
|
|
normalizedIndex += backgroundSprites.Length;
|
|
}
|
|
|
|
return normalizedIndex;
|
|
}
|
|
|
|
private void ApplyBackgroundSprite(int index) {
|
|
if(spriteRenderer == null || backgroundSprites == null || backgroundSprites.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Sprite backgroundSprite = backgroundSprites[index];
|
|
|
|
if(backgroundSprite != null)
|
|
{
|
|
spriteRenderer.enabled = true;
|
|
spriteRenderer.sprite = backgroundSprite;
|
|
spriteRenderer.color = Color.white;
|
|
}
|
|
}
|
|
}
|