본문 바로가기

TIL

23.11.13

FSM : 유한상태머신

FSM(Finite State machine)은 다음과 같은 특징을 가집니다.

  • 자신이 취할 수 있는 유한한 갯수의 상태들을 가진다
  • 그 중에서 반드시 하나의 상태만 취한다
  • 현재 상태는 특정 조건이 되면 다른 상태로 변할 수 있다
  • 가능한 상태들의 집합과 각 상태들의 전이 조건으로 정의 될 수 있다

FSM을 사용하는 이유로는

  • 가능한 상태들을 명확히 규정할 수 있다
  • 상태 중복을 피할 수 있다
  • 전이들을 명확하게 규정할 수 있다
  • 따라서 기계의 동작을 분명하게 규정할 수 있다
  • FSM에 기반한 객체를 만든다면, 안정적인 작동을 보장할 수 있다

 

비동기 씬 로딩

비동기 씬 로딩을 위해서 SceneManager에서 LoadSceneAsync를 사용하면 구현 할 수있다.

유니티에서 Scene이 로드되면 Scene에 포함되는 Assset들이 메모리 상에 올라가며, 다른 Scene으로 넘어가는 경우 이전 Scene의 사용되지 않는 리소스들이 메모리에서 해제됩니다. 

 

Scene의 볼륨이 큰 경우 로드가 길어지게 되며 유저의 흥미가 떨어지게 되므로, 비동기적으로 씬을 로딩 시키고 진행 과정을 보여줘서 유저의 흥미를 유지시킬 수 있습니다.

 

SceneLoadManager.cs

LoadingScene 을 만들고, 로딩 씬에 슬라이더를 넣어놓고 SceneLoadManager의 인스펙터창에 슬라이더를 참조시킨면,

A라는 씬에서 B라는 씬으로 이동하기 위해서 static으로 선언된 LoadScene메소드를 사용하여서 SceneLoadManager.LoadScene("B")를 실행시키게되면 LoadingScene으로 이동되면서 Start 메소드에 있는 코루틴이 실행되며 비동기 씬 로딩이 실행되고, 진행사항이 슬라이더로 표시되게됩니다.

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

public class SceneLoadManager : MonoBehaviour
{
    public static string sceneName;
    [SerializeField] Slider progressBar;

    private void Start()
    {
        StartCoroutine(LoadScene());
    }

    public static void LoadScene(string sceneName)
    {
        sceneName = sceneName;
        SceneManager.LoadScene("LoadingScene");
    }

    IEnumerator LoadScene()
    {
        yield return null;
        AsyncOperation op;

        op = SceneManager.LoadSceneAsync(sceneName);

        op.allowSceneActivation = false;
        float timer = 0.0f;
        while (!op.isDone)
        {
            yield return null;
            timer += Time.deltaTime;
            if (op.progress < 0.9f)
            {
                progressBar.value = Mathf.Lerp(progressBar.value, op.progress, timer);
                if (progressBar.value >= op.progress)
                {
                    timer = 0f;
                }
            }
            else
            {
                progressBar.value = Mathf.Lerp(progressBar.value, 1f, timer);
                if (progressBar.value == 1.0f)
                {
                    op.allowSceneActivation = true;
                    yield break;
                }
            }
        }
    }
}

 

'TIL' 카테고리의 다른 글

23.11.15  (0) 2023.11.16
23.11.14  (0) 2023.11.14
23.11.10  (0) 2023.11.13
23.11.09  (0) 2023.11.13
23.11.08  (0) 2023.11.13