본문 바로가기
코딩/연습

유니티 : 캔버스로 메뉴 만들기

by gold_koi 2023. 4. 11.

저번 주 매일을 만나가며 컨셉, 기획을 끝냈다. 이제 남은 것은 메인프로젝트 시작!!!

...

인 줄 알았지만..


저번에는 간단하게 씬에 대해 알아보았다.

이번에 제작할 메인프로젝트는 전작에서 쓰이지 않은 다양한 기능들을 사용하기 때문에

각자의 실력계발에 힘쓰는 이번 한 주가 될 것 같다.


 

이제는 편하게 왼쪽정렬로 글 써야지 ㅇ.ㅇ;;

 

이번에 알아 볼 것은 캔버스이다.

 

캔버스를 왜 전작에서 사용하지 않았냐!! 기본아니냐!! 할 수 있는데, 전작은 그냥 게임을 만들 수 있는가 정도의 실력확인이였기 때문에...ㅠㅠ 자잘구리한 것들은 전부 들어내고 제작했다...

 

이번에 제작할 게임은 추리게임으로, 쿼터뷰의 2D형식으로 제작할 생각이니 2D환경에서 진행하겠다.

 

우리는 esc를 눌렀을 때의 메뉴를 제작할 것이므로 간단하게 버튼부터 알아보자.

 

캔버스의 생김새이다.

왼쪽아래 핸들에 있는 작은 스퀘어가 실제 화면이다.

캔버스가 왜이리 크냐! 라고 한다면, 캔버스의 위치는 world space가 아니라 카메라를 기준으로 잡히기 때문에 캔버스의 크기는 우리 화면의 픽셀 크기에 맞게 생성된다.(world space의 1m가 1px이라는 점)

난 창모드로 해서 그런가 크기가 요상하게 잡혔다.

 

캔버스는 있지만 그 위에 있어야 할 버튼들이 존재하지 않는다..

버튼을 만들려면 좌측 하이어라키 창의 캔버스에서 우클릭 - UI - button을 순서대로 클릭하자.

(tada~!)

버튼이 만들어졌다.

버튼의 자식오브젝트에는 에디터 상의 button text가 존재하는 text오브젝트가있다.

 

 

좌측을 보면 button컴포넌트 안에 OnClick() 함수가 있다.

 

클릭을 하면 내부에 지정된 함수를 실행하겠단 뜻이다.

 

처음 셋팅은 No Function, None(gameObject)로 됐을텐데, 어디에 있는(gameobject) 어떤 스크립트를(function) 실행할 것이냐에 따라 들어가는 object, 메서드가 다를 것이다.

 

즉 !!!

 

function은 object에 컴포넌트 되어있는 스크립트를 자동으로 인식하여 버튼을 클릭할 시 실행할 메서드를 가져올 수 있다! (옆의 예시는 ButtonTest라는 스크립트 안의 메서드들을 보여준다.)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

그럼 이제 간단한 메뉴의 윤곽을 만들어보자!

 

버튼 각각의 역할을 수행하도록 하기 위해 4개의 버튼을 만들었다.

하이어라키 창에 cavas의 자식오브젝트를 보면,

 

pause라는 오브젝트는 일시정지상태일 때 나타나는 메뉴이다.

 

저 아래의 text(tmp)는 이름을 수정하는 것을 깜빡했지만, 시간이 흐르는지 확인하기 위한 텍스트이다.

저 버튼들은 esc를 눌러야만 보이게 할 것이므로 Pause를 비활성화해주자.

 

아래는 Canvas에 들어갈 스크립트이다.

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

public class ButtonTest : MonoBehaviour
{

    private bool isPaused = false;
    public GameObject pauseMenu;
    // Start is called before the first frame update
    private void Update(){
        if(Input.GetKeyDown(KeyCode.Escape)){
            if(isPaused)
                Resume();
            else
                Pause();
        }
    }
    public void Resume(){	//게임을 재개한다.
        pauseMenu.SetActive(false);
        Time.timeScale = 1f;
        isPaused = false;
        Debug.Log("resume");
    }
    public void Pause(){	//게임을 일시정지한다.
        pauseMenu.SetActive(true);
        Time.timeScale = 0f;
        isPaused = true;
        Debug.Log("Pause");
    }
    public void Exit(){		//게임을 끈다.
        Application.Quit();
    }
    public void Option(){	//옵션을 연다.
        Debug.Log("옵션");
    }
}

 

게임의 일시정지 상태를 파악해주는 bool 타입의 isPaused가 있고,

그 아래에 활성화시켜줄 게임오브젝트를 넣어주기 위해 public으로 선언하였다.

 

각각의 메서드들은 버튼들이 읽을 수 있게 public으로 선언해주었다.

 

update문에서 esc 신호를 감지하면 isPaused의 상태에 따라 메서드들이 실행된다.

timeScale은 시간의 흐름의 속도를 숫자로 표현한 것이다. 기본은 1f, 0.5배로 진행하려면 0.5를 입력하면 된다.

우리는 일시정지할 것이기 때문에 Pause()메서드에는 0으로 바꿔준다.

 

이제 위의 메서드들을 각각 버튼의 역할에 맞게 할당해주자.

 

 

실제 기능은 구현하지 않았다.

 

아래는 text(tmp)오브젝트에 들어갈 스크립트다.

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

public class TimeTest : MonoBehaviour
{
    private float realTime=0f;		//현재 시간
    private TextMeshProUGUI text;	//화면 상에 표시해 줄 컴포넌트
    // Start is called before the first frame update

    private void Start()
    {
        text=GetComponent<TextMeshProUGUI>();
    }
    // Update is called once per frame
    void Update()
    {
        realTime += Time.deltaTime;	
        text.text = realTime.ToString();
    }
}

 

게임의 실시간 진행상태를 화면에 표시해준다.

 

간단하므로 설명은 생략.

 

아래는 실행화면이다.

 

 

esc를 누르기 전까진 시간이 흐르다가...
esc를 누른 순간 멈춘다.

잘 안보이지만 아래에 콘솔창을 확인해보면, esc를 누르면 pause가, 환경설정과 오디오설정을 누르면 옵션이 기록된다.

게임종료는 빌드를 안해서 굳이 안눌러봤다만, 문제가 있을 것 같진 않으니 잘 될 것이다.

 

돌아가기를 누른 후 다시 esc를 눌렀을 때 모습(콘솔 창 확인)

 

 

 

여기서 유의할 점이 있다. TimeScale을 0으로 만드는 것은 deltaTime을 0으로 만들겠다는 것이나 다름이 없기 때문에, deltaTime을 사용하지 않는 코드 혹은 메서드는 실행이 될 것이다. 즉, 시간만 멈추는 것이지 시간에 구애받지 않는 코드를 컴포넌트한 오브젝트가 있다면 그것들은 작동될 것이라는 의미이다.

 

실제로 게임을 정지시키려면 아래 주소의 주인분이 정말 깔끔하게 정리해놓은 것이 있으니, 가능한 저것을 활용하자.

 

https://scvtwo.tistory.com/27 

 

[Unity] 유니티에서 게임 종료 & 비활성화 처리

안녕하세요. 오늘은 안드로이드에서의 백버튼을 눌렀을 경우 게임이 종료와 홈버튼을 눌러서 프로그램이 비활성화 되었을 경우에 대해서 알아보겠습니다. 유니티 종료 함수 Application.Quit() 함수

scvtwo.tistory.com

 

(덕분에 도움 많이 받았습니다. 감사합니다!)

 


 

요약

 

캔버스는 world space에 위치하지 않고 카메라를 따라간다.

캔버스의 버튼은 button 컴포넌트의 onclick()을 통해 클릭 시 실행시킬 함수를 지정할 수 있다.

time.timeScale은 시간의 배속과 대응한다.

deltaTime에 구애받지 않는 메서드들은 실행되므로 주의하자.

 

끝.

 

 

 

 

폰트 출처 : 공유마당 - 무료 폰트 기상청 - 기상청달콤기후제

 

캔버스 도움 : https://husk321.tistory.com/107

 

 

 

'코딩 > 연습' 카테고리의 다른 글

혼자 만든 테스트씬  (0) 2023.09.23
유니티 : 해상도와 사운드 조절  (2) 2023.04.14
유니티 : 키 바인딩  (2) 2023.04.13
유니티 : Scene에 대한 것들 정리  (2) 2023.04.11