- 유니티는 일반적으로 게임엔진 이라고 부릅니다. 게임 엔진이란 3D와 2D 그래픽 렌더링, 물리 시뮬레이션과 충돌 검출, 사운드와 애니메이션 등 게임 개발에 필요한 기능을 제공하는 프레임 워크를 말합니다. 과거와는 달리 누구나 로열티 없이 사용할 수 있게 됐고 이를 게임 개발의 민주화(Democratizing game development)라고도 이야기 합니다.
- 씬(scene)이란 오브젝트를 배치하는 3D공간을 말하며 이 씬은 게임의 무대가 됩니다. 이 무대에 배치되는 오브젝트를 게임 오브젝트(GameObject)라고 부르고 배우(캐릭터 등 모델)뿐만 아니라 배경이나 무대 장치라고 할 수 있는 카메라와 라이트, UI등도 게임 오브젝트라고 할 수 있으며, 이들도 씬에 배치됩니다.
- 게임의 레이아웃은 사용자가 마음대로 변환할수 있으며 커스터마이징이 가능합니다.
씬 뷰는 씬에 배치한 게임 오브젝트의 상태를 확인하거나 게임 오브젝트를 조작할 때 사용하는 화면입니다.
- 게임 오브젝트를 조작하기 위해 사용하는 이동툴 핸드툴(Q) 이동툴(W), 회전툴(E) 스케일툴(R)키 넥트 툴(T)
- 카메라 이동 ALT + 마우스 드래그 또는 커서키
- 카메라 회전 ALT + Ctrl 마우스 드래그(윈도) , ALT + 커맨드 + 마우스 드래그(맥)
- 카메라 줌 ALT + 마우스 오른쪽 버튼 누르고 드래그, ALT + Ctrl + 드래그 또는 마우스 휠
마우스 오른쪽 버튼을 누른 상태에서는 Flythrough모드가 됩니다. (Q W E A S D) 버튼으로 FPS 게임처럼 이동가능
- 게임 오브젝트를 선택한 상태에서 F키를 누르면 씬뷰에 있는 카메라가 이동하여 현재 선택된 게임 오브젝트가 특히 강조돼 나타납니다. Shift 키를 누른 상태에서 F키를 누르면 선택된 게임 오브젝트가 이동할 때 카메라도 같이 이동합니다.(오브젝트의 위치를 찾을때 편하다)
❏ 씬 뷰 위에 있는 컨트롤 바를 사용해 표시 모드를 전환하거나 라이트, 오디오, 기즈모 표시를 켜거나 끌 수 있습니다.
❏ 씬에 배치된 카메라를 통해 렌더링 되고 합성된 최종 결과가 게임 뷰에 표시됩니다. 씬을 실행하는 동안에는 플레이 모드라고 부르고, 실행 중이 아닐 때는 에디트 모드라고 부릅니다.
❏ 씬에 배치된 게임 오브젝트의 계층구조를 표시하는 화면을 말합니다. 드래그 앤드 드롭해 나열하면 이 계층 구조를 변경할 수 있습니다. 그리고 더블 클릭하면 그 게임 오브젝트가 씬 뷰에 표시됩니다.
❏ 프로젝트 뷰는 현재 프로젝트에 포함된 모든 파일을 표시하는 화면이며 윈도이ㅡ 익스플러로나 맥의 피언더와 비슷흡니다. 프로젝트에 포함된 파일은 에셋(Asset)이라고 부릅니다. 에셋은 프로젝트 폴더에 있는 Asset폴더에 배치돼 있고 Assets 폴더에 있는 계층 구조가 그대로 프로젝트 뷰에 반영돼 있습니다. - Assets 폴더에 있는 파일을 익스플로러나 파인더에서 직접 이동시키거나 이름을 변경하면 유니티가 이 파일을 에셋 형태 형태로 추적할 수 없게 되므로 파일 작업은 반드시 프로젝트 뷰에서 해야 합니다. Assets 폴더에 파일을 새로 저장하거나 기존 파일을 덮어 쓰기를 해서 변경하면 유니티가 이를 감지하고 자동으로 에셋형태로 다시 임포트하므로 작업이 정상적으로 이뤄집니다.
❏ 인스펙터 뷰에는 씬뷰와 하이어라키 뷰에서 선택한 게임 오브젝트와 프로젝트 뷰에서 선택한 에셋정보가 표시됩니다. Trasform 컴포넌트는 모든 게임 오브젝트에 추가된 특수 컴포넌트이며, 이 컴포넌트를 추가한 게임 오브젝트의 위치, 회전각, 스케일을 정의합니다. 그리고 게임 오브젝트의 계층 구조도 이 Trasnform 컴포넌트에 의해 실현됩니다.
1 이번 장에서 설명한 뷰 외에도 여러가지 뷰가 있습니다. 윈도 메뉴 → 뷰 (애니메이션 뷰, 오디오 믹서, 프로파일러, 프레임 디버거, 콘솔 뷰)
❏ 파일 메뉴
❏ 에디트 메뉴 - 선택한 게임 오브젝트를 주시하는 기능(fram selected),
- 추종 기능(Lock View to Selected)
- Selection (선택 저장 기능)
- Snap Settings
물리 운동
- 리지드 바디란 강체를 말하며 리지드 바디 컴포넌트를 추가한 게임 오브젝트는 씬에서 중력의 영향을 받기도 하고 다른 오브젝트와 상호 작용하는 등의 물리적인 운동을 합니다.
- Is Kinematic 속성을 체크해 다른 오브젝트에 물리적으로 작용은 하지만 자신은 공간에 멈춰있게 할 수 있습니다.
- 움직임이 부자연스러워 보일때 물리 머터리얼을 사용해봅시다. 물리 머터리얼이란 이름 그대로 물리적인 재질을 정의하는 것이며 이를 사용해 게임 오브젝트에 반발계수나 마찰계수와 같은 물리적인 속성을 설정 할 수 있습니다.
- 생성한 물리 머터리얼은 프로젝트 뷰에서 Cube 오브젝트에 추가된 box collider 컴포넌트 아래에 있는 Material 속성으로 드래그 앤드 드롭해 설정합니다.
프리팹
- 동일한 게임 오브젝트를 다시 이용하려면 프리팹을 이용하면 됩니다.
- 프리팹 에셋은 프로젝트 뷰로부터 하이어라키 뷰나 씬 뷰로 드래그 앤드 드롭해 게임 오브젝트의 인스턴스(instance : 실체) 형식으로 씬에 배치 할 수 있습니다. 이 과정을 프리팹의 인스턴스화(instantiate)라고 부릅니다.
- 프리팹의 인스턴스가 된 게임오브젝트는 하이어라키 뷰에서 파란색 문자로 표시됩니다.
- 여러 개의 프리팹 인스턴스 중 하나를 골라 속성값을 벼경하더라도 다른 인스턴스에 아무런 영향을 주지 않습니다. 이때 변경된 속상값은 인스펙터 뷰에서 굵은 문자로 표시됩니다.
- select 버튼 : 인스턴스의 원본 프리팹을 프로젝트 뷰에서 선택합니다.
- Revert 버튼 : 인스턴스의 변경사항을 취소하고 원본 프리팹과 같은 상태로 되돌립니다.
- Apply 버튼을 누르면 인스턴스의 변경 사항이 프리팹에 반영됩니다. 이때 동일한 원본 프리팹으로 만든 다른 인스턴스에도 변경사항이 반영됩니다. 다른 인스턴스들끼리 속상값 설정이 서로 다를때는 해당 속성값은 오버라이트 되지 않고 유지 됩니다.
- Apply changes to Prefab : GameObject 메뉴에서 선택을 하면 Apply버튼을 눌렀을때와 마찬가지로 인스턴스의 변경 사항을 프리팹에 반영할 수있습니다.
- Break Prefab Instance를 선택하면 해당 인스턴스에는 프리팹 변경사항이 반영되지 않게 됩니다.
튜토리얼2 : 스크립트
스크립트
- MonoBehavior 클래스를 상속한 스크립트는 컴포넌트 형태로 추가할 수 있다.
- 게임 오브젝트에 추가한 컴포넌트는 GetComponent<T>로 가져와서 접근 할 수 있다.
- 유니티에서 게임 오브젝트를 제어하는 스크립트(프로그램)는 Mono런타임 상에서 실행됩니다.
- Mono는 소스가 공개돼 있으며. NET Framework와 호환되는 환경이고 다양한 플랫폼에서 작동합니다.
- Mono는 멀티 플래폼 환경을 지원하기 위해 유니티에 포함된 것입니다.
- C# , 자바스크립트
- C#을 추천
- 유니티스크립트(자바스크립트)에서는 클래스나 정적인 형, 제네릭 메서드 등 독자적으로 확장된 개념들이 있어서 일반적으로 많이 사용하는 자바스크립트와는 다르다.
- MonoBehaviour 클래스는 모든 스크립트의 기반이 되는 클래스입니다.
- Monobehaviour클래스는 component클래스 → Behaviour클래스 순서로 상속되므로 이 클래스를 상속한 클래스를 가진 스크립트 컴포넌트 형태로 씬에 배치된 게임 오브젝트에 추가할 수 있습니다.
- Time.deltaTime은 이전 프레임이 끝난 후 지금까지 지난시간(초) 입니다.
- 필드와 인스펙터 뷰
- 작성한 스크립트에서 소스코드에 직접 기재돼 있는 값을 바꾸기 위해서는 public 필드로 선언을 해야 하며 선언 후 인스펙터뷰에서 값을 변경할 수 있습니다.
- 인스펙터 뷰에서 값을 변경하고 싶지만. 외부 코드에서 값을 변경하지 못하게 하려면 필드를 private나 protected로 지정할 때도 있습니다. 이럴때는 SerializeField 속성을 지정하면 필드를 private나 protected로 정의하더라도 인스펙터 뷰에서 변경할 수 있습니다.
[SerializeField] private float rotationSpeed; // |
티 없이 사용할 수 있게 됐고 이를 게임 개발의 민주화(Democratizing game development)라고도 이야기 합니다.
씬(scene)이란 오브젝트를 배치하는 3D공간을 말하며 이 씬은 게임의 무대가 됩니다. 이 무대에 배치되는 오브젝트를 게임 오브젝트(GameObject)라고 부르고 배우(캐릭터 등 모델)뿐만 아니라 배경이나 무대 장치라고 할 수 있는 카메라와 라이트, UI등도 게임 오브젝트라고 할 수 있으며, 이들도 씬에 배치됩니다.
게임의 레이아웃은 사용자가 마음대로 변환할수 있으며 커스터마이징이 가능합니다.
씬 뷰는 씬에 배치한 게임 오브젝트의 상태를 확인하거나 게임 오브젝트를 조작할 때 사용하는 화면입니다.
게임 오브젝트를 조작하기 위해 사용하는 이동툴 핸드툴(Q) 이동툴(W), 회전툴(E) 스케일툴(R)키 넥트 툴(T)
카메라 이동 ALT + 마우스 드래그 또는 커서키 카메라 회전 ALT + Ctrl 마우스 드래그(윈도) , ALT + 커맨드 + 마우스 드래그(맥) 카메라 줌 ALT + 마우스 오른쪽 버튼 누르고 드래그, ALT + Ctrl + 드래그 또는 마우스 휠
마우스 오른쪽 버튼을 누른 상태에서는 Flythrough모드가 됩니다. (Q W E A S D) 버튼으로 FPS 게임처럼 이동가능
- 게임 오브젝트를 선택한 상태에서 F키를 누르면 씬뷰에 있는 카메라가 이동하여 현재 선택된 게임 오브젝트가 특히 강조돼 나타납니다. Shift 키를 누른 상태에서 F키를 누르면 선택된 게임 오브젝트가 이동할 때 카메라도 같이 이동합니다.(오브젝트의 위치를 찾을때 편하다)
❏ 씬 뷰 위에 있는 컨트롤 바를 사용해 표시 모드를 전환하거나 라이트, 오디오, 기즈모 표시를 켜거나 끌 수 있습니다.
❏ 씬에 배치된 카메라를 통해 렌더링 되고 합성된 최종 결과가 게임 뷰에 표시됩니다. 씬을 실행하는 동안에는 플레이 모드라고 부르고, 실행 중이 아닐 때는 에디트 모드라고 부릅니다.
❏ 씬에 배치된 게임 오브젝트의 계층구조를 표시하는 화면을 말합니다. 드래그 앤드 드롭해 나열하면 이 계층 구조를 변경할 수 있습니다. 그리고 더블 클릭하면 그 게임 오브젝트가 씬 뷰에 표시됩니다.
❏ 프로젝트 뷰는 현재 프로젝트에 포함된 모든 파일을 표시하는 화면이며 윈도이ㅡ 익스플러로나 맥의 피언더와 비슷흡니다. 프로젝트에 포함된 파일은 에셋(Asset)이라고 부릅니다. 에셋은 프로젝트 폴더에 있는 Asset폴더에 배치돼 있고 Assets 폴더에 있는 계층 구조가 그대로 프로젝트 뷰에 반영돼 있습니다. - Assets 폴더에 있는 파일을 익스플로러나 파인더에서 직접 이동시키거나 이름을 변경하면 유니티가 이 파일을 에셋 형태 형태로 추적할 수 없게 되므로 파일 작업은 반드시 프로젝트 뷰에서 해야 합니다. Assets 폴더에 파일을 새로 저장하거나 기존 파일을 덮어 쓰기를 해서 변경하면 유니티가 이를 감지하고 자동으로 에셋형태로 다시 임포트하므로 작업이 정상적으로 이뤄집니다.
❏ 인스펙터 뷰에는 씬뷰와 하이어라키 뷰에서 선택한 게임 오브젝트와 프로젝트 뷰에서 선택한 에셋정보가 표시됩니다. Trasform 컴포넌트는 모든 게임 오브젝트에 추가된 특수 컴포넌트이며, 이 컴포넌트를 추가한 게임 오브젝트의 위치, 회전각, 스케일을 정의합니다. 그리고 게임 오브젝트의 계층 구조도 이 Trasnform 컴포넌트에 의해 실현됩니다.
1 이번 장에서 설명한 뷰 외에도 여러가지 뷰가 있습니다. 윈도 메뉴 → 뷰 (애니메이션 뷰, 오디오 믹서, 프로파일러, 프레임 디버거, 콘솔 뷰)
❏ 파일 메뉴
❏ 에디트 메뉴 - 선택한 게임 오브젝트를 주시하는 기능(fram selected),
- 추종 기능(Lock View to Selected)
- Selection (선택 저장 기능)
- Snap Settings
물리 운동
- 리지드 바디란 강체를 말하며 리지드 바디 컴포넌트를 추가한 게임 오브젝트는 씬에서 중력의 영향을 받기도 하고 다른 오브젝트와 상호 작용하는 등의 물리적인 운동을 합니다.
- Is Kinematic 속성을 체크해 다른 오브젝트에 물리적으로 작용은 하지만 자신은 공간에 멈춰있게 할 수 있습니다.
- 움직임이 부자연스러워 보일때 물리 머터리얼을 사용해봅시다. 물리 머터리얼이란 이름 그대로 물리적인 재질을 정의하는 것이며 이를 사용해 게임 오브젝트에 반발계수나 마찰계수와 같은 물리적인 속성을 설정 할 수 있습니다.
- 생성한 물리 머터리얼은 프로젝트 뷰에서 Cube 오브젝트에 추가된 box collider 컴포넌트 아래에 있는 Material 속성으로 드래그 앤드 드롭해 설정합니다.
프리팹
- 동일한 게임 오브젝트를 다시 이용하려면 프리팹을 이용하면 됩니다.
- 프리팹 에셋은 프로젝트 뷰로부터 하이어라키 뷰나 씬 뷰로 드래그 앤드 드롭해 게임 오브젝트의 인스턴스(instance : 실체) 형식으로 씬에 배치 할 수 있습니다. 이 과정을 프리팹의 인스턴스화(instantiate)라고 부릅니다.
- 프리팹의 인스턴스가 된 게임오브젝트는 하이어라키 뷰에서 파란색 문자로 표시됩니다.
- 여러 개의 프리팹 인스턴스 중 하나를 골라 속성값을 벼경하더라도 다른 인스턴스에 아무런 영향을 주지 않습니다. 이때 변경된 속상값은 인스펙터 뷰에서 굵은 문자로 표시됩니다.
- select 버튼 : 인스턴스의 원본 프리팹을 프로젝트 뷰에서 선택합니다.
- Revert 버튼 : 인스턴스의 변경사항을 취소하고 원본 프리팹과 같은 상태로 되돌립니다.
- Apply 버튼을 누르면 인스턴스의 변경 사항이 프리팹에 반영됩니다. 이때 동일한 원본 프리팹으로 만든 다른 인스턴스에도 변경사항이 반영됩니다. 다른 인스턴스들끼리 속상값 설정이 서로 다를때는 해당 속성값은 오버라이트 되지 않고 유지 됩니다.
- Apply changes to Prefab : GameObject 메뉴에서 선택을 하면 Apply버튼을 눌렀을때와 마찬가지로 인스턴스의 변경 사항을 프리팹에 반영할 수있습니다.
- Break Prefab Instance를 선택하면 해당 인스턴스에는 프리팹 변경사항이 반영되지 않게 됩니다.
튜토리얼2 : 스크립트
스크립트
- MonoBehavior 클래스를 상속한 스크립트는 컴포넌트 형태로 추가할 수 있다.
- 게임 오브젝트에 추가한 컴포넌트는 GetComponent<T>로 가져와서 접근 할 수 있다.
- 유니티에서 게임 오브젝트를 제어하는 스크립트(프로그램)는 Mono런타임 상에서 실행됩니다.
- Mono는 소스가 공개돼 있으며. NET Framework와 호환되는 환경이고 다양한 플랫폼에서 작동합니다.
- Mono는 멀티 플래폼 환경을 지원하기 위해 유니티에 포함된 것입니다.
- C# , 자바스크립트
- C#을 추천
- 유니티스크립트(자바스크립트)에서는 클래스나 정적인 형, 제네릭 메서드 등 독자적으로 확장된 개념들이 있어서 일반적으로 많이 사용하는 자바스크립트와는 다르다.
- MonoBehaviour 클래스는 모든 스크립트의 기반이 되는 클래스입니다.
- Monobehaviour클래스는 component클래스 → Behaviour클래스 순서로 상속되므로 이 클래스를 상속한 클래스를 가진 스크립트 컴포넌트 형태로 씬에 배치된 게임 오브젝트에 추가할 수 있습니다.
- Time.deltaTime은 이전 프레임이 끝난 후 지금까지 지난시간(초) 입니다.
- 필드와 인스펙터 뷰
- 작성한 스크립트에서 소스코드에 직접 기재돼 있는 값을 바꾸기 위해서는 public 필드로 선언을 해야 하며 선언 후 인스펙터뷰에서 값을 변경할 수 있습니다.
- 인스펙터 뷰에서 값을 변경하고 싶지만. 외부 코드에서 값을 변경하지 못하게 하려면 필드를 private나 protected로 지정할 때도 있습니다. 이럴때는 SerializeField 속성을 지정하면 필드를 private나 protected로 정의하더라도 인스펙터 뷰에서 변경할 수 있습니다.
[SerializeField] private float rotationSpeed; // |
❏ 인스턴스 오브젝트 만들고 자식 객체에 위치시키기
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class CubeGenerator : MonoBehaviour {
public GameObject cubePrefab; //상자프리팹
public void Generate() { // 상자 프리팹을 인스턴스로 만든다. GameObject obj = Instantiate(cubePrefab) as GameObject; // 인스턴스를 CubeGenerator오브젝트의 자식 형태로 종속시킨다. obj.transform.SetParent(transform); //인스턴스의 스케일을 프리팹에 맞춘다. obj.transform.localScale= cubePrefab.transform.localScale; //인스턴스의 위치를 CubeGenerator오브젝트에 맞춘다. obj.transform.position=transform.position; } }
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class InputController : MonoBehaviour {
void Update () {
if (!Application.isMobilePlatform) { //모바일 플래폼이 아닐때 실시할 처리 if (Input.GetMouseButtonUp (0)) { //마우스 왼쪽 버튼을 눌렀다. 뗀 상태라면 //CubeGenerator 컴포넌트에 포함된 Generate 메서드 호출 GetComponent<CubeGenerator> ().Generate (); } } else { //모바일 플랫폼일때 실시할 처리 if (Input.touchCount >= 1) { //멀티 터치에서 가장 처음 터치된 것을 구한다. Touch touch=Input.GetTouch(0); if (touch.phase = TouchPhase.Began) { //터치가 시작된 상태라면 CubeGenerator 컴포넌트에 포함된 //Generate 메서드를 호출 GetComponent<CubeGenerator>().Generate(); } } } } }
- 오브젝트의 인스턴스가 로드됐을 때 한번 호출됩니다. 씬에 배치된 게임 오브젝트에 추가된 스크립트라면 씬이 시작 될 때 호출되고 프리팹에 추가된에 추가된 스크립트라면 인스턴스로 만들어진 직후에 호출됩니다. 단, 비활성화일 때에는 호출되지 않고 처음 활성화 된 시점에 호출됩니다.
- Awake 메서드가 호출된 시점에서 생성될 오브젝트의 인스턴스는 모두 생성된 상태가 되므로 이 시점에서 다른 오브젝트를 참조할 수는 있습니다. 그러나 각 오브젝트에 연관된 Awake 메서드가 호출되는 순서가 정해진 것이 아니므로 참조되는 쪽 오브젝트와 관련된 처리가 아직 끝나지 않았을 수도 있습니다. 따라서 이 시점에서 다른 오브젝트로부터 어떤 정보를 얻어내려고 시도하는 일은 피하는 것이 좋습니다.
- Awake 메서드에서는 자신의 초기화를 하고 나서 다른 오브젝트로 연결되는 참조를 얻어내기만 하고 다른 오브젝트로부터 정보를 얻어내는 일은 나중에 호출되는 Start 메서드에서 하는 것이 바람직할 것입니다.
- 첫 프레임이 지나가기 전에 한번만 호출됩니다.
- 게임오브젝트가 활성화되어 있는 동안 고정 프레임마다 호출됩니다.
- 게임 오브젝트가 활성화되어 있는 동안 프레임마다 호출됩니다.
- 프레임마다 Update 메서드가 처리를 끝내면 LastUpdate 매서드가 호출됩니다. Update 메서드에서 변경된 내용을 처리에 반영하고 싶을때 사용합니다.
*============================================================================= - UI 요소도 게임 오브젝트 형태로 구성되므로 씬 내부에 구축해야 한다.
- 씬 내부에 있는 UI는 UI요소를 렌더링하는 캔버스와 이벤트 시스템에 의해 제어된다.
- UI 요소의 위치와 크기느 Rect Transform 컴포넌트로 제어한다.
- 모든 UI는 Rect Transform 컴포넌트에 의해 위치와 크기가 제어 됩니다. 이 장에서는 이들 컴포넌트에 관한 자세한 내용과 UI의 기본적인 레이아웃, 이벤트 시스템에 관해 설명하겠습니다.
- Button 오브젝트를 생성하면 Canvas 오브젝트는 자동으로 생성되고 Canvas오브젝트는 자동으로 Button오브젝트의 부모요소가 됨. 또한 EventSystem 오브젝트도 생성됩니다.
- 캔버스는 Canvas 컴포넌트가 추가된 게임 오브젝트를 말합니다. 모든 UI요소의 부모가 되는 요소이며 이름 그대로 그림을 그리는 캔버스 처럼 UI요소를 화면에 렌더링 하는 기능을 제어 합니다.
- 어떤 UI요소를 렌더링 하기 위한 캔버스는 보통 한 개만 있으면 충분합니다. 그러나 다른 UI에 오버레이해서 표시하는 UI처럼 여러 개의 캔버스를 배치할 수도 있습니다. 그리고 캔버스의 자식 요소에 다시 캔버스를 넣어서 종속 시킬수도 있습니다.
- 캔버스 위에 있는 Ui 요소가 렌더링 되는 순서는 매우 명확합니다.
- 하이어라키 뷰에 나열된 순서대로 렌더링 됩니다
- 즉 하이어라키 뷰에서 위쪽에 있는 요소가 먼저(안쪽에) 렌더링 되고 하이어라키 뷰에서 아래쪽에 있는 요소가 나중에(앞쪽에)렌더링 됩니다. 포토샵과 정반대순
- 이러한 렌더링 순서는 UI가 부모 자식의 계층 형태를 이루고 있을때도 동일하게 적용되며, 자식 요소는 부모 요소보다 나중에 렌더링 됩니다.
- 즉 아래쪽에 있는 게임오브젝트 일수록 화면에서 가장 위에 표시됨.
- 스크립트로도 렌더링 순서를 변경 할 수 있습니다.
- 스크립트로 렌더링 순서를 변경하려면 아래 코드에 나온 것처럼 Transform 클래스(또는 이 클래스를 상속한 클래스인 RectTransform 클래스)에 포함된 SetAsFirstSibling메서드, SetAsLastSibling 메서드, SetSibling Index 메서드를 사용합니다.
❏ 스크립트로 렌더링 순서 변경하기 //obj가 현재 위치한 계층에서 가장 먼저 렌더링 되도록 한다(가장 안쪽에 렌더링 된다) obj.transform.SetAsFitstSibling();
//obj가 현재 위치한 계층에서 가장 나중에 렌더링 되도록 한다.(가장 바깥쪽에 렌더링 된다) obj.transform.SetAsLastSibling();
//obj를 현재 위치한 계층에서 3번째 요소가 되는 위치에 놓는다(안쪽에서 부터 3번째로 렌더링 된다) obj.transform.SetSiblingIndex(2); |
- 유니티 메뉴얼 참고
- 캔버스 모드 3가지 설명 튜토리얼
- 3가지 모드
- Screen Space -Overlay,
- Screen Space - Camera,
- World Space
- 캔버스를 부모 자식 관계로 계층화한 상태에서 자식 캔버스의 렌더링 모드는 부모 캔버스의 렌더링 모드를 동일하게 따릅니다.
- Screen Space - Overlay 모드

- 캔버스가 씬 내부의 어느 곳에 있더라도 화면 전체를 덮는 모습으로 렌더링 된다.
- 이는 지금까지 사용해왔던 UI시스템인 유니티GUI가 렌더링한 UI화면과 닮았습니다.
- 화면(게임뷰)의 크기가 해상도가 변경되면 그에 맞춰서 캔버스의 크기도 자동으로 변경됩니다.
- Pixel Perfeck : 체크 : 캔버스에 있는 UI요소를 픽셀의 색 그대로 표현하도록 렌더링합니다. 이 속성은 ON으로 지정하면 픽셀이 맞지 않는 위치에 배치하더라도 희미하지 않고 명확하게 표현할 수 있습니다.
- 그러나 무거울수 있다. 대부분의 UI요소가 스케일,회전 , 애니메이션 등에서 미세한 위치나 배율을 사용할 가능성이 큰데, 여기서 기기의 퍼포먼스를 높여야할 때는 Pixel Perfect속성을 off로 지정해두는 것도 좋을 것 입니다.
- Sort Order : 캔버스가 렌더링 되는 순서를 수치로 설정할 수 있습니다. 값이 작을수록 먼저(안쪽에) 렌더링 되고, 값이 클수록 나중에 (바깥쪽에) 렌더링 됩니다.

- Screen Space - Camera 모드에서 캔버스는 지정된 카메라와 일정한 거리만큼 떨어진 앞쪽 위치에 배치되고 카메라에 의해 렌더링 됩니다.
- 따라서 UI요소가 어떻게 표현될지는 카메라가 어떻게 설정돼 있는지에 따라 달라집니다.
- 카메라의 Projection 속성이 Perspective로 지정돼 있다면 UI요소는 원근감이 느껴지게 렌더링 됩니다. (원금감의 정도는 Field of View 속성값에 따라 달라집니다.)
- 화면(게임뷰)의 크기나 해상도가 변경되거나 카메라이ㅡ 뷰포트가 달라지만 이에 맞춰 자동으로 캔버스도 카메라를 정면으로 바라보도록 크기와 위치와 방향이 변경됩니다.
- Pixel Perfect
- Render Camera : 캔버스를 렌더링할 카메라를 지정합니다.
- Plane Distance : 카메라에서 캔버스까지의 거리를 설정합니다.
- Sorting Layer : 소팅레이어란 2D 스프라이트를 포함한 2D 그래픽 렌더링하는 순서를 제어하는 기능을 말합니다. 소팅 레이어를 사용하면 카메라로 부터 그래픽 요소까지의 거리(Z좌표)와 상관없이 렌더링 순서를 제어할 수 있습니다.
- Sorting Layers - Unity - sort 레이어 관련 튜토리얼(레이어 별로 sort 값을 정할수 있고 레이어 내에서도 코드에서 렌더링을 조절할 수 있다.
- Order In layer : 캔버스의 소팅 레이어 순서 안에서 다시 렌더링 순서를 설정합니다. 값이 작을 수록 (안쪽에) 렌더링 되고 값이 클수록 나중에(바깥쪽에)렌더링 됩니다.


- 캔버스는 씬에 있는 다른 게임 오브젝트와 동일한 자격으로 취급됩니다. 캔버스의 크기는 화면(게임뷰)의 크기와 상관없이 Rect Transform 컴포넌트에 따라 정의됩니다.
- 캔버스에 있는 UI요소는 씬에 있는 다른 게임 오브젝트와 함께 3D 공간에서의 위치 관계대로 렌더링 됩니다.
- Event Camera : 이벤트를 처리하기 위한 카메라를 지정합니다. 이벤트에 관해서는 CHAPTER 2-3 이벤트 시스템과 4-2이벤트에서 자세하게 설명하겠습니다.
- Sorting Layer → Order in Layer : 캔버스에 지정한 소팅 레이어대로 렌더링 순서를 설정하고 소팅 레이어 안에서 다시 렌더링 순서를 Order in Layer에 설정합니다.
- Canvas Scaler 컴포넌트는 캔버스에 추가된 컴포넌트 입니다. 캔버스 안에 있는 UI요소 전체의 스케일과 픽셀 밀도를 제어합니다. 폰트 크기나 이미지에 포함된 선의 너비 등 캔버스에서 렌더링 되는 모든 요소에 영향을 줍니다.
- Constant Pixel Size
- Scale With Screen Size
- Constant Physical Size : 물리적인 단위로 설정.
- World : 렌더링 모드가 World 일때 고정되는 값
이미지 해상도, 픽셀의 크기- 참고 사이트 - UI요소의 위치나 크기가 화면상 픽셀 단위에 의해 설정 됩니다. 이 동작은 Canvas Scaler 컴포넌트가 추가돼 있지 않을때 기본으로 지정되는 동작입니다. UI를 픽셀 크기에 맞춰 표시할 때는 이 모드를 선택합니다.
Scale With Screen Size 모드
- UI요소의 위치나 크기는 지정된 참조 해상도(Reference Resolution)에 따라 설정이 달라집니다. 먼저 참조 해상도로 UI를 생성한 다음에 해상도가 다른 장치에서 UI를 확대하거나 축소해 표시하려면 이 모드를 선택합니다.
- Reference Resolution : 생성할 UI의 기준이 되는 참조 해상도를 Reference Resoulution에 설정합니다. UI를 생성할 때 게임 뷰의 해상도를 참조 해상도와 동일하게 지정해두면 참조 해상도로 UI를 레이아웃할 수 있어 편리합니다.
- Match Width Or Height : 참조 해상도의 너비나 높이에 맞춰 캔버스를 스케일 합니다. 참조 해상도의 너비와 높이 중 어느쪽에 맞출지는 나중에 설명할 Match 속성에 설정합니다. 0.5로 설정하면 배율로 증가?
- Match : Screen Match Mode 속성이 MAtch Width Or Height일 때 참조 해상도의 너비와 높이 중 어느 쪽에 맞출지 설정합니다. 값의 범위는 0,0 ~1.0입니다. 값이 0,0 일때에는 참조 해상도의 너비에 맞추고 값이 1.0일때에는 참조 해상도의 높이에 맞춰캔버스의 스케일을 설정합니다. 값이 0,0~1.0 사이 일때는 그 값으로 참조 해상도의 너비에 맞춘 스케일과 참조 해상도의 높이에 맞춘 스케일 사이에 있는 스케일 값을 사용합니다.
- Unity - Manual: Designing UI for Multiple ...
- Expand : 캔버스의 영역을 넓혀서 캔버스의 너비와 높이 모두 참조 해상도보다 작아지지 않게 설정합니다.
- Shrink : 캔버스의 영역을 오려 캔버스의 너비와 높이 모두 참조 해상도를 넘지 않게 합니다.
Constant Physical Size 모드
- UI 요소의 위치나 크기는 센티미터, 밀리미터, 인치, 포인트, 파이카등의 물리적인 단위로 설정됩니다.
- Constant Physical Size 모드에서는 다음과 같은 속성을 설정할 수 있습니다.
- Physical Unit : UI요소의 위치나 크기를 설정할 물리 단위를 지정합니다. 물리 단위는 다음과 같은 다섯 가지 종류로 지정할 수있습니다.
- 센티미터, 밀리미터, 인치, 포인트, 파이카
- Fallback Screen DPI : Constant Physical Size 모드는 화면의 DPI(Dot per Inch : 1인치당 도트수) 값을 장치로 부터 제대로 얻어올 수 있다는 것을 전제로 하는데 DPI값을 얻어 올수 없을 때는 Fallback Screen DPI라는 속성값이 사용됩니다.
- Default Sprite DPI : Pixels Per Unit이 Reference Pixels Per Unit 속성값과 동일한 스프라이트의 1인치당 픽셀 수를 설정합니다.
- Reference Pixels Per Unit : 캔버스의 렌더링 모드가 World space 일때 UI Scale Mode 속성은 World로 고정됩니다.

- 유니티에 포함된 이벤트 시스템의 핵심이라고도 할 수 있는 레이캐스트라는 기능이 있습니다. 레이캐스트란 어떤 좌표로 부터 다른 좌표를 향해 레이(Ray)라는 가상의 직선을 쏴서 씬에 있는 오브젝트와 충돌하는지 검출하는 기능입니다.
- Graphic Raycaster 컴포넌트를 통해서 현재 사용자가 조작하고 있는 UI요소가 캔버스 에서 어느 UI인지 판정합니다.
- Ignore Reversed Graphics : 이 속성을 ON으로 지정하면 뒤집혀서 뒷면이 보이는 요소는 무시합니다.
- Blocking Objects : 레이캐스트를 블록하는(막는) 오브젝트의 타입을 지정합니다. 다음 네 종류의 오브젝트 타입 중 하나를 지정 할 수 있습니다.
- None(없음)
- Two D (2D 오브젝트)
- Three D (3D 오브젝ㅌ)
- All (모든 오브젝트)
- Blocking Mask : 레이캐스트를 블록하는 오브젝트의 레이어를 지정합니다. Blocking Objects 속성에 지정한 오브젝트 타입이면서 Blocking Mask 속성에 지정한 레이어에 속한 오브젝트가 레이캐스트를 블록합니다.
- Canvas Renderer 컴포넌트
- 캔버스 그룹
- 캔버스 그롭(Canvas Group)을 사용하면 여러 개의 UI 요소를 그룹화해서 특정 속성을 한꺼번에 변경할 수 있습니다.
- 캔버스 그룹을 생성하려면 빈 게임 오브젝트를 생성하고 인스펙터 뷰 아래쪽에 있는 Add Component 버튼을 누른 뒨 Layout → Canvas Group를 선택해 Canvas Group 컴포넌트를 추가합니다.
- 여러 개의 UI 요소를 캔버스 그룹의 자식 요소로 지정하면 CanvasGroup 컴포넌트의 속성을 이용해 자식이 된 UI요소들의 특정 속성을 한 꺼번에 변경할 수 있습니다.
- Canvas Group컴포넌트에서는 다음과 같은 속성을 설정할 수 있습니다.
- Alpha : 캔버스 그룹에 포함된 모든 UI요소의 알파값(불투명도)을 설정합니다. 여기에는 0.0 ~1.0(불투명)범위에 있는 값을 설정합니다.
- 각 Ui요소에 알파값이 설정돼 있다면 Alpha 속성값과 각 UI요소의 알파값을 곱한 값이 적용됩니다. 예를 들어 여러 개의 버튼을 포함하고 있는 윈도 형태의 UI를 페이드인/페이드 아웃 시킬때 유용하게 사용됩니다.\
- Interactable : 캔버스 그룹에 포함된 모든 UI 요소의 유효/무효상태를 설정합니다.
- ON으로 지정하면 모든 UI요소를 조정할 수 있게 되고 OFF로 지정하면 모든 UI요소를 조정할 수 있습니다.
- Blocks Raycasts : 캔버스 그룹에 포함된 모든 UI 요소가 레이캐스트를 블록할지(충돌판정을 허가할지) 설정합니다. ON으로 지정하면 캔버스 그룹에 속한 UI요소는 레이캐스트를 블록하지 않으므로 UI요소를 조작할 수 없게됩니다.
- HUD(Head -UP Display/ 화면에 겹쳐지는 형태로 정보를 표시하는 UI)에 정보를 표시하거나 인디케이터처럼 표시만 하고 사용자가 UI를 조작할 수 없게 만들고 싶을때 유용합니다.
- Ignore Parent Groups : 캔버스 그룹이 계층화돼 있을 때 이 속성을 On으로 지정하면 부모 캔버스 그룹에 설정된 속상값을 무시합니다.
*============================================================================
- Pos X, Pos Y : 피봇 위치의 좌표를 앵커로부터의 상대좌표를 표시합니다.
- Pos Z : 요소의 Z 좌표를 설정합니다.

- Width, Height : UI 요소의 너비와 높이를 설정합니다.

- Left, Top, Right, Bottom : 앵커가 붙어있지 않고 떨어졌을때 Pos X, Pos Y, Width, Height 속성에 대신하여 설정하는 수치기능. 부모 요소(or 앵커)의 좌변, 윗변, 우변, 아랫변으로 부터 UI요소의 좌변, 윗변, 우변, 아랫변까지의 거리를 각각 설정합니다.
 
- Anchors : 앵커의 위치를 설정 → 다음장에 자세히 설명
- Pivot : 피봇의 위치를 설정합니다. Rect Transform의 너비와 높이에 대한 상대적인 위치이며 값의 유효 범위는 X,Y 모두 0.0~1.0이다. 예를 들어 X =0.0 , Y=0.0은 Rect Transform의 왼쪽 아래를 나타내고 X=1.0, y=1.0은 오른쪽 위를 나타냅니다.
  
- 앵커란 배에서 쓰이는 닻을 의미하며 닻 처럼 Rect Transform의 핸들을 새로운 UI 요소의 특정 위치에 고정해주는 기능이 있습니다.
- 앵커를 사용하면 데스크 톱이나 스마트폰, 태블릿과 같은 다양한 화면 해상도를 지원하는 반응형 UI를 생성할 수 있습니다.
- 네 개의 앵커 핸들을 각각 드래그 해서 이동 시킬수 있습니다.
- 앵커가 닫혀 있을 때 앵커의 삼각형 네 개 또는 두개의 한가운데를 드래그하면 해당 삼각형을 한꺼번에 이동시킬수 있습니다.
- shift 키를 누르면서 한 개의 핸들을 드래그 하면 각 모서리에 대응하는 Rect Transform 핸들도 앵커 핸들과의 거리를 유지하면서 이동합니다.
- 앵커 핸들을 부모 요소의 영역안에서 상대적인 위치를 나타내므로 부모 요소가 리사이즈 되는 값에 맞춰 이동합니다.
- 그리고 네 개의 앵커 핸들은 각각 Rec Transform 에서 네 개의 핸들에 대응돼 있어서 앵커 핸들과 Rect Transform 핸들 사이의 거리를 유지하면서 동작합니다.
- 따라서 부모 요소의 크기를 조정하면 그에 연동하여 자동으로 UI요소의 위치나 크기를 조정할 수 있습니다.
- 예를 들어 내 개의 앵커 핸들을 모두 부모 요소의 중앙으로 설정하면 부모 요소의 크기를 변경하더라도 UI요소는 항상 부모 요소의 중앙에 배치됩니다.
- 만약 네 개의 앵커 핸들을 모두 부모 요소의 오른쪽 아래 모서리로 설정하면 UI 요소와 부모 요소 사이에 오른쪽과 아래쪽 마진(여유공간)이 고정됩니다. 따라서 부모 요소의 크기를 조정하더라도 UI요소와 부모 요소의 오른쪽 아래 모서리 부터의 상대적인 위치는 변하지 않습니다.
- 자주 사용하는 애커 설정은 앵커 프리셋에서 빠르게 선택할수 있습니다.
- 앵커 프리셋에서
- shift키를 누른 상태로 프리셋을 선택하면 앵커의 설정함과 동시에 피봇을 이동시킬 수 있습니다.
- alt 키를 누른 상태로 선택하면 앵커를 설정함과 동시에 UI 요소의 위치와 크기도 변경할 수 있습니다.
- shift + alt 키를 함께 누른 상태로 선택하면 피봇도 이동시키고 UI요소의 위치와 크기도 변경 하게 됩니다.

- Blueprint모드 버튼
- Raw edit 모드 버튼
- Blueprint 모드를 on으로 지정하면 회전이나 스케일을 적용한 이미지라도 회전이나 스케일 조정이 않은 상태의 가상의 축으로 조정할 수있다.
 
- Raw eidt 모드를 on으로 지정하면 Anchors 속성이나 pivot속성값이 변경됏을때 Left,Top,Right,Bottom 값이 변하지 않는다.
게임 오브젝트와 Rec Transform 컴포넌트
- 빈 게임 오브젝트 생성 단축키 shift + ctrl + n
- 자식 게임 오브젝트 생성 단축키 : create Empty Child : alt + shift + n
- 부모가 캔버스인 경우 자식 게임 오브젝트를 만들면 자동으로 Rect Transform 컴포넌트가 추가된 오브젝트가 생성된다.
이벤트 시스템- 이벤트 시스템
- Event System 컴포넌트의 동작
- 유니티에는 다음과 같은 4가지 좌표계가 있습니다.
- 월드좌표계 : 씬의 3D 공간에 지정된 절대적인 좌표계입니다. 이 좌표계에서는 게임 오브젝트의 ㅜ이치는 계층 구조에 상관없이 씬의 원점으로부터 좌표를 표현됩니다.
- 스크린 좌표계 :화면(게임뷰)의 왼쪽 아래를 원점으로 하는 좌표계입니다. 여기서 1단위는 1픽셀에 해당합니다.
- 뷰포트 좌표계 : 스키린 좌표계에서의 좌표를 0.0~1.0 사이의 범위로 정규화한 좌표계입니다.
- 로컬 좌표계 : 부모 게임오브젝트의 원점을 기준으로 하는 상대적인 좌표계 입니다. 캔버스에 포함된 UI요소는 앵커의 위치를 기준으로 한 좌표가 됩니다. 인스펙터 뷰에서 Transform 컴포넌트나 Rect Transform 컴포넌트에 표시되는 좌표는 로컬 좌표계로 표현된 좌표입니다.
==============================================================================
- 유니티의 렌더링 엔진이 그래픽 API를 호출하는 것을 드로우 콜이라고 부른다.
- 한 번의 드로우 콜로 렌더링하는 편이 효율이 높으며 배치라고 불리는 처리가 수행된다.
- 렌더링 성능을 최적화하려면 유니티에 포함된 툴을 이용한다.
- 유니티의 렌더링 엔진은 오브젝트를 화면에 렌더링 하기 위해서 OpenGL 이나 Direct3D 등의 그래픽 API에 드로우 콜(Draw call)을 발행합니다. 드로우 콜이 발행될 때마다 그래픽 API가 부담이 큰 처리를 수행해 포퍼먼스 오버헤드가 발생하므로 드로우이라는 것이 매우 값비싼 처리라고 생각하는 사람들이 많습니다. 그러나 실제로는 드로우 콜 자체가 비싼 것은 아닙니다.
- 배치
- 유니티의 렌더링 엔진은 한개의 프레임이 진행되는 동안 많은 폴리곤 메쉬를 특정 순서로 렌더링을 합니다. 폴리곤 메쉬를 렌더링하는 작업은 각각 머터리얼이나 텍스처와 같은 리소스에 의존하므로 현재 렌더링에 사용되고 있는 리소스와 다른 리소스에 의존하는 폴리곤 메쉬를 렌더링 할때에는 리소스를 변경해야 합니다.
- 리소스를 변경하는 작업은 부담이 크므로 동일한 리소스를 사용하는 폴리곤 메쉬를 그룹화해서 될 수 있으면 드로우 콜 한번에 렌더링한다면 효율적일 것입니다. 이 처리를 배치(Batching)라고 부릅니다.
- 리소스를 변경하는 일 중에서도 머터리얼을 변경하는 작업은 세이더를 변경하기 위해서 내부에 있는 렌더링 스테이트를 재구축해야하므로 특별하게 느린 처리입니다. 이 처리를 셋 패스(SetPass)라고 부릅니다.
- 한편 텍스처를 변경하는 작업은 세이더 관련 속성은 변경되지만 내부에 있는 렌더링 스테이트는 변하지 않으므로 드로우 콜이 1개 늘어날 뿐 머터리얼이 변경하는 작업만큼 느린 처리는 아닙니다. 따라서 드로우 콜(배치) 회수를 줄이기보다는 셋 패스 수를 얼마나 줄일 수 있는지가 렌더링 성능 향상에 중요한 사항이라고 말할 수 있습니다.
- UI 요소를 배치 처리하는 것은 각각의 캔버스 (계층화되어 있는 캔버스도 포함) 단위로 수행됩니다. 앞서 이야기한 대로 같은 머터리얼이나 같은 텍스처를 사용하는 요소는 배치됩니다. 그러나 2개의 동일한 머터리얼/텍스처의 요소를 렌더링하는 동안에 다른 머터리얼/텍스처 요소가 렌더링될 때는 배치 처리되지 않습니다. 각 요소가 겹쳐 있지 않을때에는 배치 소팅(Batch sorting) 이라는 기능이 최적화를 수행합니다. 배치 소팅이란 한꺼번에 렌더링할 수 있으며 겹치지 않는 UI요소의 렌더링 순서를 머터리얼이나 텍스처 변경이 최소한으로 이뤄지도록 자동으로 변경하여 배치 작업을 최적화하는 기능을 말합니다.
- 유니티 그래픽 최적화 - 메뉴얼
- 드로우 콜 배칭 - 메뉴얼
- 이전에 설명했던 대로 머터리얼이나 텍스처 변경은 부담이 크므로 가능한 한 그 회수를 줄이는 것이 성능 향성에 도움이 됩니다. 예를 들면, 특수한 이팩트가 필요한 요소에만 특별한 머터리얼을 사용하고, 대부분의 UI요소에는 한 개의 머터리얼을 사용한다든가 스프라이트는 가능한 한 1개의 텍스처 아틀라스에 포함시키는 게 좋습니다. 또한, 다른 폰트를 사용하면 드로우 콜 회수가 증가하므로 삼가는 게 좋습니다.
- 캔버스 상에 렌더링 되는 모든 그래픽 요소에는 Canvas Renderer컴포넌트가 추가돼 있고 이 컴포넌트로 렌더링을 제어합니다. 그래서 요소에 변경을 가하면 머터리얼이나 텍스처가 변경되거나 폴리곤 메쉬끼리 겹치는 부분이 달라진 가능성이 있으므로 배치가 새로 계산 됩니다. 재계산 자체는 그다지 부담이 크지 않지만 될 수 있으면 회수가 적을수록 좋을 것입니다.
- 그리고 계층 구조를 변경하는 것은 부담이 큰 처리 중의 하나입니다. 캔버스에 있는 모든 그래픽 요소의 렌더링 순서를 다시 계산해야 할 뿐 아니라 배치도 다시 계산해야 합니다. 같은 계층에서 순서를 변경하는 것도 이에 해당하므로 될 수 있으면 삼가는 것이 바람직 할 것입니다.
- 그리고 캔버스의 렌더링 모드가 Screen Space -Overlay나 Screen Space - Camera일 때 설정할 수 있는 Pixel Perfect 속성을 On으로 지정하면 그래픽 요소를 픽셀에 맞추도록 렌더링 합니다.
- 이렇게 렌더링 하는 것은 그래픽 요소를 이동시킬 때마다 매번 정점을 다시 생성해야 하므로 부담이 큰 처리가 됩니다. 이동시킬 그래픽 요소를 포함한 캔버스의 Pixel Perfect속성을 OFF로 지정하거나 그래픽 요소를 이동시키기 전에 Off로 지정하고 이동시킨 다음에 On으로 지정하면 렌더링 성능을 향상 시킬 수 있습니다.
- 프레임률 : 현재의 프레임률(Frames Per Second/FPS)과 게임 뷰에서 1개의 프레임을 렌더링하는데 걸리는 시간이 표시됩니다.
- Batches : 배치된 최종적인 드로우 콜 회사가 표시됩니다.
- Saved by batching : 배치때문에 삭제된 드로우 콜 개수가 표시됨.
- Tris Verts : 렌더링되는 폴리곤과 정점의 개수를 표시합니다.
- Screen : 화면 해상도와 메모리 사용량을 표시합니다.
- SetPass calls : 셋 패스(머터리얼 변경)의 개수를 표시합니다.
- Shadow casters : 그림자를 렌더링 하는 횟수를 표시합니다.
- Visible Skinned Meshes : Skinned Mesh Renderer로 렌더링되는 스킨 메쉬의 개수를 표시합니다.
- Animations : 재생되고 잇는 애니메이션의 개수를 표시합니다.
- 상세한 프로파일링에는 프로파일러가 마련돼 있습니다. 프로파일러를 표시하려면 Window 메뉴 → Profiler를 선택합니다.
- 실행 중일 때의 퍼포먼스를 프로파일러의 타임라인에 기록할 수 있습니다.
- CPU 사용률,GPU사용률,렌더링,메모리 사용률,오디오 등등 각 프로파일러가 있어서 필요한 정보만 표시할수 있습니다.
- 렌더링에 관한 프로파일링에 사용하는 렌더링 프로파일러에는 배치의 개수(Batches), 셋패스의 개수(SetPass Calls), 폴리곤의 개수(Triangles), 정점의 개수(Vertices)가 프레임 단위로 기록됩니다.
- 프레임 디버거를 사용하면 특정 프레임에서 렌더링 될때 발생하는 모든 드로우 콜에 대한 상세한 내용을 확인 할 수 있습니다. 프레임 디버거를 표시하려면 Window메뉴 → Frame Debugger를 선택합니다.
- 프레임 디버거 오른쪽에는 드로우 콜과 프레임 버퍼 클리어의 시퀀스가 계층을 이뤄 표시되므로 드로우 콜이 어디서 어떤 순서로 발생했는지 확인할 수 있습니다. 왼쪽에 있는 목록에서 드로우 콜을 선택하면 해당 드로우 콜에 의해 렌더링 되는 폴리곤 메쉬나 사용되는 세이더 등에 관한 자세한 정보그 오른쪽 패널에 표시됩니다. 동시에 게임 뷰에서 씬이 선택한 드로우 콜까지 어떻게 렌더링 되는지에 관한 내용이 표시됩낟. 그리고 프레임 디버거 위쪽에 있는 슬라이더나 좌우 화살표 버튼을 사용하면 리스트에 있는 시퀀스를 한단계씩 진행하거나 되돌리면서 렌더링 순서를 확인 할 수 있습니다.
============================================================================== - 사용자의 조작으로 이벤트가 발생하고 이벤트 리스너가 실행된다.
- 이벤트 리스너는 인스펙터 뷰의 인터랙션 컴포넌트에서 설정할 수 있다.
- Event Trigger 컴포넌트를 사용하면 모든 이벤트를 받아들일 수 있다.
- 인터랙티브 UI요소에 대해 특정한 조작이 이뤄지면 그 조작은 트리거가 되어 미리 설정 해놓은 액션이 실행됩니다.
- 트리거가 되는 조작을 이벤트(Event)라고 부르고 실행시킬 액션을 이벤트 리스너(Event Listener) 또는 단순히 리스너(Listener) 라고 부릅니다.
- 설정할 수 있는 이벤트 리스너는 인터랙션 컴포넌트에 따라 다릅니다. 예를 들어 Butten 컴포넌트는 버튼을 눌렀다가 땠을 때 트리거되는 On Click() 이벤트에 이벤트 리스너를 설정할 수 있고, Slider 컴포넌트는 슬라이더를 조작해서 값이 변했을 때 트리거 되느 On Value Change(Single) 이벤트에 이벤트 리스너를 설정할 수 있습니다.
- 이벤트 리스너를 실행할지 실행하지 않을지 설정합니다.
- off : 이벤트 리스너가 실행되지 않습니다.
- Editor And Runtime : 에디터 모드이거나 플레이 모드일때(각 플랫폼에서 실행 중일때) 이벤트 리스너가 실행됩니다. 예를 들어 에디트 모드일 때 Toggle 컴포넌트에서 Is On 속성을 ON이나 OFF로 지정하거나 Slider 컴포넌트에서 Value 속성값을 변경하면 이벤트 리스너가 실행됩니다.
- Runtime Only : 플레이 모드일때 (각 플랫폼에서 실행 중일때)에만 이벤트 리스너가 실행됩니다.
- 실행하려는 액션을 가진 오브젝트를 드래그 앤드 드롭하거나 오브젝트 피커를 사용해 설정합니다. 오브젝트를 지정하면 해당 오브젝트에 포함된 컴포넌트 클래스 목록이 함수 목록에 나옵니다.
- 오브젝트 필드에 설정한 오브젝트에 추가된 컴포넌트의 클래스 목록이 표시됩니다. 클래스 이름을 선택하면 해당 클래스에 정의되어 실행할 수 있는 액션의 목록이 나옵니다. 그럼 4-9에서는 Canvas Renderer 컴포넌트가 추가된 FaceImage 오브젝트를 지정했고, Canvas Renderer 컴포넌트에 정의된 SetAlpha 메서드를 선택했습니다.
- 함수 목록에서 선택한 액션이 인수가 있는 메서드이거나 속성일때는 액션에 넘겨 줄 값을 설정합니다. 메서드나 속성에 따라 설정할 수 있는 값의 종류가 다릅니다.
- 그림 4- 10에서는 Canvas Renderer 컴포넌트에 정의된 SetAlpha 메서드에 넘겨줄 인수로 0.5라는 수치를 설정했습니다.
- 이처럼 이벤트 리스너를 설정하면 스크립트에 코딩할 필요없이 이벤트에 대한 액션을 실행시킬 수 있습니다.
- 다음은 이미지에 추가된 Canvas Renderer 컴포넌트의 SetAlpha 메서드를 버튼의 OnClik() 이벤트 리스너에 설정한 예제 입니다. 버튼을 누르면 SetAlpha 메서드에 파라미터 필드에서 설정한 값(0.5)이 넘어가서 이미지가 반투명으로 변합니다.
- 하나의 이벤트에 대해 여러 개의 이벤트 리스너를 설정할 수도 있습니다. 여러 개의 이벤트 리스너를 설정한 경우에는 리스트의 위에서부터 순서대로 실행됩니다.
- 앞서 이야기했던 대로 빌트인 컴포넌트 클래스의 정의된 메서드나 속성을 이벤트 리스너 형태로 설정할 수 있습니다. 마찬가지로 독자적으로 작성한 사용자 지정 컴포넌트 클래스에 정의한 메서드나 속성도 이벤트 리스너 형태로 설정할 수 있습니다. 이때도 설정 방법은 같습니다.
- 다음 조건을 만족하는 메서드나 속성은 이벤트 리스너 형태로 설정 할 수 있습니다.
- 인수가 없고 리턴값도 없는(void) public 메서드
- 인수가 한 개이고 리턴값이 없는(void) public 메서드
- 단, 인수의 형은 bool,int,float,string 또는 GameObject나 MonoBehaviour를 포함하는 Object 클래스를 상속한 클래스 일것
- 단, 속성은 형은 bool, int, float, string 또는 GameObject나 MonoBehaviour를 포함하는 Object클래스를 상속한 클래스일 것.
- 앞 조건을 만족하지 않는 메서드나 속성은 함수 목록에 표시되지 않으므로 이벤트 리스너 형태로 설정할 수 없습니다. static으로 지정된 메서드나 속성도 이벤트 리스너 형태로 설정 할 수 없습니다.
// 이벤트 리스너 형태로 설정할 수 있는 속성 public bool BoolExample { get; set; } public int IntExample { get; set; } public float FloatExample { get; set; } public string StringExample { get; set; } public RectTransform RectTransformExample { get; set; }
// 이벤트 리스너 형태로 설정할 수 있는 메서드 public void OnExample() { } public void OnExample(bool param) { } public void OnExample(int param) { } public void OnExample(float param) { } public void OnExample(RectTransform param) { }
// 이벤트 리스너 형태로 설정 할 수 없는 속성 public int IntReadOnlyExample { get { return 1; } } //읽기전용 public int[] IntArrayExample { get; set; } //배열 public double DoubleExample { get; set; } //double 형 public Rect RectExample { get; set;} //구조체 public KeyCode KeyCodeExample { get; set; } //열거형 public System.Array ArrayExample { get; set; } //Object 클래스를 상속하지 않는 클래스
//이벤트 리스너 형태로 설정할 수 없는 속성 public int OnExampleInt() { return 1; } //리턴값이 있다. public void OnExample(int[] param) { } //인수가 배열 형태다. public void OnExample(int param1, int param2) { } //인수가 여러 개다. public void OnExample(Rect param) { } //인수가 열거형이다. public void OnExample(System.Array param) { } //인수가 Object클래스를 상속하지 않는 클래스다 
|
이벤트 리스너는 인스펙터 뷰의 인터랙션 컴포넌트에서 설정할 수 있지만, 스크립트로 작성해 동적으로 설정할할 수도 있습니다. 이벤트 리스너를 스크립트에 설정하려면 인터랙션 컴포넌트의 이벤트속성에 정의돼 있는 AddListener 메서드를 사용합니다. 예를 들어 Button 컴포넌트는 Button클래스에 있는 onClick 속성의 AddListener 메서드로 이벤트 리스너를 추가합니다.
[SerializeField] private Button button;
private void Start() { button.onClick.AddListener(()=>OnClickButton(button)); }
public void OnClickButton(Button sender) { Debug.Log("Button is clicked"); } |
- 인터랙션 컴포넌트의 종류에 따라 설정할 수 있는 이벤트 리스너가 다릅니다. Button 컴포넌트는 OnClick() 이벤트의 이벤트 리스너만 설정할 수 있고 Slider 컴포넌트는 OnValue Changed(Single) 이벤트의 이벤트 리스너만 설정할 수 있습니다. 그리고 본래 인터랙션 컴포넌트가 아닌 이미지나 텍스트에는 이벤트 리스너를 설정할 수 없습니다.
- 정해지지 않은 이벤트 리스너를 인터랙션 컴포넌트에 설정하거나 인터랙션 컴포넌트가 추가돼 있지 않은 오브젝트에 이벤트 리스너를 설정하려면 Event Trigger 컴포넌트를 사용합니다. Event Trigger컴포넌트가 추가된 오브젝트는 이벤트 시스템에 의한 모든 이벤트를 받아들일 수 있게 되어 트리거에 미리 설정해둔 액션을 해당 이벤트로 실행 할 수 있게 됩니다.
- EventTrigger 컴포넌트를 추가하려면 인스펙터 뷰 아랫부분에 있는 Add Component버튼을 누르고 Event → EvenTrigger를 선택합니다.
- 그리고 Add New Event Type버튼을 눌러 받아들일 이벤트를 선택하면 이벤트 리스너 목록이 표시됨.
- 이처럼 Event Trigger 컴포넌트 이용하면 본래 받아들일 수 없는 이벤트에 대해서도 이벤트 리스너를 설정해 액션을 실행시킬 수 있게 됩니다.
- 그러나 Event Trigger 컴포넌트를 추가한 오브젝트는 모든 이벤트를 받아들입니다. 따라서 오브젝트 뒤에 있는 오브젝트에는 이벤트가 전달되지 않으므로 주의해야 합니다.
- 즉 이미지와 버튼이 겹쳐있을때 버튼이 뒤에 위치하면 이벤트가 발생하지 않는다.
- 이벤트 리스너를 스크립트에 설정할 때는 Button 클래스에 포함된 onClick속성(Button,ButtonClickedEvent클래스)의 AddListener메서드를 사용합니다. 인수가 없는 메서드를 Button.ButtonClickedEvent클래스에 포함된 AddListener메서드에 이벤트 리스너 형태로 설정할 수 있습니다.
[SerializeField] private Button button;
private void Start() { button.onClick.AddListener(=>OnClickButton(button); }
public void OnClickButton(Button sender) { Debug.Log("Button is clicked"); } |
|
|