미디어 콘텐츠 스터디

15. 게임 요소 UI와 정보 풍선 만들기 본문

가상현실(Virtual Reality)/가상현실 맛보기

15. 게임 요소 UI와 정보 풍선 만들기

danmujicat 2021. 9. 25. 08:49

게임 세계에서 게임 요소 UI는 광고판, 점수판, 제어판, 휴대용 메뉴 팔레트, 퍼즐 등이 포함될 수 있습니다. 이들 모두의 공통점은 일부 정보를 전달하고/하거나 사용자가 일부 작업을 수행하기 위해 이들과 상호 작용해야 함을 나타내는 장면의 객체라는 것입니다.

이번에는 스코어보드과 정보 풍선과 같은 몇 가지 다른 시나리오를 시도할 것입니다. 또한 Unity에 내장되어 텍스트 그래픽을 보다 효과적으로 제어할 수 있는 강력한 TMP(TextMesh Pro) 도구를 소개합니다.



1. 스코어보드 만들기

 

앞에서 Ethan이 디오라마 장면에서 죽으면 GameController 개체의 KillTarget 스크립트에 있는 점수 값이 업데이트되지만 현재 점수는 플레이어에게 표시되지 않습니다. 이제 배경 사진 이미지의 왼쪽 상단 모서리에 있는 장면에 스코어보드를 추가하여 이 작업을 수행합니다.

 

① Project 창에서 Default Canvas 프리팹을 장면 보기로 직접 끌어서 ScoreBoard로 이름을 변경니다.
② 이미지 모서리에 캔버스 위치 및 크기 조정(스코어보드를 선택한 상태에서 Rect Transform 구성 요소의 Pos X, Pos Y

   및 Pos Z 값을 각각(-2.8, 7 및 4.9)로 설정하고 너비 및 높이 값을 각각 2000 및 750로 설정합니다..
③ Hireachy 창에서 Panel를 선택하고 Inspector 창에서 Image컴포넌트를 비활성화/삭제하여 Panel 배경을 숨깁니다.
④ Text를 확대합니다(텍스트 개체를 선택하고 속성 창에서 글꼴 크기를 300으로 설정).
⑤ Text 객체에 대해 빨간색과 같은 눈에 띄는 색상을 선택합니다.
⑥ Text에 Score: 0 샘플 문자열을 입력합니다.

 

 

다음과 같이 KillTarget.cs 스크립트를 수정합니다.


① 먼저 UnityEngine.UI 클래스를 사용할 것이므로 파일 상단에서 UnityEngine.UI를 사용하여 선언합니다.

using UnityEngine.UI;

② 클래스 맨 위에 scoreText에 대한 공용 변수를 추가합니다.

public Text scoreText;

③ Start()에 줄을 추가하여 점수 텍스트를 초기화합니다.

scoreText.text = "Score: 0";

④ 그런 다음 Update()에 줄을 추가하여 점수가 변경될 때 점수 텍스트를 변경합니다.

score += 1;
scoreText.text = "Score: " + score;

⑤ 스크립트 파일을 저장한 후 Unity 편집기로 돌아가 Hierarchy 패널에서 GameController를 선택한 다은 Scoreboard        아래의 Text 개체를 Kill Target 구성 요소의 Score Text 필드로 끌어다 놓습니다.


⑥ VR에서 장면을 실행합니다. Ethan을 쳐다볼 때마다 Ethan을 죽일 때마다 사진 평면의 왼쪽 상단에 있는 Scoreboard     구성 요소에서 점수가 업데이트됩니다.

 

2. TextMesh Pro 사용하기


TextMesh Pro(TMP)은 네온사인처럼 고품질 텍스트 스타일 지정 및 텍스처링 기능을 제공하는 고급 텍스트 렌더링 툴킷입니다.

① Package Manager(window | Package Manager)를 엽니다.
② 검색창에서 TextMeshPro를 검색합니다. 필요한 경우 왼쪽 필터 드롭다운에서 Unity Registry를   선택합니다.
③ install를 클릭하여 패키지를 설치하거나 필요한 경우 업데이트를 선택하여 현재 버전을 설치합니다.

④ TMP Essentials을 프로젝트로 가져온 다음(Window| TextMeshPro | Import TMP Essential Resources) import 버튼

상자에서 가져오기를 선택합니다.
⑤ 새 TMP 가져오기 창이 열립니다. 가져오기를 완료하려면 TMP Essentials 가져오기 버튼을 누릅니다.
⑥ 마찬가지로 TMP 예제 및 추가 항목 가져오기를 선택하여 TMP 예제 및 추가 항목을 가져오고 이전 단계를

수행합니다.

 

 

프로젝트에서 TMP 텍스트를 사용합니다.


① Hierarchy에서 ScoreBoard을 선택한 상태에서 새 Text(TMP)를 추가합니다(오른쪽 클릭 후 UI | Text -

    TextMeshPro로 이동). 기본 이름은 Text(TMP)입니다.
② Text(TMP)가 표준 UI 텍스트 요소를 대체하므로 Text 개체를 비활성화합니다(Inspector 왼쪽 상단에 있는 활성화 확인란 선택 취소).
③ Rect Transform | Anchor Preset을 선택하여 Shift + Alt를 누르고  Strech-Strech를 클릭하여 Text(TMP)를 원본 텍스트처럼 설정합니다.
④ 텍스트 문자열의 경우 Score : 0으로, 글꼴 크기를 300으로, Wrapping을 Disabled로, Overflow를 Overflow로,     

    Alignment를 Left, Middle로 설정합니다.

이제 몇 가지 글꼴을 실험해 보겠습니다. Bangers를 사용해 봅시다(Bangers 없는 경우 다른 글꼴을 사용해도 됩니다.
① Font Asset에서 도넛 아이콘을 선택하여 TMP 글꼴 선택 창을 열고 Bangers SDF를 선택합니다.
② Material Preset 설정에 Bangers SDF Glow를 사용합니다.
③ Material 창에서 Glow 설정으로 스크롤하여 원하는 대로 색상 및 기타 설정을 조정합니다.

 

 

KillTarget.cs 스크립트에서 표준 UI 텍스트 개체가 아닌 TMP 텍스트 개체를 사용합니다. 다음과 같이 KillTarget.cs를 수정합니다. 먼저 Unity 엔진 TMP 클래스를 사용 중임을 선언합니다.

using TMPro;

scoreText 변수의 데이터 유형을 TMP_Text로 바꿉니다.

public TMP_Text scoreText;

 

TMP는 버튼, 드롭다운 및 입력 필드 UI 요소를 포함하여 장면에서 기본 텍스트 개체가 사용되는 모든 곳에서 사용할 수 있습니다. 독특하게도 TMP를 사용하면 캔버스 없이도 장면에 직접 3차원 텍스트 개체를 메쉬로 추가할 수 있습니다(메인 메뉴에서 GameObject | 3D Object | Text - TextMeshPro로 이동). 

KillTarget.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; //추가
using TMPro; //추가
public class KillTarget : MonoBehaviour
{
    public GameObject target;
    public ParticleSystem hitEffect;
    public GameObject killEffect;
    public float timeToSelect = 3.0f;
    public int score;
    public Text scoreText; //추가
    public TMP_Text scoreText;  //추가

    Transform camera;
    private float countDown;

    void Start()
    {
        camera = Camera.main.transform;
        score = 0;
        countDown = timeToSelect;
        scoreText.text = "Score: 0"; //추가
    }

    void Update()
    {
        bool isHitting = false;
        Ray ray = new Ray(camera.position, camera.rotation * Vector3.forward);
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit))
        {
            if (hit.collider.gameObject == target)
            {
                isHitting = true;
            }
        }

        if (isHitting)
        {
            if (countDown > 0.0f)
            {
                // on target 
                countDown -= Time.deltaTime;
                // print (countDown); 
                hitEffect.transform.position = hit.point;
                if (hitEffect.isStopped)
                {
                    hitEffect.Play();
                }
            }
            else
            {
                // killed 
                Instantiate(killEffect, target.transform.position, target.transform.rotation);
                score += 1;
                scoreText.text = "Score: " + score; //추가
                countDown = timeToSelect;
                SetRandomPosition();
            }
        }
        else
        {
            // reset 
            countDown = timeToSelect;
            hitEffect.Stop();
        }
    }

    void SetRandomPosition()
    {
        float x = Random.Range(-5.0f, 5.0f);
        float z = Random.Range(-5.0f, 5.0f);
        target.transform.position = new Vector3(x, 0.0f, z);
    }

}


3. 정보 거품 만들기

많은 온라인 소셜 VR 세계에서 참가자는 아바타로 대표되며 종종 다른 사람의 아바타 위로 마우스를 가져가면 참가자의 이름이 표시됩니다. 이러한 유형의 UI를 정보 거품(Info Bubble)이라고 부릅니다. 


앞 예에서 LookMoveTo.cs 스크립트에 의해 제어되는 WalkTarget 객체의 X 및 Z 위치를 표시합니다.

정보 풍선을 추가하려면 다음 단계를 따릅니다.
① Project 창에서 Default Canvas 프리팹을 Hierachy 창으로 직접 끌어 WalkTarget의 자식이 되도록 합니다.
② InfoBubble로 이름을 바꿉니다.
③ Sence 창에서 사각형 도구를 사용하여 InfoBubble 캔버스 크기를 조정합니다. Pos X, Pos Y 및 Pos Z를 각각 0, 0.2 및     0으로 설정하고 너비와 높이를 각각 600 및 150으로 설정합니다.
④ 자식 Text 요소에서 Text에 X:00.00, Z:00.00 문자열을 입력합니다.

 

⑤ 현재 WalkTarget 객체의 X 및 Z 위치를 표시하도록 LookMoveTo.cs 스크립트를 수정합니다.

먼저 infoBubble 및 infoText 변수를 선언한 다음 시작에서 infoText를 초기화합니다.

LookMoveTo.cs

using UnityEngine;
using UnityEngine.UI; //추가
public class LookMoveTo : MonoBehaviour
{
     public GameObject ground;
     private Transform camera;
     public Transform infoBubble; //추가
     private Text infoText; //추가
   
     void Start()
     {
          camera = Camera.main.transform;
      
          if (infoBubble != null)   //추가 start
          {
             infoText = GetComponentInChildren<Text>();
          }   //추가 end
	 }  
}


⑥ 다음과 같이 항상 카메라를 향하도록 캔버스를 회전합니다.

LookMoveTo.cs

void Update()
{
	Ray ray;
	RaycastHit[] hits;
	GameObject hitObject;
	ray = new Ray(camera.position, camera.rotation * Vector3.forward);
	hits = Physics.RaycastAll(ray);
	for (int i = 0; i < hits.Length; i++)
	{
		RaycastHit hit = hits[i];
		hitObject = hit.collider.gameObject;
		if (hitObject == ground)
		{
			if (infoBubble != null)  //추가start
			{
				infoText.text = "X:" + hit.point.x.ToString("F2") +
								", " +
								"Z:" + hit.point.z.ToString("F2");
				infoBubble.LookAt(camera.position);
				infoBubble.Rotate(0, 180f, 0);
			} //추가end
            
			transform.position = hit.point;
		}
	}
}

NOTE) TMP 패키지는 고급 텍스트 표시, 텍스처 및 효과를 위한 강력한 텍스트 도구 키트이며 장면에 3차원 텍스트 메시를 추가하는 데 사용할 수도 있습니다.

Comments