[타워디펜스게임] #1. 로딩창 구현

치치·2024년 11월 12일
0

타워디펜스게임

목록 보기
1/18
post-thumbnail

읽고 가주세요! 😊

코딩을 배우고, 미숙한 상태로 처음 만들어본 게임입니다.
기획자 한분과 사운드 한분과 프로그래밍 저, 이렇게 3명이서 만든 작품입니다.
많은 시행착오가 있었고, 저 또한 코드를 짜면서 막혔던 부분이 많았습니다.
그래서 이 글을 읽으시면, 코드가 깔끔하지 못하고 아쉬운 부분이 많습니다.
그래도 처음 만들었고, 정말 많이 노력해서 만들었습니다. 강의도 많이 듣고, 질문도 많이하고, 외국인 강의도 들어보고, 챗지피티의 도움도 받고, 기획자와의 상의도 많이 거쳐서 만들어 낸 작품입니다.
부디 잘 봐주시면 감사합니다! 피드백 받습니다!

https://youtu.be/qr9vnbdCm0k

1. 타이틀 씬

2. 로딩씬

3. 게임 씬

[빌드 셋팅 순서]

📌타이틀 씬 > 로딩씬 > 로드가 완료되면 > 게임씬


📌 전체 코드 - LoadingSceneController 스크립트

로딩씬의 로딩바 관련 이미지가 담겨있는 Canvas에 스크립트 넣어주기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class LoadingSceneController : MonoBehaviour
{
    static string nextScene;

    [SerializeField] Image progressBar;

    public static void LoadScene(string sceneName)
    {
        nextScene = sceneName;
        SceneManager.LoadScene("LoadingScene"); // 씬 불러오기
    }

    void Start()
    {
        StartCoroutine(LoadSceneProcess());
    }

    // 코루틴 사용
    IEnumerator LoadSceneProcess()
    {
        // 씬을 비동기로 불러들일 때
        // 씬의 로딩이 끝나면 자동으로 불러온 씬으로 이동할 것인지를 설정
        AsyncOperation op = SceneManager.LoadSceneAsync(nextScene);
        op.allowSceneActivation = false;

        float timer = 0f;

        while (!op.isDone)
        {
            yield return null;
        
            if(op.progress < 0.9f)
            {
                progressBar.fillAmount = op.progress;
            }
            else
            {
                timer += Time.unscaledDeltaTime;
                progressBar.fillAmount = Mathf.Lerp(0.9f, 1f, timer);

                if(progressBar.fillAmount >= 1f && Input.GetKeyDown(KeyCode.Space))
                {
                    op.allowSceneActivation = true;
                    yield break;
                }
            }
        }
    }
}

🔒 LoadingSceneController 스크립트 자세히 보기

  • 씬 전환을 위해 사용되는 클래스
using UnityEngine.SceneManagement;
  • 로딩바 이미지를 담을 컴포넌트
[SerializeField] Image progressBar;

  • 다음 씬을 담을 변수 static으로 선언
static string nextScene;
  • 매개변수로 다음씬 이름을 받아온 뒤, 로딩씬 불러오기
public static void LoadScene(string sceneName)
{
    nextScene = sceneName;
    SceneManager.LoadScene("LoadingScene"); // 씬 불러오기
}

📌 nextScene변수와 LoadScene함수를 static으로 선언한 이유

해당 클래스의 인스턴스(스크립트 부착된 게임 오브젝트)가 존재하지 않아도 접근 가능
다른 스크립트에서 접근이 가능함
ex) LoadingSceneController.LoadScene("GameScene");

  • 코루틴을 사용한 LoadSceneProcess함수
// 코루틴 사용
IEnumerator LoadSceneProcess()
{
    // 씬을 비동기로 불러들일 때
    // 씬의 로딩이 끝나면 자동으로 불러온 씬으로 이동할 것인지를 설정
    AsyncOperation op = SceneManager.LoadSceneAsync(nextScene);
    op.allowSceneActivation = false;

📌 allowSceneActivation을 false하는 이유

  • 다음 씬을 비동기로 불러들일 때, 자동으로 불러온 씬으로 이동할 것인지 설정 함 (bool)
  • false일시, 90% 까지만 로드하고 다음 씬 넘어가지 않고 대기

📌 AsyncOperation

  • 비동기적인 연산을 위한 코루틴 제공
  • SceneManager.LoadScene("LoadingScene");
    동기방식 -> 씬 다 불러오기 전까지 다른 작업 수행 불가
  • SceneManager.LoadSceneAsync("LoadingScene");
    비동기방식 -> 다른 작업 수행 가능

🔒

  • timer 변수 선언
  • !op.isDone -> 씬 로딩이 끝나지 않은 상태면 반복
  • 📌 isDone : 해당 동작이 완료되었는지 나타내는 bool (읽기전용)
  • yield return null -> 코루틴을 사용할 때 Update함수 호출을 위해 사용

    ex) 📌 yield return null

    Start()
    {
    	StartCoroutine(DoSomething());
    }
    Update()
    {
    	Debug.Log("Update");
    }
    IEnumerator DoSomething()
    {
    	Debug.Log("Before");
        yield return null;
        Debug.Log("After");
    }
    // 결과값
    // Before
    // Update
    // After
float timer = 0f;

while (!op.isDone)
{
    yield return null;
  • 📌 progress : 작업의 진행상태 float (읽기전용)
  • <로딩바 진행도 표시>
  if(op.progress < 0.9f)
    {
        progressBar.fillAmount = op.progress;
    }
  • <페이크 로딩 / 진행도 90% 이상일 때>'
  • Time.unscaleDeltaTime : 실제 시간이 흐른 양
  • Mathf.Lerp(0.9f, 1f, timer) : 90% -> 100% timer값에 비례해서 증가
  • 📌 즉 1초 동안 점진적으로 증가함
    else
    {
        timer += Time.unscaledDeltaTime;
        progressBar.fillAmount = Mathf.Lerp(0.9f, 1f, timer);

        if(progressBar.fillAmount >= 1f && Input.GetKeyDown(KeyCode.Space))
        {
            op.allowSceneActivation = true;
            yield break;
        }
    }
}

📌 전체 코드 - SceneLoadTester 스크립트

  • 타이틀씬의 게임오브젝트에 스크립트 넣어주기
  • 스페이스바를 누르면 게임씬으로 이동
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SceneLoadTester : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            LoadingSceneController.LoadScene("GameScene");
        }
    }
}

📌 위의 코드 자세히 설명

  • LoadingSceneController.LoadScene("GameScene"); 하게되면
public static void LoadScene(string sceneName)
    {
        nextScene = sceneName;
        SceneManager.LoadScene("LoadingScene"); // 씬 불러오기
    }
  • 여기로 들어가서 "GameScene"이 nextScene, 즉 다음씬이 되고 우선적으로 로딩씬이 보여지게 됨

    결론적으로 타이틀씬 > 로딩씬 > 게임씬 순서로 보이게 된다

profile
뉴비 개발자

0개의 댓글