KoreanFoodie's Study

8. 게임 매니저, UI, PlayerPrefs : 유니티 튜토리얼 본문

Game Dev/Unity : Tutorial

8. 게임 매니저, UI, PlayerPrefs : 유니티 튜토리얼

GoldGiver 2021. 9. 5. 00:10

바닥 회전

Rotate( ) 메서드를 이용해서 물체를 회전시킬 수 있다.

public class Rotator : MonoBehaviour
{
    public float rotationSpeed = 60f;

    // Update is called once per frame
    void Update()
    {
        transform.Rotate(0f, rotationSpeed * Time.deltaTime, 0f);        
    }
}

위에서 rotationSpeed에 Time.deltaTime을 곱합으로써, 어떤 기기에서도 안정적으로 1초마다 rotationSpeed만큼의 각도의 회전을 줄 수 있다. Update( ) 는 1프레임마다 실행되며, Time.deltaTime은 ( 1 / 초당 프레임 수)이므로, 프레임이 60이든 120이든 상관없이 1초마다 rotationSpeed만큼 회전되는 것을 보장한다.

 

게임 UI 제작 : 유니티는 UI도 게임 오브젝트이다!

Time 과 Press R to Restart 등은 게임 UI이다. (Text 형태)

캔버스와 이벤트 시스템

우리가 UI를 위해 Text 게임 오브젝트를 생성하면, Canvas와 Event System 오브젝트가 자동으로 생성되는 것을 알 수 있다. Text 게임 오브젝트는 Canvas 게임 오브젝트의 자식 오브젝트로 설정되어 있는데, UI 요소들은 캔버스의 2차원 평면에 배치되기 때문이다. UI 게임 오브젝트는 일반 게임 오브젝트와 달리 트랜스폼 컴포넌트를 확장한 사각 트랜스폼(Rect Transform) 컴포넌트를 가진다. 즉, UI 요소는 자신이 배치될 2차원의 액자가 필요하고 Canvas 게임 오브젝트는 UI 요소가 배치될 수 있는 액자 역할을 한다! (모든 UI 게임 오브젝트는 Canvas 게임 오브젝트의 자식임)

2D로 뷰를 전환했을 때 캔버스의 모습

EventSystem 게임 오브젝트는 이벤트 시스템 컴포넌트를 가진 게임 오브젝트로, UI 게임 오브젝트에 클릭이나 터치, 드래그 같은 상호작용을 이벤트 메시지로 전달한다. 이 게임 오브젝트가 씬에 없다면 UI 버튼이나 슬라이드 바를 클릭하고 드래그하는 등의 UI 상호작용을 할 수 없습니다.

EventSystem 게임 오브젝트는 별다른 설정을 요구하지 않고 스스로 동작한다. 우리가 직접 수정할 일은 거의 없다.

 

앵커 프리셋 (Anchor Presets)

UI 요소를 잘 배치하기 위해서는 앵커(Anchor), 피벗(Pivot), 포지션(Position) 값을 조정해야 한다.

앵커 프리셋

[ALT]를 누르면 스내핑(Snapping)이 활성화된다. 이 상태에서는 앵커값 뿐만 아니라 포지션값도 변경되며, UI 게임 오브젝트가 해당 방향의 모서리에 달라붙는 형태로 정렬된다.

 

게임 매니저 제작

게임 매니저는 게임오버 상태 표현이나 생존 시간 갱신, UI 갱신 및 표시, 게임오버 시 게임 재시작 등을 관리한다.  GameManager 스크립트를 만들면, 먼저 UI, 씬 관리와 관련된 코드를 using을 사용해 가져와야 한다.

using UnityEngine.UI; // UI 관련 라이브러리
using UnityEngine.SceneManagement; // 씬 관리 관련 라이브러리

위 선언을 추가하지 않으면 UI 관련 컴포넌트를 변수로 선언하고 사용할 수 없다. 

그럼 게임오버, 생존 시간, 최고 기록 등을 설정하는 간단한 스크립트를 보자.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.UI; // UI 관련 라이브러리
using UnityEngine.SceneManagement; // 씬 관리 관련 라이브러리

public class GameManager : MonoBehaviour
{
    public GameObject gameoverText;
    public Text timeText;
    public Text recordText;

    private float surviveTime;
    private bool isGameover;


    // Start is called before the first frame update
    void Start()
    {
      surviveTime = 0;
      isGameover = false;  
    }

    // Update is called once per frame
    void Update()
    {
        if (!isGameover)
        {
            surviveTime += Time.deltaTime;
            timeText.text = "Time: " + (int) surviveTime;

        }
        else
        {
            if (Input.GetKeyDown(KeyCode.R))
            {
                SceneManager.LoadScene("SampleScene");
            }
        }
    }

    public void EndGame()
    {
        isGameover = true;
        gameoverText.SetActive(true);

        float bestTime = PlayerPrefs.GetFloat("BestTime");

        if (surviveTime > bestTime)
        {
            bestTime = surviveTime;

            PlayerPrefs.SetFloat("BestTime", bestTime);

        }

        recordText.text = "Best Time: " + (int) bestTime;


    }

}

 

PlayerPrefs

PlayerPrefs는 Player Preference (플레이어 설정)라고 읽으며, 간단한 방식으로 어떤 수치를 로컬에 저장하고 나중에 다시 불러오는 메서드를 제공하는 유니티에 내장된 클래스이다.

PlayPrefs는 키-값 단위로 데이터를 로컬에 저장한다. 마치 파이썬의 Dictionary 같이! 두 가지 메서드를 살펴보자.

PlayerPrefs.SetFloat(string key, float value); // 값을 저장. 없으면 추가, 있으면 덮어쓰기
PlayerPrefs.GetFloat(string key); // 값을 불러옴. 없으면 0 리턴
PlayerPrefs.HasKey(string key); // 값이 있는지 없는지에 따라 bool 타입 리턴

 

PlayerController

앞서 GameManager의 EndGame( ) 메서드에서는 게임 오버시 어떤 동작을 할 지를 관리했지만, 실제로 이를 호출하는 것은 player 오브젝트의 Die( ) 이다. 코드를 보자.

    public void Die() 
    {
        gameObject.SetActive(false);
        GameManager gameManager = FindObjectOfType<GameManager>();

        gameManager.EndGame();
    }

Die( )에서는 GameManager를 찾은 다음, EndGame( )을 호출한다.

 

다음 포스팅에서는 방향,위치, 속력 등 공간과 관련된 기초적인 수학적 지식과 코딩을 다루고자 한다.

Comments