Dodg미니게임에 UI및 재시작 추가
20261019 Unity UI 추가
Dodge에 UI 추가
Unity에는 3가지 UI시스템이 있다. 한가지는 수업때만 사용하고 사용 안한다고 보면 되고 남은 두가지는 UGUI, UI 툴킷이 있다. 이번 수업에서는 UGUI로 배울 예정이다.
Canvas 생성
Hierarchy -> UI (Canvas) -> Canvas로 생성한다.
Canvas 조작
Scene 화면 우상단 -> 2D모드 On 상태로 작업을 한다. Tools의 Rect Tools선택 상태로 Hierarchy에 있는 Canvas의 GameObject 선택하면 크기 조절이 가능하다.
당분간 수업진행시 UI(Canvas) 기본 설정(Canvas Scaler 설정)
- Canvas Scaler -> UI Scale Mode를 Scale With Screen Size로 설정
- Reference Resolution X 1920 Y 1080로 설정
- Match의 Height 1로 설정
Canvas에 Text 추가 및 Font 설정
Canvas는 Scene에 소속되어 있고 UI는 Canvas 하위에 생성해야 한다. Canvas 밖에 UI에 들어갈 항목들을 생성할 경우 정상적으로 작동하지 않는다. Canvas가 여러개일 때는 작업하고자 하는 캔버스 우클릭 -> 넣고싶은 UI 추가를 해주어야 한다.
Canvas 우클릭 -> UI (Canvas) -> Text - TextMeshPro를 선택하면 Text가 추가되며
그렇게 생성된 Text Object의 Inspector View -> TextMeshPro - Text (UI) -> Font Asset 항목에서 Font를 설정할 수 있다.
Font는 Project View의 TextMesh Pro폴더에 있는 Fonts폴더 안에 있으며 Project View에 TextMesh Pro폴더가 없다면 불러와야 한다.
TextMesh Pro 폴더 불러오는 방법
Window -> TextMeshPro -> Import TMP Essential Resources을 클릭하여 Project View에 TextMesh Pro폴더를 불러온다.
Project View에 TextMesh Pro폴더에는 Fonts, Resources, Shaders, Sprites같은 Text를 표시하기 위한 정보들이 들어있다.
GamePlay 화면과 UI 화면이 같이 렌더링 되는 원리
UI와 게임화면은 렌더링을 2번 한다고 보면 된다.
- UI를 제외하고 게임플레이 화면을 렌더링한 화면
- 게임플레이 화면을 제외하고 UI만 렌더링한 화면
이 두가지를 합친것이 UI가 보이는 게임플레이 화면이다.
Text Object의 Rect Transform Component
Rect Transform에서는 Text의 위치나 Scale, Anchors 등의 Text의 틀에 대한 설정을 할 수 있다.
- Pos X, Pos Y, Pos Z 의 값은 좌측의 Anchor Preset(왼쪽에 있는 그림 클릭)으로 선택한 기준점을 기준으로 한 값이다.
- Pivot은 Text Box의 중앙점 위치를 설정하는 것이다.(0.0이 최소값, 1.0이 최대값)
- Anchor Preset에서 Shift는 Pivot까지 함께 정렬하여 옮기는 것, Alt는 Text는 위치까지 옮기는 것이다. 둘다 사용하면 Pivot과 위치가 모두 설정한 Anchor Preset을 따라 이동한다.
- 주의사항: Anchor와 Pivot을 잘못 설정하면 화면 해상도에 따라서 UI가 화면을 넘어가는 등 문제가 발생할 수 있다. 내 UI에서는 잘 보여도 다른사람 UI에서는 해상도 따라서 안보일 수 도 있으니 주의해야 한다.
Text 정렬
기본적으로 Text내용은 Rect의 좌상단 부터 적힌다. 이를 정렬해주려면 Inspector View의 TextMeshPro에 있는 Alignment항목을 통해서 정렬하면 된다.
Script의 변수명 변경시 주의사항
Script에서 변수 이름을 바꿀때 연결되어있던 레퍼런스가 있다면 연결이 깨지기 때문에 다시 연결해주어야 한다. 자주발생하는 실수 중 하나이다.
Player의 생존 시간에 따라 시간을 표시하는 방법
시간증가
우선 시간에 따라 증가하는 텍스트를 표시하려면 GetComponent를 통해 Text를 가져와서 수정해주어야 한다.
TextMeshPro는 Unity에서 제공하는게 아니라 다른곳에서 만든것을 Unity에서 가져와 쓰는것이다.
그러므로 Using으로 가져와야 한다. - using TMPro;TextMeshProUGUI가 TextMeshPro Component를 담는 클래스이다.
public TextMeshProUGUI timeText;
private void Update()
{
if(!isGameOver)
{
surviveTime += Time.deltaTime;
timeText.text = $"TIME: {surviveTime:F1}";
}
}
GameOver가 진행되는 구조
Player GameOver시 GameManager에 이를 알려주고 GameManager에서 다른 객체들에 Player의 GameOver를 전달하는 방식으로 만든다. Player에서 알리던 Bullet에서 Player를 죽인것을 알리던 2개중 고르면 된다.(수업에서는 Player에서 알리는 방식으로 진행한다.)
Player에 GameManager를 호출할 수 있도록 변수 추가
PlayerController에서 GameManager의 함수를 호출할 수 있도록 private GameManager gameManager; 선언 후 GameManager 가져오기
GameManger를 Tag로 가져올 수 있도록 GameManager의 Tag를 GameController로 설정
private GameManager gameManager;
private void Start()
{
GameObject findGo = GameObject.FindWithTag("GameController");
gameManager = findGo.GetComponent<GameManager>();
}
Player에 OnDie 함수를 추가
Bullet이 Player의 OnDie 함수를 실행시키고 OnDie함수에서 GameManger로 Player의 죽음을 알린 후 GameManager에서 GameOver되면 Time을 멈추는 것으로 한다.
public void OnDie()
{
gameObject.SetActive(false); // 기존 Bullet에서 SetActive 해주던 부분을 Player에서 진행
gameManager.EndGame(); // GameManager에 Player의 죽음을 알림
}
Bullet에서 PlayerController를 호출하도록 변경
기존 Bullet에서 직접 Player의 SetActive를 변경해 주던 것을 PlayerController를 호출하여 OnDie를 실행
if(other.CompareTag("Player"))
{
PlayerController playerController = other.GetComponent<PlayerController>();
playerController.OnDie();
}
GameManager에서 시간 증가를 멈춤
private bool isGameOver;
private void Update()
{
if(!isGameOver)
{
surviveTime += Time.deltaTime;
timeText.text = $"TIME: {surviveTime:F1}";
}
}
public void EndGame()
{
isGameOver = true;
}
Start()에서 변수 초기화
private void Start()
{
surviveTime = 0;
isGameOver = false;
gameOverUI.SetActive(false);
}
GameOver Text 및 BestRecord Text 추가 및 R키를 통한 게임 재시작하는 방법
GameOver UI 생성
- Canvas안에 GameOverText를 생성 후 기본 Active 상태를 false로 설정한 뒤 GameOver가 되면 Active 상태를 true로 바꿔줘서 화면에 보이도록 한다.
Record UI 생성
- GameOver시 현재까지의 Score 중 최고 점수를 표시하기 위하여 GameOverText의 자식으로 RecordText를 추가 생성한다.
키 입력 확인
Update 함수 안에서 사용 해야한다. Input.GetKeyDown(KeyCode.R)를 사용한다.
- Input.GetKeyDown(KeyCode.R) 키가 눌렸을때 한 프레임 실행
- Input.GetKey(KeyCode.R) 키가 눌려있는 동안 프레임당 한번씩 계속 실행
- Input.GetKeyUp(KeyCode.R) 키가 눌렸다가 떼어질 때 한 프레임 실행
Scene 변경 혹은 재시작하는 방법
File -> Build Profiles(Ctrl + Shift + B) -> Scene List에 Scene을 추가해야한다. Open Scene List 후 List창에 Project View에 있는 Scene을 마우스로 드래그 해서 넣는다.
GameManager에 using UnityEngine.SceneManagement;를 추가하고
SceneManager.LoadScene("Game");를 사용하여 Scene을 재시작 한다.
// Update 함수 안에 조건으로 추가한다.
if(Input.GetKeyDown(KeyCode.R))
{
SceneManager.LoadScene("Game");
}
Best Score 저장하는 방법
Scene이 재시작 되어도 BestScore를 유지해야 하기 때문에 일반적인 변수 선언으로는 저장할 수 없다. 이를 저장할 수 있는 방법은 2가지 정도가 있다.
- 레지스트리에 저장(임시로 하는방법임)-그래픽 설정 같은것은 저장해도 되지만 BestScore 같은 경우는 수정하면 안되기 때문에 쉽게 접근 및 수정이 가능한 레지스트리에 저장하면 안됨
float bestScore = PlayerPrefs.GetFloat("BestTime");
if(surviveTime > bestScore)
{
bestScore = surviveTime;
PlayerPrefs.SetFloat("BestTime", bestScore);
}
- 파일에 입출력 하는방법
- 이번 수업은 임시로 저장하는 방법만 사용한다. 파일 입출력은 추후에 따로 다룰 예정이다.
임시저장 되는 위치
레지스트리에 저장이 되는데 위치는 Project Settings -> Player 에 있는 Company Name, Product Name 항목을 참고하여 경로가 생성된다. 정확한 위치는 Help -> Documentation -> Scriptin API 선택후 PlayerPrefs를 검색하여 찾아보면 된다.(\HKEY_CURRENT_USER\Software\ExampleCompanyName\ExampleProductName)
메인카메라 설정
Unity 화면 좌상단 GameObject -> Align With View(Ctrl + Shift + F)를 누르면 Scene View에서 비추고있는 화면대로 Game View의 카메라 위치를 정렬한다.
level 회전
각도를 변경하는 방법에는 2가지가 있다. 각각 Degree, Radian이라고 하며 오늘 다룰 것은 Degree이다.
Level GameObject에 Rotater Script를 추가 후 Update마다 transform.Rotate()를 호출한다.
public float rotSpeed = 30f; // 회전 속도 설정
private void Update()
{
transform.Rotate(0f, rotSpeed * Time.deltaTime, 0f); // 실제 회전
}
Build 하는 방법
File -> Build Profiles -> Build 선택 후 폴더를 선택해서 Build를 하면 해당 위치에 Build파일이 생성된다.



