무한 스크롤 배경화면 (Unity)

장민제·2025년 5월 6일

내일배움캠프

목록 보기
18/41

🔁 무한 스크롤 구현하기

개인과제로 진행하는 메타버스 만들기 프로젝트에서 미니게임으로 FlappyBird와 같은 게임을 만들어보았다.
플레이어가 이동하는 것이 아닌 배경이 움직이는 것으로 구현해보고자 하였고,
장애물들을 일정 거리마다 반복 재배치하여 무한히 스크롤되는 느낌을 주는 구조를 구현해보았다.

[SerializeField] Obstacle[] obstacles;
[SerializeField] float scrollSpeed = 3f;

[SerializeField] int startIdx_Ob; // 오른쪽 끝
[SerializeField] int endIdx_Ob = 0;

private float camWidth;

void Start()
{
	// 오른쪽 끝 인덱스
    startIdx_Ob = obstacles.Length - 1;
	
    camWidth = Camera.main.orthographicSize;

    Vector3 lastObstacle = Vector3.zero;
    
    // 장애물 초기 배치
    foreach (var ob in obstacles)
    {
        lastObstacle = ob.SetRandomPosition(lastObstacle);
    }
}

void Update()
{
    if (isGameOver) return;

    foreach (Obstacle ob in obstacles)
    {
        ob.transform.Translate(Vector3.left * scrollSpeed * Time.deltaTime);
    }
    
    ScrollObstacles();
}

void ScrollObstacles()
{
	 // 제일 왼쪽에 있는 장애물이 카메라의 범위를 벗어나면 이동
    if (obstacles[endIdx_Ob].transform.position.x < -camWidth)
    {
        Vector3 frontPos = obstacles[startIdx_Ob].transform.localPosition;
        obstacles[endIdx_Ob].SetRandomPosition(frontPos);
		
        int pre_startIndex = startIdx_Ob;
        startIdx_Ob = endIdx_Ob;
        
        // 인덱스가 범위를 벗어나면 다시 범위 안으로 조정
        endIdx_Ob = pre_startIndex - 1 == -1 ? obstacles.Length - 1 : pre_startIndex - 1;
    }
}

장애물은 계속해서 왼쪽으로 이동하게 하고,
제일 왼쪽 끝에 있는 장애물은 endIdx_Ob 오른쪽 끝을 startIdx_Ob로 설정하고 카메라의 범위를 벗어나면 다시 오른쪽 끝으로 배치하는 방식으로 구현을 하였다.

🧩 문제 발생

그런데 여기서 장애물이 3개일 때는 잘 반복하던 코드가 4개 이상이 되자 순차적으로 진행되지않는 현상이 발생하였다.

인덱스 계산이 꼬이면서 순환 순서가 어긋나게 되버린 것이다.

int pre_startIndex = startIdx_Ob;
startIdx_Ob = endIdx_Ob;
        
// 인덱스가 범위를 벗어나면 다시 범위 안으로 조정
endIdx_Ob = pre_startIndex - 1 == -1 ? obstacles.Length - 1 : pre_startIndex - 1;

문제는 이 부분에서 인덱스를 지정해주는 부분이 문제였다.

가장 왼쪽에 있는 장애물이 카메라의 범위를 벗어났을 때 0번 인덱스 장애물이 startIdx_Ob (가장 오른쪽) 장애물이 되고 1번 장애물이 다음 endIdx_Ob(가장 왼쪽) 인덱스가 되어야하는데 3번 인덱스가 다음 endIdx_Ob 장애물이 되어버리며 문제가 발생.

😁 문제 해결

먼저 가독성을 위해 인덱스 변수의 이름을 leftIdx_ObrightIdx_Ob로 바꿔 주었다.

void ScrollObstacles()
{
    if (obstacles[leftIdx_Ob].transform.position.x < -camWidth)
    {
        Vector3 frontPos = obstacles[rightIdx_Ob].transform.localPosition;
        obstacles[leftIdx_Ob].SetRandomPosition(frontPos);

        int pre_leftIndex = leftIdx_Ob;
        rightIdx_Ob = leftIdx_Ob;
        leftIdx_Ob = pre_leftIndex + 1 > obstacles.Length - 1 ? 0 : pre_leftIndex + 1;
    }
}

그런 후 인덱스의 순환을 왼쪽부터 하나하나 순환하도록 수정해주었다.
가장 왼쪽에 있는 인덱스를 하나씩 증가시켜주고 최대 길이를 넘게되면 다시 처음으로 돌아오는 식으로 구현하였다.

처음에 왜 역방향으로 생각하고 작성했는지 잘 기억이 나지 않는다...
어찌됐든 해결하고 앞으로 다시는 저러지 않아야 겠다고 다짐을 하는 오늘이다.!

profile
Unity, C#

0개의 댓글