이 글은 해당 유튜브를 보고 진행한 것에 대해 공부한 것을 정리한 글입니다.
RectTransform과 Canvas 구조
RectTransform
UI 요소에만 존재하는 UI 전용 Transform 컴포넌트이며, 길이와 높이, 위치, 그리고 앵커(Anchor)로 구성되어 있습니다.
Canvas 내에서 생성되는 오브젝트는 기본적으로 RectTransform이 자동으로 추가됩니다.
앵커 (Anchor)
부모 기준으로 UI의 기준점을 설정합니다. 이를 통해 반응형 UI 구현이 가능합니다.
- Shift 키로 앵커 설정 시 기준점만 변경됩니다.
- Alt 키로 앵커 설정 시 위치 및 크기까지 함께 변경됩니다.
- Shift와 Alt 키로 앵커 설정 시 기준점, 위치, 크기까지 모두 변경됩니다.
Canvas 컴포넌트
Render Mode
Canvas 컴포넌트의 Render Mode는 UI를 어떤 방식으로 화면에 렌더링할지 결정하는 설정입니다.
- Screen Space - Overlay
- UI가 화면 가장 위에 직접 그려지는 모드입니다.
- 카메라와 무관하게 항상 화면 최상단에 고정되어 보여집니다.
- 2D UI 게임이나 HUD(체력바, 미니맵 등)에 적합합니다.
- 장점
- 카메라 설정이 필요 없고, 가장 간단하게 UI를 구현할 수 있습니다.
- 단점
- 다른 카메라 뷰와의 연동이 어렵고, UI가 항상 최상단에 고정되기 때문에 이를 고려해야 합니다.
- Screen Space - Camera
- UI가 지정한 카메라의 시점에서 그려지는 모드입니다.
- 카메라를 지정해야 하며, UI가 카메라의 원근감을 일부 받습니다.
- Perspective 카메라와 같이 사용할 경우, 3D처럼 연출하는 것도 가능합니다.
- 장점
- UI가 카메라에 따라 회전하거나 확대/축소되는 등의 효과를 줄 수 있습니다.
- UI가 3D 환경에 자연스럽게 녹아들 수 있습니다.
- 단점
- 카메라 설정을 해줘야 하고, 위치나 거리 등을 신경 써야 합니다.
- World Space
- UI를 3D 오브젝트처럼 월드 공간에 배치하는 모드입니다.
- UI 요소가 게임 오브젝트처럼 행동하며, 위치, 크기, 회전을 자유롭게 조절하는 것이 가능합니다.
- 마치 UI 오브젝트가 게임 세계 안에 간판이나 화면처럼 존재하는 것처럼 느껴집니다.
- 장점
- UI를 실제 환경 안에서 사용할 수 있습니다. (예 : NPC 머리 위 대화창)
- 단점
- 설정이 복잡하고, 카메라나 사용자 거리 등에 따라 가독성이 떨어질 수 있습니다.
UI Scale Mode
- Constant Pixel Size (고정 픽셀 크기)
- UI 요소의 크기를 픽셀 기준으로 고정합니다.
- 화면 해상도가 바뀌어도 UI 크기는 그대로 유지됩니다.
- 저해상도에서는 UI가 커 보이고, 고해상도에서는 작아 보일 수 있습니다.
- 반응형 UI가 필요 없는 경우에 적합합니다.
- Scale With Screen Size (화면 크기에 따라 스케일 조절)
- 가장 일반적으로 사용되는 모드이며, 해상도에 따라 UI 크기를 자동으로 조절합니다.
- 기준 해상도를 설정한 후, 실제 해상도와 비교하여 UI를 축소/확대합니다.
- 반응형 UI에 최적이며, 다양한 해상도를 고려한 UI 구현에 적합합니다.
- 추가 설정
- Reference Resolution : 기준이 되는 해상도
- Screen Match Mode
- Match Width or Height : 가로와 세로 중 어떤 방향을 기준으로 할지 비율 설정
- Expand : 화면의 한 축이 짧아져도 전체가 다 보이도록 확장
- Shrink : 축이 길어져도 전체가 잘리지 않도록 축소
- Constant Physical Size (고정 물리 크기)
- 화면의 물리적 크기를 기준으로 UI 요소의 크기를 조정합니다.
- DPI(Dots per inch, 인치당 픽셀 수)를 고려하여 다양한 디바이스에서 동일한 시각 크기를 유지하려 할 때 사용됩니다.
- 주로 태블릿, 스마트폰 등 다양한 DPI를 가진 기기를 지원할 때 유용합니다.
UI
HUD
HUD란 Head-Up Display의 약자로, 게임 중 실시간으로 보여주는 체력바, 미니맵과 같은 UI 정보를 말합니다.
Text 요소
Unity에는 UI 텍스트를 표시할 때 Text와 TextMeshPro 컴포넌트를 통해 표현할 수 있습니다.
Text (Legacy UI Text)
UnityEngine.UI.Text 컴포넌트는 Unity의 기본 UI 시스템에서 제공하는 텍스트 렌더링 방식입니다.
UGUI(Canvas 기반 UI)와 함께 작동합니다.
- 장점
- 기본적으로 제공되므로 별도 패키지 설치가 필요 없습니다.
- 사용법이 간단하며 소규모 UI에 적합합니다.
- 단점
- 렌더링 품질이 낮고, 해상도가 높아질수록 깨지거나 흐릿하게 보일 수 있습니다.
- 커스텀 스타일이나 다양한 텍스트 효과(그림자, 외곽선 등)에 한계가 있습니다.
- 다국어, 특수문자, 동적 텍스트 표현에 제약이 존재합니다.
TextMeshPro
Unity의 차세대 텍스트 렌더링 시스템으로, TextMeshPro 패키지를 임포트해야 사용이 가능합니다.
TMPro.TextMeshProUGUI, TextMeshPro 두 가지 버전이 있으며,
TextMeshProUGUI는 Canvas 기반 UI용으로, TextMeshPro는 3D 공간에서의 텍스트용으로 사용됩니다.
- 장점
- 고해상도에서도 선명한 텍스트 렌더링이 가능합니다.
- 그림자, 외곽선, 컬러 그라데이션 등 다양한 효과를 지원합니다.
- 텍스트 스타일링을 지원합니다.
- <b>, <i>, <color=#FF0000> 등 HTML 유사 태그가 가능합니다.
- 커스텀 폰트 생성 및 문자 집합 최적화가 가능하여, 용량 절약에 유리합니다.
- 리치 텍스트(Rich Text)와 동적 텍스트 교체에 매우 강력합니다.
- 단점
- 전용 폰트 에셋을 필요로 하기 때문에, Font Asset Creator를 사용하여 폰트 에셋을 직접 만들어야 합니다.
Image 컴포넌트
Set Native Size 버튼을 사용하면, 스프라이트의 원래 크기로 이미지 오브젝트를 조정할 수 있습니다.
Vertical Layout Group 컴포넌트
자식 오브젝트들을 자동으로 세로로 정렬해주는 컴포넌트입니다.
Outline 컴포넌트
UI 그래픽을 기준으로 외곽선을 그리는 컴포넌트로, 텍스트나 이미지 등에 외곽선을 부여하는 시각적 효과를 줍니다.
스크립트에서의 UI
스크립트에서 UI를 제어할 때 Unity.Engine.UI 네임스페이스를 꼭 포함시켜야 합니다.
String.Format을 통한 UI Text 지정
String.Format( )은 문자열을 포맷팅할 때 유용합니다.
myText.text = String.Format("Lv.{0:F0}", GameManager.instance.level);
- 옵션
- F0, F1, F2 ⋯ : 소수점 자리를 지정합니다.
- D0, D1, D2 ⋯ : 자리 수를 지정합니다.
UI의 위치 갱신
해당 프로젝트에서 체력바는 player의 종속되어 있지 않고, Canvas에 종속되어 있습니다.
그렇기에 체력바가 player를 따라 다니게끔 전용 Follow 스크립트를 만들었고, 체력바의 RectTransform을 player의 Transform이 되게끔 구현하였습니다. 이때 player의 position은 월드 좌표로 반환되기 때문에 WorldToScreenPoint을 사용하여, 월드 좌표를 스크린 좌표로 변환해줍니다.
RectTransform rect;
void Awake()
{
rect = GetComponent<RectTransform>();
}
void FixedUpdate()
{
rect.position
= Camera.main.WorldToScreenPoint(GameManager.instance.player.transform.position);
}
UI 업데이트 타이밍
UI 데이터 갱신은 주로 LateUpdate( )에서 처리하는 것이 안전합니다. 렌더링 이후 위치 반영이 명확해지기 때문입니다.
name 변수
UnityEninge.Object 클래스를 상속받은 클래스는 name 변수를 따로 선언하지 않고도 사용이 가능합니다.
즉, MonoBehaviour를 상속한 클래스라면 name 속성을 기본적으로 사용할 수 있습니다.
name은 해당 스크립트가 붙어있는 GameObject의 이름에 접근하는 것이 가능합니다.
Navigation
Unity UI에서 Navigation은 키보드, 게임패드 등 비마우스 입력 장치로 UI 요소 간 이동 경로를 제어하는 시스템입니다.
즉, UI 요소들(버튼, 토글, 슬라이더 등) 사이를 사용자가 방향키나 탭 키 등으로 이동할 수 있도록 포커스 순서를 정의하는 기능입니다.
Navigation 종류 (Mode)
- None : 네비게이션 기능을 사용하지 않습니다.
- Horizontal : 좌우 방향 입력에만 반응합니다. 수평으로 정렬된 UI에 적합합니다.
- Vertical : 상하 방향 입력에만 반응합니다. 수직 UI 리스트에 적합합니다.
- Automatic : Unity가 주변 요소를 자동으로 판단해서 연결합니다. 편리하지만, 정확히 제어하고 싶을 때는 부적합합니다.
- Explict : 개발자가 직접 어떤 방향으로 이동할지를 지정합니다. 가장 정밀한 제어가 가능합니다.
Scriptable Object
Scriptable Object는 Unity에서 데이터를 저장하고 재사용하기 위한 경량 데이터 컨테이너입니다.
일반적으로 게임 내에서 공유되거나 자주 사용하는 데이터들을 저장하는 용도로 사용되며, 메모리 효율이 뛰어나고, 에디터 상에서 쉽게 관리할 수 있습니다.
ScritableObject 특징
- MonoBehaviour와 달리 GameObject에 붙일 수는 없지만, 자체적으로 에셋 파일처럼 생성해서 사용할 수 있는 클래스입니다.
- 데이터를 직렬화하여 에디터에서 저장할 수 있습니다.
- 인스턴스는 씬이 아니라 프로젝트에 존재하게 됩니다.
- 런타임 중에도 해당 데이터를 참조할 수 있으며, 여러 객체가 하나의 ScriptableObject를 공유할 수 있어 관리가 편합니다.
ScritableObject 생성
스크립트를 생성 후, MonoBehaviour 대신 ScriptableObject를 사용합니다.
[CreateAssetMenu(fileName = "Item", menuName = "Scriptable Object/ItemData")]
public class ItemData : ScriptableObject
{
public enum ItemType { Melee, Range, Glove, Shoe, Heal }
[Header("# Main Info")]
public ItemType itemType;
public int itemId;
public string itemName;
[TextArea]
public string itemDesc;
public Sprite itemIcon;
[Header("# Level Data")]
public float baseDamage;
public int baseCount;
public float[] damages;
public int[] counts;
[Header("# Weapon")]
public GameObject projectile;
public Sprite hand;
}
CreateAssetMenu 애트리뷰트
해당 애트리뷰트는 Unity 에디터에서 우클릭 메뉴에 새 에셋 생성을 가능하게 해줍니다.
[CreateAssetMenu(fileName = "생성 시 기본 파일명", menuName = "메뉴 경로 지정")]
- fileName : 생성 시 기본 파일명
- menuName : 메뉴 경로 지정
장면 전환과 관리
장면을 전환하기 위해서는 SceneManager가 필요합니다.
그리고 SceneManager를 사용하기 위해서는 UnityEngine.SceneManagement 네임스페이스가 필요합니다.
using UnityEngine.SceneManagement;
// ...
// 씬 전환 예시
SceneManager.LoadScene("GameScene");
BroadcastMessage
BroadcastMessage는 Unity에허 현재 GameObject와 그 모든 자식 오브젝트들에 있는 컴포넌트들에게 특정 메서드를 호출하도록 '방송'하는 기능입니다.
즉, 부모 오브젝트에서 함수를 한번 호출하면 모든 자식까지 호출되는 구조입니다.
시그니처
gameObject.BroadcastMessage("함수 이름", 파라미터, 옵션);
- 파라미터 (선택)
- 함수에 전달할 값
- 옵션 : SendMessageOptions (선택)
- 함수가 없을 때의 처리 방식
- RequireReceiver : 기본값으로, 호출 대상 함수가 없으면 오류를 발생시킵니다.
- DontRequireReceiver : 함수가 없어도 오류를 무시합니다.
유의사항
퍼포먼스에 다소 부담이 있으므로, 자주 호출하거나 많은 오브젝트가 포함된 경우에는 사용을 주의해야 합니다.
함수 오버로디은 지원하지 않으며, 함수 이름은 고유해야 안전합니다.
오브젝트 계층 관련 함수
- ChildCount : 자식 오브젝트 개수를 반환하는 함수입니다.
- GetChild(int index) : 특정 인덱스의 자식을 반환하는 함수입니다.
- GetComponents의 순서는 계층 구조의 순서를 따릅니다.
비활성화 오브젝트 탐색
기본적으로 비활성화된 오브젝트는 GetComponentInChildren( )에 포함되지 않지만, 인자값으로 true를 넣어주면 비활성화된 오브젝트도 포함시킵니다.
hands = GetComponentsInChildren<Hand>(true);
[TextArea] 애트리뷰트
인스펙터에서 여러 줄의 문자열을 입력 가능하게 합니다.
[TextArea]
public string description;
시간 제어
Time.timeScale을 통해 게임의 흐름을 제어하는 것이 가능합니다.
Time.timeScale의 값에 따라 배속이 걸립니다.
Time.timeScale의 값이 0일 때는 게임 속 흐르는 시간이 정지하고, 1일 때는 원래의 시간으로 설정됩니다.
주의할 점
시간 정지 및 시간 속도 제어는 GameManager.cs와 같은 전역 스크립트에서 처리하는 것이 좋습니다.
또한, Update 계열 함수에서 timeScale을 고려한 처리도 함께 필요합니다.
Git
GitHub - Dobby-yhs/Undead-Survivor
Contribute to Dobby-yhs/Undead-Survivor development by creating an account on GitHub.
github.com
'Unity' 카테고리의 다른 글
| [Unity] 디자인 패턴 : SOLID 원칙 (1) | 2025.06.09 |
|---|---|
| [Unity] Unity 2D 게임 개발 정리 (4) (0) | 2025.06.04 |
| [Unity] Unity 2D 게임 개발 정리 (2) (0) | 2025.05.29 |
| [Unity] Unity 2D 게임 개발 정리 (1) (1) | 2025.05.28 |
| [Unity] MonoBehaviour, Prefab, Rigidbody, PlayerPrefs (0) | 2025.05.22 |