20120510 유니티 유저매뉴얼 v3.0

Download Report

Transcript 20120510 유니티 유저매뉴얼 v3.0

유니티 매뉴얼
유니티에 오신 것을 환영합니다.
유니티는 사용자 분들이 최고의 인터랙티브 환경과 멀티미디어의 경험을 창조하는 것을 돕기 위하여 만들어졌습니다. 이 매뉴얼은
여러분이 유니티를 어떻게 이용하는지 기초부터 고급 테크닉까지 모두 배울 수 있게 해드립니다. 처음부터 끝까지 읽으셔도 좋고
참조용으로 사용하셔도 좋습니다.
이 매뉴얼은 몇가지 다른 섹션으로 나뉘어 있습니다. 첫 섹션, 유저 가이드(User Guide) 는 유니티 인터페이스, 에셋
작업방식(워크플로우), 그리고 게임을 만드는 기초에 대한 소개입니다. 만약 여러분이 유니티를 처음 접하시는 것이라면 유니티
기초(Unity Basics) 안의 섹션들을 읽고서 배우시는 것을 추천해드립니다.
iOS 가이드 (iOS Guide) 는 iOS 특정 스크립팅 API, 최적화, 일반 플랫폼 개발 질문들 등의 iOS 관련 토픽들을 보여줍니다.
안드로이드 가이드 (Android Guide) 는 안드로이드 SDK 셋업과 일반 개발 질문들 등의 안드로이드 관련 토픽들을 보여줍니다.
다음 섹션인 FAQ 는 몇몇 절차들을 밟아야 해결 되는 일반적인 작업 수행 방법들에 관련 흔히 물어보는 질문들을 묶어논 것입니다.
마지막 섹션인 고급 (Advanced) 섹션은 게임 최적화, 셰이더, 파일 크기, 배치 (deployment) 등의 토픽들을 보여줍니다.
그리고 유니티를 사용한 게임 제작의 다양한 가능성들을 자세하게 살펴보기 위해 레퍼런스 매뉴얼 (Reference Manual) 과
스크립팅 레퍼런스 (Scripting Reference) 도 읽어보시기 바랍니다.
만약 찾는 답을 구하지 못하셨을 경우, www.unity3dkorea.com 의 유니티 Q&A 섹션을 이용하시거나 Unity Answers , Unity
Forums 등을 이용하시면 답을 찾으실 수 있습니다..
즐겁게 읽어보시기 바랍니다,
유니티 팀
유니티 매뉴얼 가이드는 특정 플랫폼에만 해당되는 섹션들로 구성되어 있습니다. 보시길 원하는 플랫폼 섹션으로 이동하셔서
보시기 바랍니다.특정 플랫폼 관련 정보는 각 페이지에 보여주기 삼각형을 누르시면 보실 수 있습니다.
목차
•
User Guide
o
유니티 기초

인터페이스 배우기

작업창 커스터마이징

에셋 워크플로우

씬 제작

빌드 퍼블리슁

튜토리얼

유니티 단축키
o
씬 빌딩



o
게임오브젝트

게임오브젝트-컴포넌트 관계

컴포넌트 사용하기

컴포넌트-스크립트 관계
인스펙터 사용하기

값(Value) 속성 수정하기

참조(Reference) 속성 수정하기

인스펙터 옵션
씬 뷰 이용하기

씬 뷰 네비게이션

게임오브젝트 포지션 조정

뷰 모드

기즈모와 아이콘 시각화

검색

프리팹

조명

카메라

파티클 시스템

지형
에셋 임포트와 만들기

에셋 임포트

메쉬

애니메이션

매터리얼

텍스쳐

진행형(Procedural) 매터리얼

비디오 파일

오디오 파일


스크립팅
트랙커 모듈

o
•
에셋 스토어

에셋스토어 들어가기

에셋스토어 네비게이션

에셋스토어 다운로드매니져

에셋 서버

메타데이터 관리 뒷이야기
게임플레이 제작

프리팹 인스턴스화하기

인풋

트랜스폼

피직스

애니메이션 뷰 가이드

애니메이션 스크립팅

사운드

게임 인터페이스 요소들

네트워크 연결된 멀티플레이어
아이폰 시작하기
o
아이폰 기초
o
유니티 리모트
o
아이폰 API

아이폰 인풋

iOS 키보드

iOS 고급

iOS .Net
o
아이폰 하드웨어
o
아이폰 성능


아이폰 그래픽 성능 최적화

아이폰 드로우콜 배치(Batch)

아이폰 최적화된 캐릭터 모델링

아이폰 렌더링 통계
아이폰 피직스 최적화
•

아이폰 스크립트 최적화

아이폰 내부 프로파일러

아이폰 메인룹 최적화

아이폰 플레이어 크기 최적화
o
아이폰 계정 셋업
o
아이폰 미지원 기능
o
아이폰 플러그인
o
아이폰 다운로드 가능 콘텐츠
o
모바일 스플래쉬 스크린 최적화
o
아이폰 문제 해결
o
아이폰 버그 보고
안드로이드 시작하기
o
안드로이드 SDK 셋업
o
안드로이드 리모트
o
안드로이드 문제 해결
o
안드로이드 버그 보고
o
안드로이드 미지원 기능
o
안드로이드 플레이어 세팅
o
안드로이드 API

안드로이드 인풋

안드로이드 키보드

안드로이드 고급

안드로이드 .Net
o
안드로이드 플러그인
o
안드로이드 스플래쉬 스크린
o
안드로이드 테스트 된 기기
o
안드로이드 이클립스와 유니티 연동

•
안드로이드 유니티에서 안드로이드 앱 런칭하기
FAQ
o
버젼 2 에서 3 으로 업그레이드 하는 법

피직스 업그레이드 상세설명

모노 업그레이드 상세설명

렌더링 업그레이드 상세설명

SL-V3 변환
o
현재 버젼에 새로 추가된 것
o
액티베이션
o
게임 코드-하는법

o
1 인칭 게임 만들기
그래픽-하는법

알파맵

노멀맵

디테일텍스쳐 사용

큐브맵 만들기

스카이박스 사용

메쉬파티클에미터

스플래쉬 스크린

라이트쿠키

Z축 위방향 설정 고치기

물
o
FBX 익스포트
o
오브젝트 임포트
o

마야 오브젝트 임포트

시네마 4D 오브젝트 임포트

맥스 오브젝트 임포트

치타 3D 오브젝트 임포트

모도 오브젝트 임포트

라이트웨이브 오브젝트 임포트

블렌더 오브젝트 임포트
워크플로우

모노디벨롭

팩키지 익스포트

스탠다드 에셋 설치
•
고급
o
에셋 번들
o
에셋 데이타베이스
o
렌더링패쓰
o
프로파일러
o
라이트맵핑

라이트맵핑 상세설명

라이트맵핑 커스텀세팅

라이트맵핑 UV
o
오클루젼 컬링
o
런타임시 리소스 로딩
o
스크립팅을 통해 소스 에셋 수정하기
o
순차적인 메쉬 도형(Geometry) 생성

메쉬의 구조

메쉬 클래스 사용하기

예: 빌보드 평면 만들기
o
실행 순서
o
그래픽 성능 최적화

최적화된 캐릭터 모델링

렌더링 통계
o
파일 사이즈 줄이기
o
플랫폼 종속적 컴파일
o
디버깅

콘솔

디버거

로그 파일

숨겨진 폴더 접속
o
플러그인
o
커맨드 라인 아규먼트(Arguments)
o
셰이더

셰이더 튜토리얼 1

셰이더 튜토리얼 2
o
그래픽스 에뮬레이션
o
네트워크 에뮬레이션
o
보안 샌드박스
o
사용가능한 .NET 클래스 라이브러리들에 대한 개요(준비중.내용없음)
o
비쥬얼 스튜디오 통합
o
외부 버젼 컨트롤 시스템 지원
o
분석
o
버젼 확인
o
문제 해결
•
IME 인풋
•
그림자
o
방향성 광원(Directional Light) 그림자 상세설명
o
그림자 문제 해결
o
그림자 크기 상세설명
o
통합 그래픽 카드 최적화
•
웹 플레이어 스트리밍
•
웹 플레이어 배포(Deployment)
o
유니티 웹 플레이어 콘텐츠를 로드하기 위한 HTML 코드
o
유니티 오브젝트 이해하기
o
유니티 웹 플레이어 로딩 화면 커스터마이징
o
웹플레이어 행동방식(Behavior) 태그
o
유니티 웹 플레이어와 브라우져 커뮤니케이션
o
웹 플레이어 템플릿 사용하기
유저 가이드
메뉴얼의 이 섹션은 유니티의 기능과 함수에 중점을 둡니다. 인터페이스, 코어 유니티 빌딩 블락, 에셋 워크플로워 그리고 기본
게임 플레이 생성을 다룹니다. 유저 가이드를 다 읽어 갈때 쯤이면 어떻게 상호작용하는 씬을 통합하고 그것을 퍼블리슁 하는지에
대한 확실한 이해를 가지게 될 것입니다.
새로운 유저는 Unity Basics 섹션 부터 읽기를 권장합니다.
•
•
유니티 기초
o
인터페이스 배우기
o
작업창 커스터마이징
o
에셋 워크플로우
o
씬 제작
o
빌드 퍼블리슁
o
튜토리얼
o
유니티 단축키
씬 빌딩
o
o
o
•
게임오브젝트

게임오브젝트-컴포넌트 관계

컴포넌트 사용하기

컴포넌트-스크립트 관계
인스펙터 사용하기

값(Value) 속성 수정하기

참조(Reference) 속성 수정하기

인스펙터 옵션
씬 뷰 이용하기

씬 뷰 네비게이션

게임오브젝트 포지션 조정

뷰 모드

기즈모와 아이콘 시각화
o
검색
o
프리팹
o
조명
o
카메라
o
파티클 시스템
o
지형
에셋 임포트와 만들기
o
에셋 임포트
o
메쉬
o
애니메이션
o
매터리얼
o
텍스쳐
o
진행형(Procedural) 매터리얼
o
비디오 파일
o
오디오 파일

•
트랙커 모듈
o
스크립팅
o
에셋 스토어

에셋스토어 들어가기

에셋스토어 네비게이션

에셋스토어 다운로드매니져
o
에셋 서버
o
메타데이터 관리 뒷이야기
게임플레이 제작
o
프리팹 인스턴스화하기
o
인풋
o
트랜스폼
o
피직스
o
애니메이션 뷰 가이드
o
애니메이션 스크립팅
o
사운드
o
게임 인터페이스 요소들
o
네트워크 연결된 멀티플레이어
유니티 기초
이 섹션은 Unity 와의 시작을 위한 키 입니다. 극서은 Unity 인터페이스, 메뉴 아이템, 에셋 사용법, 씬 생성 그리고 빌드를 출판하는
것을 설명할 것입니다.
사용자가 이 섹션을 읽는 것이 끝내질 때 사용자는 Unity 가 어떻게 작동하는지 그것을 어떻게 효과적으로 사용하는지 그리고
기본적임 게임을 함께 놓는 과정등을 이해하게 될 것입니다.
Learning the Interface
Publishing Builds
배울게 많이 있어서 사용자는
언제든지 사용자가 사용자의 게임을
인터페이스를 관찰하고 이해하기
생성하는 동안 사용자는 사용자가
위해 시간을 들일 필요가 있습니다.
독립형 또는 웹 플레이어로 편집기
우리는 각 인터페이스 요소들을
밖에서 그것을 빌드할 때 그것이
다룰 것입니다.
어떻게 보이는지 보고싶을지도
모릅니다. 이 섹션은 그 빌드 세팅에
어떻게 접근하는지 그리고 사용자
Asset Workflow
게임의 다른 빌드를 어떻게
생성하는지 설명할 것입니다.
여기서 우리는 Unity 와 함께 하나의
에셋을 사용하는 단계를 설명할
것입니다. 이러한 단계들은
Tutorials
일반적이고 기본적인 행동을 위한
개요로서 여겨집니다.
이러한 온라인 튜토리얼은 실제
프로젝트를 구축하면서 체험을
Creating Scenes
제공하면서 사용자가 따라하는 동안
Unity 와 작업하게 해줍니다.
씬은 사용자 게임의 오브젝트를
포함합니다. 각 씬에서 사용자는
사용자의 게임을 디자인하고
구축하면서 사용자의 환경, 장애물,
그리고 장식등을 위치하게 합니다.
인터페이스 배우기
처음 시작
유니티 배우기를 시작합시다. 유니티를 아직 열지 않았다면, 윈도우에서 Start->Programs->Unity 를 찾을 수 있고, 맥에서는
Applications->Unity 에서 찾으실 수 있습니다. 시작하면 유니티 Editor 가 보일 것 입니다. 시간을 가지고 유니티 에디터의
인터페이스를 점검해 보시고, 익숙하게 만드시길 바랍니다. Main Editor Window 는 몇몇 Tabbed Windows 로 구성되는데
Views 라고 일컫습니다. 유니티에는 몇몇 타입의 뷰가 있는데, 각각의 목적을 가지고 있습니다
프로젝트 뷰
모든 유니티 프로젝트는 Assets 폴더를 가집니다. 이 폴더의 내용은 프로젝트 뷰에 표시됩니다. 게임을 구성하는 모든 asset(씬,
scripts, 3D models, textures, audio files, Prefabs)이 저장되어 있는 곳입니다. 프로젝트 뷰에서 어떤 자산이든 오른쪽 클릭을 하여
Reveal 을 누르면(MS 윈도우에서는 Reveal in Explorer / 맥에서는 Reveal in Finder), 파일 시스템에서 자산 자체를 볼 수 있습니다.
중요사항: 프로젝트 asset 을 OS 를 이용해서 옮기지 마십시오. 이는 asset 과 관련된 메타데이터의 파괴를 야기할 수 있습니다. 항상
프로젝트 뷰를 사용해서 asset 을 구성/관리하십시오.
asset 들을 프로젝트에 추가하기 위해서는, OS 에 있는 파일을 드래그하여 프로젝트 뷰로 옮겨놓습니다. 또는 Assets->Import New
Asset 를 사용합니다. 이제 asset 은 게임에서 사용할 준비가 되었습니다. Asset 작업을 위한 더 자세한 정보는 이 매뉴얼의 Asset
Workflow 섹션을 참고 바랍니다.
Scenes 은 프로젝트 뷰에 저장됩니다. 이들을 개개의 레벨로 생각하십시오. 예를 들어, Islands Scene 는 유니티가 처음 시작할 때
기본적으로 불려집니다. 새로운 Scene 을 만들기 위해서는 Control-N (Mac 에서 Command-N)을 누르십시오. 프로젝트 뷰에 현재의
Scene 을 저장하기 위해서는 Control-S (Mac 에서 Command-S)를 사용하십시오.
몇몇 게임 asset 들은 유니티 안에서 생성될 필요가 있습니다. 이를 위해서는 Create 드롭 다운이나 right click->Create 을
사용하십시오.
Create 드롭다운
이는 프로젝트를 구성하기 위해서 스크립트들을 추가하거나, Prefabs, 또는 폴더들을 추가하게 합니다. 윈도우에서는 F2 를
눌러서(맥에서는 Enter) asset/folder 의 이름을 바꿀 수 있습니다. 또는 asset 이름에 일정한 속도의 두 번 클릭으로도 이름 바꾸기가
가능합니다. 디렉토리(뷰)를 줄이거나 확장할때 Alt 키를 누르고 계시면, 모든 하위 디렉토리들도 줄이거나 확장됩니다
계층구조
Hierarchy 는 현재의 씬에 있는 모든 GameObject 를 포함합니다. 이들 중의 일부는 3D 모델들과 같은 asset 파일들의 직접적인
인스턴스입니다. 그리고, 나머지들은 Prefabs(게임을 구성하는 custom 오브젝트들)의 인스턴스도 포함합니다. 계층구조에서 부모
오브젝트들을 선택할 수 있습니다. 오브젝트들이 씬에서 추가되고 삭제됨에 따라서, 계층구조에서도 또한 보이고 사라집니다.
양육
유니티는 Parenting 의 개념이 있습니다. 어떤 GameObject 도 다른 오브젝트의 자식으로 만들려면, 선택한 자식 오브젝트를
계층구조내의 대상 부모 오브젝트로 드래그합니다. 자식 오브젝트는 부모의 동작과 회전을 상속받습니다. 이제 게임에 영향을
미치지 않고, 계층구조 내에서 부모(뷰)를 확장하거나 줄여서 볼 수 있습니다.
양육되지 않는 두 오브젝트들(Two unparented objects)
하나의 오브젝트가 다른 하나의 오브젝트로 양육됨
양육에 대해서 더 알고자 한다면 Transform Component page 의 양육 섹션을 검토하십시오.
Toolbar
툴바는 5 개의 컨트롤을 가지고 있습니다. 각각 에디터의 다른 부분과 관련 있습니다.
변환 툴들-- 씬 뷰에 사용됩니다
변환 장치 토글들-- Scene View 의 표시에 영향을 줍니다
Play/Pause/Step 버튼들 -- 게임 뷰와 함께 사용됩니다
계층별 드롭다운 Layers Drop-down -- Scene View 어떤 오브젝트들이 진열될지 컨트롤 합니다
Layout Drop-down -- 모든 뷰에서의 제어들을 진열합니다
씬뷰
씬뷰
Scene View 는 상호작용적인 (놀이)툴 상자 입니다. 씬 뷰로 플레이어, 카메라, 적들, 그리고 모든 GameObjects 의 환경을 정하고
위치 시킬 수 있습니다. 오브젝트들을 씬뷰에서 움직이고 다루는 것은 유니티의 가장 중요한 기능입니다. 그러므로, 씬 뷰를 사용할
수 있는 것은 매우 중요합니다.
씬 뷰 다루기
씬 뷰 다루기 Scene View Navigation 의 모든 세부사항은 링크에 포함되어 있습니다. 아래는 간략한 핵심 부분의 소개 입니다:
•
Flythrough 모드로 들어가기 위해서 오른쪽 마우스 버튼을 누르고 계세요. 이는 마우스를 돌리고 WASD 키들(추가로 Q(up)와
E(down))을 빠른 일인칭 뷰 다루기로 들어가게 합니다.
•
임의의 GameObject 를 선택하시고 F 키를 누릅니다. 이는 씬 뷰를 중심에서 중심 회전축의 선택이 되게 합니다.
•
화살 키를 사용해서 X/Z 평면 주위를 움직입니다.
•
Alt 키를 누른 상태에서 현재의 중심점 주위로 카메라 궤도 순항을 위해 click-drag 합니다.
•
Alt 키를 누른 상태에서 Scene View 카메라 주위를 드래그 하기 위해서 가운데 click-drag 를 합니다.
•
Alt 키를 누른 상태에서 씬 뷰를 줌 하기 위해서 오른쪽 click-drag 를 합니다. 이는 마우스 휠을 스크롤링 하는 것과 같습니다.
특히, 원버튼 마우스를 사용하시면 Hand Tool (shortcut: Q)에서 사용을 찾으실 수 있습니다. Hand 도구가 선택된 상태에서
카메라 주위를 드래그 하기 위해서 Click-drag 합니다.
Alt 키를 누른 상태에서 Scene View 카메라 주위를 드래그 하기 위해서 가운데 click-drag 를 합니다.
카메라를 줌 하기 위해서 Control (맥에서 Command)을 상태에서 click-drag 합니다.
씬 뷰의 위 코너에는 Scene Gizmo 가 있습니다. 이는 씬 카메라의 현재 오리엔테이션을 표시하며, viewing angle 을 빠르게 변화할
수 있게 해줍니다.
씬 카메라를 지정장소로 잡아채기(snap) 위해서는 팔 들의 아무 부분을 클릭할 수 있습니다. 그런 후 Isometric Mode 로 바꿉니다.
Isometric 모드에서는, 궤도를 돌기 위해 오른쪽 클릭 드래그를 할 수 있으며, Alt 클릭 드래그로 회전할 수 있습니다. 이 모드에서
나오려면, 씬 장치의 가운데를 클릭하십시오. Isometric Mode 를 토글하기 위해서는 씬 뷰의 가운데를 언제든 Shift 클릭을 하십시오.
GameObjects 를 위치 시키기
씬에서의 GameObjects 를 위치시키는 것의 세부 사항은 Positioning GameObjects 페이지를 참조 하십시오. 아래는 핵심적인
사항의 개요입니다:
게임을 만들 때, 게임의 세상에 많은 다른 종류의 오브젝트들을 위치 시킵니다. 툴바의 변환 툴을 이용하여, 개개의 GameObjects 를
변환, 회전, 비율 조정합니다. 각각은 상응하는 씬 뷰에서 선택된 GameObjects 주위에 보이는 장치(Gizmo)를 가지고 있습니다.
마우스를 사용하여 GameObjects 의 Transform 컴포넌트를 바꾸기 위해서는 어떤 Gizmo 축도 다룰 수 있습니다. 또는, 인스펙터
내의 변환 컴포넌트의 숫자 입력란으로 값을 직접 넣으실 수 있습니다.
씬 뷰 컨트롤바
씬 뷰 컨트롤 바는 다양한 뷰 모드(Textured, Wireframe, RGB, Overdraw 등등)에서 씬을 보게 합니다. 씬 뷰에서 게임내의
라이팅(lighting), 게임 요소 및 사운드를 보거나 듣게 해줍니다. 세부 사항을 위해서 뷰모드 View Modes 를 참조 하십시오.
게임 뷰
Game View 게임에서 Cameras 로부터 표현(render) 됩니다. 게임 뷰는 마지막, 공표된 게임(published game)의 대표로 작용합니다.
플레이어가 게임 하는 동안 실제로 보는 것을 컨트롤 하기 위해서는 하나 또는 다수의 카메라를 필요로 할 것입니다. 카메라에 관한
더 많은 정보를 얻으시려면 Camera Component page 페이지를 참조하십시오.
플레이 모드
에디터의 Play Mode 를 컨트롤 하기 위해서는 툴바의 버튼들을 사용하십시오. 그리고, 공표된 게임이 어떤 식으로 플레이 되는지
살펴보십시오. 플레이모드 동안은, 어떤 변화를 만들건 일시적이며, 플레이 모드를 빠져 나가면 리셋 됩니다. 에디터 UI 는
상기시키기 위해서 어둡게 처리 할 것입니다.
게임 뷰 컨트롤 바
게임 뷰 컨트롤 바의 첫 번째 드롭 다운은 Aspect Drop-down 입니다. 게임 뷰 창의 상(aspect) 비율을 다른 값으로 바꿀 수 있습니다.
게임이 다른 상 비율로 어떻게 보이는지 테스트 하기 위해 사용됩니다.
더 오른쪽에는 플레이 토글위의 Maximize on Play 가 있습니다. 가능하게 만들면, 게임 뷰는 에디터 윈도우에서 100% 크기로
확장되어, 플레이 모드 시 전체화면 미리 뷰를 할 수 있습니다.
오른쪽으로 더 가게 되면 Gizmos 토글이 있습니다. 가능하게 하면, 모든 Gizmo 들이 씬 뷰에 등장하며, 게임 뷰에서도 그려집니다.
이는 Gizmos 클래스 함수들을 사용하여 Gizmo 들로 그려진 것들을 포함합니다.
마지막으로 Stats 버튼이 있습니다. 이는 렌더링 통계 (Rendering Statistics) 윈도우를 보여주는데, 그래픽 성능을 최적화 (Optimizing
Graphics Performance) 하는데 매우 유용합니다.
게임의 게임뷰 상태
Inspector
유니티내에서의 게임들은 다중의 GameObjects 들로 구성됩니다. 이 GameObjects 들은 메쉬들, 스크립트들, 사운드들, 또는
Lights 과 같은 다른 그래픽 요소들을 포함합니다. Inspector 는 모든 부착된 Components 과 그들의 속성을 포함하는 현재 선택된
GameObject 의 세부화된 정보를 표시합니다. 여기서 씬내에 GameObject 의 기능을 변경합니다. 이 개념을 이해하는 것은 매우
중요하므로 더 많은 정보를 위해서 GameObject-Component relationship 페이지를 참조해서 읽을 수 있습니다.
인스펙터 내의 표시된 속성은 직접 변경이 가능합니다. 어떤 스크립트 변수들도 스크립트 자체를 바꾸지 않고 수정이 가능합니다.
인스펙터를 사용해서 실행 시에 변수들을 변경할 수 있습니다. 이는 게임에서 탁월한 게임 플레이를 실험하고 찾기 위해서 입니다.
스크립트 내에서, 오브젝트 종류(GameObject 나 Transform) 의 공공 변수를 정의하면, GameObject 나 Prefab 을 드래그 & 드롭으로
인스펙터에 할당 할 수 있습니다.
인스펙터 내에서 컴포넌트 참조 페이지를 열기 위해서는 컴포넌트 이름 주위의 물음표마크를 클릭하십시오. 유니티 컴포넌트의
자세하고 완벽한 참조 가이드를 위해서는 컴포넌트 레퍼런스 Component Reference 를 참조 하세요.
Component 메뉴로부터 컴포넌트들 추가
특정 컴포넌트의 컨텍스트 메뉴를 부르기 위해서는 작은 장치(gear) 아이콘을 클릭하거나 컴포넌트 이름을 오른쪽 클릭합니다.
인스펙터는 선택된 자산 파일을 위한 가져오기 설정을 보여줄 것입니다.
Apply 를 클릭해서 자산을 다시 불러오기(reimport) 합니다.
렌더링 레이어를 GameObject 에 할당하기 위해서는 Layer drop-down 을 사용합니다. 태그를 GameObject 에 할당하기 위해서는
Tag drop-down 을 사용합니다.
Prefabs
Prefab 을 선택하면, 몇몇 추가 버튼이 인스펙터에서 사용가능 해 집니다. Prefabs 에 관한 더 많은 정보를 원하시면 Prefab manual
page 를 참조하십시오.
다른 뷰들
이 페이지에 묘사된 뷰들은 유니티에서의 인터페이스의 기본적인 사항을 설명합니다. 유니티에서의 다른 뷰들은 또 다른
페이지들에서 설명됩니다:
•
The Console 는 메시지들, 경고, 에러들의 로그를 표시합니다.
•
The Animation View 는 씬에서 오브젝트들로 애니메이션 만들때 사용됩니다.
•
The Profiler 는 게임에서 성능의 병목현상(bottle-neck)을 찾고 조사하는데 사용됩니다.
•
The Asset Server View 는 유니티의 자산 서버를 사용해 프로젝트의 버전 컨트롤을 관리하는데 사용됩니다.
•
The Lightmapping View 는 유니티의 내장된 lightmapping 을 사용하여 lightmap 들을 관리하는데 사용됩니다.
•
The Occlusion Culling View 는 성능 향상을 위해서 오클루젼 컬링(Occlusion Culling)을 관리 하는데 사용합니다.
Customizing Your Workspace
사용자는 뷰(View)의 탭을 여러 위치 중 하나의 위치에 클릭하여 드래그해 놓으므로써 View 의 Layout 을 사용자 정의할 수
있습니다. 기존창의 Tab Area 에 탭을 가져다 놓음으로써 다른 기존의 탭 옆에 탭을 추가할 수 있습니다. 다른 방법으로, 탭을 Dock
Zone 에 가져다 놓으면 새로운 창에 뷰를 추가할 수 있습니다.
뷰는 기존창의 옆이나 아래에 도킹(dock)될 수 있습니다
탭은 메인 에티터창에서 분리될 수 있으며 자신만의 하나의 움직일 수 있는 창으로 배열될 수 있습니다. 이런 창들은 메인
에디터창처럼 뷰나 탭의 배열을 가질 수 있습니다.
움직일 수 있는 에디터창은 툴바가 없다는 것만 제외하면 메인 에티터창과 같습니다
에디터 창의 레이아웃을 만들었을 때, 언제튼 그 레이아웃을 저장하고 불러올 수 있습니다. 레이웃을 드랍다운(툴바에 있음)을
확장하고 Save Layout...을 누르고 레이아웃 이름을 넣고 저장합니다. 불러오기는 그 드랍다운에서 선택하여 하실 수 있습니다.
완성된 사용자 정의 레이아웃
언제든 최대화 또는 새로운 탭 추가등의 추가적인 선택사항을 보고 싶으면 탭을 오른쪽 클릭을 합니다.
에셋 Workflow
여기서는 유니테에서 하나의 에셋을 사용하는 단계를 설명합니다. 이 단계는 일반적이고 기본 행동의 개요로만 의미가 있습니다.
예를 들어, 3D mesh 에 관해 말해보겠습니다.
다듬어 지지 않은 에셋 생성하기
다음어 지지 않은 사용자 에셋을 생성하기 위해 지원되는 아무 3D 모델 패키지나 사용하세요. 여기서는 마야를 사용합니다. 저장이
준비될 때까지 에셋에서 작업을 하세요.
불러오기
에셋을 처음 저장할 때 프로젝트 폴더안의 Assets 폴더에 저장하여야 합니다. 유티니 프로그램을 열때 에셋이 지워지고 프로젝트로
불려질 것입니다 .Project View 를 볼때 에셋이 저장한 곳에 위치한 것을 보게될 것입니다. 유니티는 사용자 모델을 FBX 파일
포멧으로 바꾸기 위해 사용자 모델 패키지가 제공하는 FBX 내보니기를 사용합니다. 다른 방법으로 그 프로그램에서 FBX 를 직접
내보내서 프로젝트 폴더에 저장할 수 있습니다.
불러오기 설정
Project View 에서 에셋을 선택하면 그 에셋의 불러오기 설정이 Inspector 에 나타납니다. 그 보여지는 설정은 선택된 에셋의 타입에
따라 바뀌게 됩니다
씬에 에셋 추가하기
프로젝트 뷰에서 메쉬를 클릭하고 Hierarchy 또는 Scene View 로 드래그해서 씬으로 추가하세요. 메쉬를 씬으로 드래그하면 메쉬
렌더러 Component 를 가지는 GameObject 를 생성합니다. 사용자가 텍스쳐나 사운드 파일로 작업을하면 그것을 씬이나
프로젝트에 이미 존재하는 GameObject 에 추가하여야 합니다.
다른 에셋 함께 넣기
여기 가장 흔한 에셋들의 관계에 대한 설명이 있습니다.
•
텍스쳐는 재질 Material 에 적용 됩니다
•
재질은 GameObject (Mesh Renderer Component 와 함께) 에 적용됩니다
•
애니메이션은 GameObject (Animation Component 와 함께) 에 적용됩니다
•
사운드 파일은 GameObject (Audio Source Component 와 함께) 에 적용됩니다
Prefab 생성하기
Prefabs 은 사용자 씬에서 재사용가능한 GameObjects 와 Components 의 집합입니다. 몇개의 동일한 객체는 하나의 Prefab 에서
생성될 수 있고 이것을 인트턴스화라고 합니다. 나무를 예로 들어보세요. 나무 Prefab 를 생성하는것은 사용자가 몇개의 동일한
나무를 인스턴스화하고 씬에 위치시키는 것을 가능하게 합니다. 모든 그 나무들은 Prefab 에 연결되어 있기 때문에 Prefab 에서의
모든 변화는 자동으로 모든 나무 인스턴스에 영향을 줍니다. 그래서 메쉬, 재질, 다른것 들을 수정하기를 원하면 Prefab 에서
수정을하면 모든 다른 나무들은 그 변화를 상속합니다. 사용자는 또한 인스턴스에 변화를 줄수도 있는메뉴에서 GameObject->Apply
Changes to Prefab 를 선택하세요. 이것은 사용자의 설정 에셋 업데이트 시간을 줄여줍니다.
사용자가 여러개의 컴포넌트를 가진 GameObject 와 하위 GameObject 의 계층 구조를 가지고 있으면 가장 높은 레벨의
GameObject(root)의 Prefab 를 만들수 있으며 GameObject 전체를 재사용할 수 있습니다
Prefab 를 GameObject 구조의 청사진이라 생각해 보십시오. 모든 Prefab 의 복제는 그 청사진과 일치해야합니다. 그러므로 청사진이
업데이트되면 모든 복제들도 그렇게 됩니다. Prefab 를 업데이트할 수 있는 다른 방법이 있는데 복제를 업데이트하고 그 것을
청사진에 적용시키는 것입니다. Prefab 의 업데이트에 관한 좀더 자세한 사항은 Prefabs 를 참조하세요
사용자 씬에 있는 GameObject 에서 실제로 Prefab 를 만들려면, 프로젝트 뷰에서 새로운 prefab 를 만드세요. 원하는 prefab 이름을
만듭니다. 씬에서 Prefab 를 만들고 싶은 게임 객체를 클릭하세요. 그리고 새로운 prefab 에 드래그 하면 게임 객체의 이름이
파란색으로 변하는 것을 볼 수 있습니다. 이제 재사용 가능한 prefab 가 만들어 졌습니다
에셋 업데이트
사용자 에셋을 불러오고, 인스턴스화하고 prefab 에 링크하였습니다. 이제 사용자의 소스 에셋을 편집하고 싶으면 프로젝트 뷰에서
그것을 더블 클릭하세요. 적절한 프로그램이 시작이되고 원하는 변화를 주세요. 엡데이트가 끝나면 저장하세요. 그리고 유니티로
돌아오면 그 변화가 탐지되고 그 에셋은 다시 불려집니다. Prefab 의 그 에셋에 대한 링크도 관리되어질 것입니다. 그래서 prefab 도
엡데이트 되는 것을 볼수 있습니다. 이것이 에셋 업데이트에대해 알아야할 전부 입니다. 열기를 한후 저장하세요!
옵션 – 에셋에 레이블 추가하기.
사용자 에셋을 잘 관리하기 위해서는 항상 에셋에 레이블을 붙이는 것이 좋습니다. 레이블이 있으면 프로젝트 뷰나 객체 설렉터에서
탐색 필드를 이용해 레이블로 에셋을 찾을 수 있습니다.
에셋에 레이블을 추가하는 스텝:
•
레이블을 주고싶은(프로젝트 뷰에서) 에셋을 선탁하세요.
•
에셋에 레이블이 없다면 Inspector 에서 "Add Label" 아이콘)을 누르세요.
o
에셋에 레이블이 있다면 레이블이 있는 곳을 클릭하세요.
•
레이블을 쓰세요.
주의:
•
어떤 에셋에도 하나 이상의 레이블을 줄 수 있습니다.
•
레이블을 구분하거나 생성하고 싶으면 레이블 이름을 쓰는 도중 space 나 enter 를 누르세요.
Creating Scenes
Scenes 는 사용자 게임의 물체들을 포함합니다. 그들은 메인 메뉴, 개별적인 레벨 등을 생성하기 위해서 사용될 수 있습니다. 고유한
레벨로서 각각 고유한 씬 파일을 생각해 보십시오. 각 씬에서 사용자는 특히 사용자의 게임을 디자인하고 구축하면서 사용자의 환경,
장애물 그리고 장식들을 놓을 것입니다.
Instancing Prefabs
Prefab 을 생성하기 위한 마지막 섹션에서 설명된 방법을 사용합니다. 일단 사용자가 하나의 Prefab 를 생성하면 사용자는
Instance 라고 불리는 Prefab 의 복사본을 빠르고 쉽게 만들 수 있습니다. Prefab 의 인스턴스를 생성하기 위해서 Project View 에서
Hierarchy 또는 Scene View 로 그 Prefab 를 드래그 합니다. 이제 사용자는 사용자가 좋아하는 위치에 사용자의 Prefab 의 고유한
인스턴스를 가집니다.
Adding Component & Scripts
사용자가 Prefab 또는 어떠한 강조된 게임오브젝트를 가질 때 사용자는 Components 를 사용해서 그것에 추가적인 기능을 추가할
수 있습니다. 모든 다른 컴포넌트에 대한 디테일을 위해서 Component Reference 를 살펴보시기 바랍니다. Scripts 는 컴포넌트
타입입니다. 하나의 컴포넌트를 추가하기 위해서 사용자의 게임오브젝트를 하이라이트 하고 Component 메뉴로 부터 하나의
컴포넌트를 선택합니다. 사용자는 게임오브젝트의 Inspector 에서 그 컴포넌트가 나타나는 것을 볼 것입니다. 스크립트는
기본적으로 Component 메뉴에 포함됩니다.
컴포넌트를 추가하는 것이 그것의 Prefab 으로 게임오브젝트의 연결을 부순다면 사용자는 메뉴로 부터 링크를 재정립하기 위해서
항상 GameObject->Apply Changes to Prefab 를 사용할 수 있습니다.
Placing GameObjects
일단 사용자의 게임오브젝트가 씬에 있다면 사용자는 그것을 사용자가 원하는 어느 곳에다 놓기 위해서 Transform Tools 을 사용할
수 있습니다. 부수적으로 사용자는 위치와 회전을 튜닝하기 위해서 인스펙터에서 Transform 값을 사용할 수 있습니다.
게임오브젝트들을 자리잡게 하고 회전하게 하는 것에 대한 더 많은 정보를 위해서 Transform Component page 를 살펴보시기
바랍니다.
Working with Cameras
Cameras 는 사용자 게임의 눈입니다. 플레이할 때 플레이어가 볼 모든 것은 하나 또는 그 이상의 카메라를 통해서 입니다. 사용자는
카메라를 위치잡게 하고 회전하고 다른 게임오브젝트처럼 부모를 정합니다. 카메라는 그것에 부착된 Camera 컴포넌트와 함께 있는
게임오브젝트 입니다. 그러므로 그것은 일반적인 GameObject 가 할 수 있는 것은 무엇이든 할 수 있고 몇개의 카메라 특정 기능들도
할 수 있습니다. 사용자가 새로운 프로젝트를 생성할 때 기본 에셋 패키지에 설치된 몇몇 도움이 되는 카메라 스크립트도 있습니다.
사용자는 메뉴로부터 Components->Camera-Control 에서 그것들을 찾을 수 있습니다. 이해하기에 좋을 카메라로의 부수적인
측면들도 있습니다. 카메라에 대해 읽기 위해서 Camera component page 를 살펴봐 주세요.
Lights
몇몇 케이스를 제외하고 사용자는 사용자의 씬에 항상 조명을 추가할 필요가 있을 것입니다. 3 가지 다른 종류의 조명이 있습니다.
그들 모두는 서로가 약간 다르게 작동합니다. 중요한 것은 그들이 사용자의 게임에 공기와 주변을 추가한다는 것입니다. 다른 조명은
사용자의 게임의 분위기를 완전하게 바꿀 수 있습니다. 그리고 조명을 효과적으로 사용하는 것은 배우기에 중요한 주제입니다. 다른
조명에 대해서 읽기 위해서 Light component page 를 참고해 주세요.
Publishing Builds
게임을 만드는 중 어느 때에도, 독립적 또는 웹 플레이어로서 에디터의 바깥에서 빌드하고 실행시켰을 때 어떻게 보일 지 알고 싶을
수도 있습니다. 이 절에서는 Build Settings 들을 어떻게 접근하고, 게임의 다른 빌드들을 어떻게 생성하는지 설명할 것입니다.
빌드 설정창을 접근 하는 메뉴 아이템은 File->Build Settings...입니다. 게임을 빌드 할 때 장면들에 포함될 사항들의 수정 가능한
리스트들이 (클릭 시)나타날 것입니다.
빌드 설정들 창
프로젝트 내에서 처음으로 이 창을 보면, 비어(blank) 보일 것입니다. 이 리스트가 비었을 때 게임을 빌드하면, 오직 현재의 열린
장면(scene)이 빌드에서 포함될 것 입니다. 하나의 장면파일로 테스트 플레이어의 빠른 빌드를 원하시면, 간단히 플레이어를 빈 장면
리스트로 빌드하십시오.
장면 파일들을 다중 장면 빌드들의 리스트에 추가하는 것은 쉽습니다. 그들을 추가하는 데는 두 방법이 있습니다. 첫 번째 방법은
Add Current 버튼을 클릭 하는 것입니다. 리스트에서 현재 열린 장면이 나타나는 것을 볼 수 있습니다. 장면 파일들을 추가하는 두
번째 방법은 Project View 에서 장면 파일들을 드래그해서 리스트로 놓는 것입니다.
이 시점에서, 각 장면은 다른 인덱스 값을 가집니다. Scene 0 이 게임을 빌드 했을 때 로드(load)될 첫 번째 장면입니다. 새로운
장면의 로드를 원하시면, 스크립트 내에서 Application.LoadLevel()을 사용하십시오.
하나의 장면 파일 이상을 추가했고, 그들을 재 정렬 하고 싶으시면, 리스트 (아이템들) 위나 아래에 장면들을 드래그 해서 원하는
순서에 놓으십시오.
리스트에서 장면의 제거를 원하시면, 장면 highlight 를 클릭하시고 Command-Delete 를 누르십시오. 그러면, 그 장면은
리스트로부터 사라지고 빌드 내에서 추가 되질 않을 것입니다.
빌드를 퍼블리쉬 할 준비가 되었을때 Platform 을 선택하고, 유니티 로고가 플랫폼 옆에 있음을 확인하세요. 그렇지 않으면 Switch
Platform 버튼을 클릭하시고 유니티가 어떤 플랫폼을 위해 빌드를 할지 알려야 합니다. 마지막으로, Build 버튼을 누르십시오. 표준
Save 대화장을 사용하여, 게임의 이름과 장소를 선택할 수 있을 것입니다 Save 버튼을 유니티는 게임을 즉시 빌드 합니다. (빌드
과정은) 이처럼 간단합니다. 만약 빌드된 게임을 어디에 저장해야 할 지 확실히 모르겠으면, 빌드된 게임을 프로젝트 루트 폴더로
저장하는 것을 고려해보십시오. 빌드된 게임을 애셋(Asset) 폴더에는 저장할 수 없습니다.
어떤 독립 플레이어의 Debug build 체크박스를 가능하게 표시하면 Profiler 기능을 가능하게 합니다. 추가로, 플레이어는 디버그
심볼들과 함께 빌드 되어, 써드 파디(3rd party) 프로파일링이나 디버깅 툴들을 사용할 수 있습니다.
Desktop
Web Player Streaming
웹 플레이어들을 스트리밍하는 것은 웹 플레이어 게임들이 장면 0 을 로드 하자마자 (게임) 플레이를 시작하게 합니다. 만약 10 개의
레벨을 가진 게임이 있으면, 레벨 1 의 플레이를 시작할 수 있기 전에, 플레이어를 기다리게 하고 레벨 2-10 사이의 애셋들의
다운로드를 강제 시키는 것은 그다지 이치에 맞지 않습니다. 스트리밍 웹 플레이어(Streaming Web Player)를 퍼블리쉬하는 것은,
다운로드 되어야 할 애셋들이 그들이 보이는 Scene 파일의 순서로 나열 될 것입니다. 모든 장면 0 을 포함하는 애셋들의 다운로드가
마치자 마자, 웹 플레이어는 (게임) 플레잉을 시작 할 것입니다.
간단하게 말하면, 스트리밍 웹 플레이어들(Streaming Web Players)은 플레이어가 게임을 이전 보다 더 빠르게 플레이하게 하도록
합니다.
걱정해야 할 유일한 일은 로드를 원하는 다음 레벨이 (로드 되기 전에) 스트리밍을 마쳤다는 것을 확인 하는 것입니다.
일반적으로, 스트림 되지 않는 플레이어에서는, 레벨을 로드 하기 위해서 다음의 코드를 사용합니다:
Application.LoadLevel("levelName");
스트리밍 웹 플레이어에서는, 레벨이 스트리밍을 끝마쳤는지 먼저 체크합니다. 이는 CanStreamedLevelBeLoaded() 함수를 통해서
이루어집니다. 아래는 어떻게 작용되는지 설명합니다:
var levelToLoad = 1;
function LoadNewLevel () {
if (Application.CanStreamedLevelBeLoaded (levelToLoad)) {
Application.LoadLevel (levelToLoad);
}
}
플레이어에 레벨 스트리밍 전개의 프로그레스(progress)를 원한다면 (로딩 바(loading bar), 또는 다른 식의 표현), 이
GetStreamProgressForLevel() 함수를 접근해서 프로그레스(progress)를 읽을 수 있습니다.
Offline webplayer 배치
만약 오프라인 배치 옵션이 웹 플레이어에 가능화 되면, UnityObject.js 파일(플레이어를 호스트 페이지에 인터페이스 하는데 사용)이
빌드 시에 플레이어에 쪽에 위치될 것입니다. 이는 플레이어가 네트워크 연결이 없을 시라도 로컬 스크립트 파일과 작용을 가능하게
합니다. 일반적으로, UnityObject.js 이 최신버전의 사용을 위해서 유니티의 웹서버로부터 다운로드 됩니다.
독립 플레이어를 빌드하기
유니티를 사용해서, 윈도우나 맥(Intel, PowerPC, 또는 두 아키텍트 모두에 실행하는 Universal) 시스템들을 위한 독립(standalone)
어플리케이션들을 빌드 할 수 있습니다. 이는 빌드 설정 대화창에서 빌드 타겟(target)을 정하고 'Build'를 누르는 간단한 문제입니다.
독립 플레이어를 빌드 할 때에, 결과 파일들은 빌드 타겟에 따라서 다양합니다. 윈도우에서는 실행 파일(.exe)들이 해당
어플리케이션을 위한 리소스들을 모두 포함하는 Data 폴더와 함께 빌드 될 것입니다. 맥에서는 어플리케이션을 실행하기 위해서
필요한 파일과 리소스들을 포함하는 app 묶음(app bundle)이 빌드 될 것입니다.
맥에서 독립 플레이어를 배포하는 것은 app 묶음을 제공하는 것입니다. (모든 것이 그 묶음으로 싸여져 있습니다.) 윈도우에서는
다른 사람들이 실행할 수 있게 .exe 파일과, Data 폴더의 제공이 필요합니다. 다음과 같이 생각하시길 바랍니다: 게임을 실행하기
위해서는 유니티가 빌드하는 결과 파일들로서 다른 사람들도 그들의 컴퓨터에 같은 파일들을 가지고 있어야 합니다.
빌드 과정 내부
빌드 과정은 우선 지정한 위치로 빌드 된 게임 어플리케이션의 빈 복사본을 위치 시킬 것입니다. 그 다음은, 빌드 설정들의 장면
리스트를 통하여 작업하며, 한번에 하나씩 에디터로 열기를 수행하고, 최적화 시키며, 하나의 어플리케이션 패키지로 통합시킬
것입니다. 포함된 장면들에 필요한 모든 애셋들을 계산하고, 어플리케이션 패키지 내에서 그 데이터를 분리된 파일로 저장 할
것입니다.
•
장면에서 'EditorOnly'로 태그된 어떤 GameObject 도 퍼블리쉬된 빌드에는 포함되지 않을 것입니다. 이는 마지막 게임에 포함될
필요가 없는 스크립트들을 디버깅하는데 유용합니다.
•
새로운 레벨을 로드 할 때, 이전 레벨의 모든 오브젝트들은 소멸됩니다. 이를 막기 위해서는 소멸을 원하지 않는 오브젝트(들)에
DontDestroyOnLoad() 함수를 사용합니다. 이는 레벨을 로드 시 또는 게임 상태를 유지하고 진행하는 게임 컨트롤러 스크립트를
위한 뮤직 플레잉(music playing)을 유지하기 위해 종종 사용합니다.
•
새로운 레벨을 로드 하는 것이 끝난 후에: OnLevelWasLoaded() 메시지가 모든 활성화된 게임 오브젝트들에게 보내어 질 것입니다.
•
다중 장면이 있는 게임을 생성하기 위한 최선의 방법에 관한 정보는 (예: 메인 메뉴, 하이 스코어(high-score) 스크린, 실제(actual)
게임 레벨들), “Scripting Tutorial.pdf” 파일을 참조하시기 바랍니다.
iOS
아이오에스 빌드 과정 내부
iPhone/iPad 어플리케이션의 빌드 과정은 다음 두 단계로 이루어 집니다:
1.
XCode 프로젝트가 모든 필요한 라이브러리들, 프리컴파일(precompile)된 .NET 코드, 직렬화된 애셋들과 함께 생성됩니다.
2.
XCode 프로젝트는 실제 디바이스 위에 빌드되고 배치됩니다.
"Build settings"대화창에서 "Build"를 누르면, 첫 번째 단계가 수립됩니다. "Build and Run"을 누르면 두 스텝 모두를 수행합니다.
유저가 프로젝트 저장 대화 창에서 이미 존재하는 폴더를 선택하면, 경고 메시지가 표시됩니다. 현재, 선택할 수 있는 두 개의 XCode
프로젝트 생성 모드들이 있습니다:
•
replace - 타겟 폴더로부터의 모든 파일들이 제거되고 새로운 컨텐트들(contents)이 생성됩니다
•
append - "Data", "Libraries"와 프로젝트 루트 폴더는 청소되고, 새롭게 생성된 컨텐트들로 채워집니다. XCode 프로젝트 파일은
최신의 유니티 프로젝트 변화(들)에 따라 업데이트 됩니다. XCode 프로젝트 "Classes" 서브폴더는 사용자 네이티브 코드(custom
native code)를 두기에 가장 안전한 장소로 고려될 수도 있지만, 정기적 백업이 권고됩니다. 첨부 모드(append mode)는 같은 유니티
iOS 버전을 사용하여 생성된 기존의 XCode 프로젝트들을 위해서 지원됩니다.
“Cmd+B” 이 눌러지면, 자동 빌드와 실행 프로세스가 호출되고, 최근의 사용된 폴더가 빌드 타겟으로 간주됩니다. 이 경우
첨부(append) 모드가 디폴트로 간주됩니다.
Android
안드로이드 어플리케이션의 빌드과정은 다음과 같은 두 단계로 이루어집니다:
1.
모든 필요한 라이브러리들과 직렬화된 애셋들과 함께 어플리케이션 패키지(.apk 파일)가 생성 됩니다.
2.
어플리케이션 패키지는 실제 디바이스에 배치(deploy)됩니다.
""Build" 가 "Build settings" 대화 창에서 눌러지면, 첫 번째 단계가 이루어 집니다. "Build and Run" 을 누르면 두 단계 모두가
수행됩니다. “Cmd+B” 이 눌러지면, 자동 빌드와 실행 프로세스가 호출되고, 최근의 사용된 폴더가 빌드 타겟으로 간주됩니다.
안드로이드 프로젝트를 빌드하는 첫 번째 시행에서, 유니티는 안드로이드 어플리케이션을 빌드하고 인스톨하는데 필요한
안드로이드 SDK 를 위치 시킬 것을 요청합니다. 이 설정들을 나중에 Preferences 에서 변경 시킬 수 있습니다.
안드로이드에서 app 를 빌드 할 때, 디바이스가 "USB Debugging"을 가지고, 디바이스 설정에는 "Allow mock locations" 체크박스가
표시되어 있는지 확인 해야 합니다.
Android SDK/platform-tools 폴더 내의 adb devices 명령어를 수행해서 운영체제가 디바이스를 볼 수 있도록 보장 시킬 수
있습니다. 이는 맥과 윈도우 운영체제 모두에서 작동합니다.
유니티는 어플리케이션 아카이브(.apk 파일)를 빌드하고, 연결된 디바이스에 그것을 인스톨 시킵니다. 몇몇의 경우에는,
어플리케이션이 iPhone 에서와 같이 자동 시작(autostart)을 수행할 수 없습니다. 그러므로, 스크린을 잠금 해제(unlock) 할 필요가
있습니다. 몇몇의 희귀한 경우는 새로 인스톨된 어플리케이션을 메뉴에서 찾을 수 있는 경우도 있습니다.
Texture Compression
Build Settings 하에서 Texture Compression 옵션을 찾을 수 있습니다. 디폴트로, 유니티는 오버라이드 하는 개개의 질감 포맷
(Texture 2D / Per-Platform Overrides 참조) 을 가지지 않는 질감들의 질감 포맷으로 ETC1/RGBA16 질감 포맷을 사용합니다.
특정 하드웨어 아키텍처를 타겟으로 한 어플리케이션 아카이브(.apk 파일)의 빌드를 원하면, 기본 작동을 오버라이드 하기 위해서
Texture Compression 옵션을 사용할 수 있습니다. 오버라이드 하는 질감 포맷을 사용하는 모든 질감들은 그냥 남겨질 것입니다.
Automatic Compressed 이 설정된 질감들만이 Texture Compression 옵션에서 선택된 포맷을 사용할 것입니다.
어플리케이션이 선택된 질감 압축을 지원하는 디바이스들 위에서 배치(deploy)되는 것을 확인하기 위해서, 유니티는 선택된 특정
포맷을 매칭하는 태그들을 포함하려고 AndroidManifest 를 편집 할 것입니다. 이는 안드로이드 마켓(Android Market) 필터링 방법이
적절한 그래픽 하드웨어를 가진 디바이스들의 어플리케이션을 돕는 것을 가능하게 합니다.
미리 불러오기(Preloading)
퍼블리쉬 된 빌드들은 장면이 불러와 질때, 장면내의 모든 애셋들을 자동으로 미리 불러오기 합니다. 이 규칙의 예외는 장면 0 입니다.
이는 첫 번째 장면은 대게 스플레쉬 스크린(splash screen)으로, 가능한 빠르게 디스플레이(display) 되는 것을 원하기 때문입니다.
모든 컨텐트가 미리 불러오기가 됨을 확인 하기 위해서 Application.LoadLevel(1)을 호출하는 빈 장면을 만들 수 있습니다. 빌드
설정들에서, 이 빈 장면의 인덱스를 0 으로 만드십시오. 모든 다음의 레벨들은 미리 불러오기 될 것입니다.
게임을 빌드 할 준비가 되었습니다
지금까지, 유니티의 인터페이스를 사용하는 법, 애셋을 사용하는 법, 장면들을 생성하는 법, 빌드들을 퍼블리쉬 하는 법을
배웠습니다. 이상적인 게임을 생성하는데 이제 장애물이 없습니다. 더 많은 것을 배워 가는 동안, 여러 가지 도움을 줄만한 자료들을
아래에 소개 하였습니다.
유니티 자체를 사용하는 것에 대해 더 자세히 배우고 싶으시면, 이 매뉴얼을 계속해서 읽으시거나 continue reading the manual,
튜토리얼들 Tutorials 을 참조하십시오.
컴포넌트들에 대해서 더 많이 배우고 싶으시고, 게임 동작들의 기본들(nuts & bolts)에 대해 더 배우고 싶으시면 Component
Reference 페이지를 참조하십시오.
스크립팅에 대해 더 배우고 싶으시면 Scripting Reference 페이지를 참조하십시오.
아트 애셋들(Art assets)을 생성하는 것을 더 배우고 싶으시면, 매뉴얼의 애셋들 섹션 Assets section 을 참조하십시오.
유니티 사용자들과 개발자들의 커뮤니티와 상호 교류 하려면, 유니티 포럼들 Unity Forums을 방문하시길 바랍니다. 질문들을 할 수
있고, 프로젝트를 공유하며, 팀을 구성하고, 원하는 것들을 할 수 있습니다. 우리는 당신이 만드는 놀라운 게임을 보기 원하므로,
포럼들을 한번 이상 꼭 방문하십시오.
Tutorials
이러한 튜토리얼은 사용자가 따라하는 동안 Unity 와 함게 작업하도록 해줍니다. 그들은 실제 프로젝트를 구축하는 것과 함께
사용자에게 체험을 전달할 것입니다. 새로운 사용자를 위해서 그것은 사용자가 GUI Essentials 과 Scripting Essentials 튜토리얼을
먼저 따라하라고 권장할 것입니다. 그 후에 사용자는 그들 중 어떤 것이라도 따라할 수 있습니다. 그들은 모두 PDF 포맷으로 되어
있고 사용자는 그들을 프린트 할 수 있고 따라하거나 Unity 옆에서 읽을 수도 있습니다.
주의: 이러한 튜토리얼은 Unity 의 데스크탑 버전의 사용을 위해 고안되어 졌습니다. 이러한 것들은 Android 또는 iOS
디바이스에서는 작동하지 않을 것입니다 (iPhone/iPad).
사용자는 또한 Unity3D Tutorial's Home Page.를 체크하는 것에 의해 튜토리얼에 대한 가장 최근의 부가적인 것들을 체크할 수도
있습니다
이 페이지는 유니티의 기본 단축키에 대한 개요를 제공합니다. 프린트가 가능한 PDF 파일을 다운로드하기 위해선 이미지를
클릭하세요.
Building Scenes
이 섹션에서는 완전한 게임을 위한 씬(Scene)을 구축하기 위해 사용자가 작업하게될 핵심 요소를 설명합니다.
•
게임오브젝트
o
게임오브젝트-컴포넌트 관계
o
컴포넌트 사용하기
o
컴포넌트-스크립트 관계
•
인스펙터 사용하기
o
값(Value) 속성 수정하기
o
참조(Reference) 속성 수정하기
o
인스펙터 옵션
•
씬 뷰 이용하기
o
씬 뷰 네비게이션
o
게임오브젝트 포지션 조정
o
뷰 모드
o
기즈모와 아이콘 시각화
•
검색
•
프리팹
•
조명
•
카메라
•
파티클 시스템
•
지형
GameObjects
게임오브젝트는 유니티에서 가장 중요한 객체 입니다. GameObject 가 무엇인지 어떻게 사용하는지 이해하는 것은 아주 중요합니다.
이 페이지는 그 모든 것을 설명할 것입니다.
게임 오브젝트란 무엇인가?
게임의 모든 객체는 게임오브젝트입니다. 하지만 게임오브젝트 만으로는 아무것도 할 수 없습니다. 그것이 하나의 캐릭터, 환경,
특수효과가 되기위해서는 특별한 속성이 필요합니다. 그러나 각각의 이 객체는 정말 다른 많은 일들을 합니다. 모든 객체가
게임오브젝트라면 어떻게 우리는 고정된 방과 인터렉티브한 파워 업된 객체를 구분할 수 있을까?
대답은 게임오브젝트는 컨테이너라는 것입니다. 그것은 빛을 맵핑한 섬이나 물리적인 자동차를 이루는 조각들을 담을 수 있는 빈
상자입니다. 그래서 게임오브젝트를 정말로 이해하기 위해서는 그 조각들을 이해해야 합니다. 이런 조각들을
컴포넌트(Component)라고 합니다. 어떤 객체를 만들고 싶은가에 따라서 게임오브젝트에 서로 다른 조합의 컴포넌트들을 넣을 수
있습니다. 게임오브젝트를 빈 요리그릇, 컴포넌트를 게임 플레이를 위한 사용자의 요리법에 쓰이는 재료들이라 생각해 보세요. 또한
스크립트를 이용하여 사용자만의 컴포넌트를 만들수 있습니다.
다음 섹션에서는 게임오브젝트, 컴포넌트, 스크립트 컴포넌트에 대해 읽을 수 있습니다:
•
게임오브젝트-컴포넌트 관계
•
컴포넌트 사용하기
•
컴포넌트-스크립트 관계
The GameObject-Component Relationship
GameObjects 페이지에서 설명하였듯, 게임오브젝트는 컴포넌트를 포함합니다. 게임오브젝트와 그것의 가장 흔한
컴포넌트인 Transform 컴포넌트를 논의하면서 이 관계를 살펴보겠습니다. 아무 유니티 씬을 열고 새로운 게임오브젝트를
만들고(윈도우에서 Shift-Control-N 를 사용하거나 맥에서 Shift-Command-N 를 사용) 그것을 선택 후 인스펙터를 보세요.
빈 게임오브젝트의 인스펙터
빈 게임오브젝트는 이름, 태그 그리고 레이어를 포함합니다. 모든 GameObject 는 또한 Transform Component 를 포함합니다.
The Transform Component
Transform 컴포넌트 없이 게임오브젝트를 만드는 것은 가능하지 않습니다. 이 Transform 컴포넌트를 사용함으로써 게임오브젝트의
Transform 속성을 활성화 하기 때문에 이 컴포넌트가 가장 중요한 컴포넌트 중에 하나입니다. 이것은 게임과 씬뷰에서
게임오브젝트의 위치, 회전 그리고 크기를 정의합니다. 게임오브젝트가 Transform 컴포넌트를 가지고 있지 않으면 그것은 컴퓨터
메모리에 존재하는 약간의 정보에 불과 합니다. 그것은 세상에 존재하지 않는 것과 같습니다.
이 Transform 컴포넌트는 또한 부모자식관계설정 (Parenting)의 개념을 가능하게 하는데 이것은 유니티 에디터에서 사용되며
게임오브젝트와 작업하는데 아주 중요한 부분입니다. Transform 컴포넌트와 상속에 관해 더 자세히 알고 싶다면 Transform
Component Reference page 를 읽으세요.
그외 컴포넌트
Transform 컴포넌트는 모든 게임오브젝트에 중요하기 때문에 모든 게임오브젝트가 하나씩 가지고 있습니다. 그러나
게임오브젝트는 그 이외의 컴포넌트도 가질 수 있습니다.
기본으로 모든 씬에 추가되는 메인 카메라
메인 카메라 게임오브젝트를 보면 그것이 다른 컴포넌트들을 포함하고 있는 것을 볼 수 있습니다. 특히 Camera Component,
GUILayer, Flare Layer, Audio Listener 가 있습니다. 이 모든 컴포넌트는 게임오브젝트에 추가적인 기능을 제공합니다. 그것들
없이는 게임의 그래픽 렌더링이 되지 않을 것입니다. 강체들 (Rigidbodies), 충돌체들 (Colliders), 파티클들 (Particles) 과
오디오(Audio)는 모드 다른 컴포넌트(또는 그들의 조합)이며 어떤 게임오브젝트에도 추가될 수 있습니다.
컴포넌트 사용(Using Components)
컴포넌트는 게임 내에서 오브젝트와 작동에 있어 너트와 볼트와 같은 역할을 합니다. 이는 모든 게임오브젝트의 기능적 부품 입니다.
아직 컴포넌트와 게임오브젝트 간의 관계를 이해하지 못한다면, 먼저 Game Objects 를 읽어보기를 권해드립니다.
게임오브젝트란 여러 가지 컴포넌트를 담는 용기입니다. 디폴트로 모든 게임오브젝트는 자동적으로 Transform 컴포넌트를 가지고
있습니다. 왜냐하면 Transform 은 게임오브젝트가 어디에 위치하며 어떻게 회전하고 크기가 정해지는 가를 결정하기 때문입니다.
Transform 컴포넌트가 없이는, 게임오브젝트는 게임 세상에서 위치를 잃게 됩니다. 한 예로 빈 게임오브젝트을 생성해 보겠습니다.
메뉴에서 the GameObject->Create Empty 을 클릭하고, 새 게임오브젝트을 선택한 후 인스펙터(Inspector)을 확인하십시오.
빈 게임오브젝트도 하나의 Transform 컴포넌트를 가집니다.
인스펙터를 사용하면 해당 게임오브젝트에 어떤 컴포넌트가 부착되어 있는지 항상 확인할 수 있습니다. 컴포넌트가 추가되고
삭제되어도 인스펙터는 항상 어떤 것이 현재 부착되어 있는지를 보여줍니다. 사용자는 인스펙터를 사용하여 (스크립트를 포함하여)
어느 컴포넌트의 속성도 변경할 수 있습니다.
컴포넌트 추가하기(Adding Components)
사용자는 컴포넌트 메뉴를 통하여 선택한 게임오브젝트에 컴포넌트들을 추가 할 수 있습니다. 여기서는 방금 생성한 빈
게임오브젝트에 Rigidbody 을 추가해 보겠습니다. 메뉴에서 Component->Physics->Rigidbody 을 선택하면, 해당 Rigidbody 의
속성이 인스펙터에 나타나는 것을 볼 수 있습니다. 아직 빈 게임오브젝트가 선택되어 있는 동안 Play 을 누르면 사용자는 의외의
것을 보고 놀랄 수도 있습니다. 한 번 해 보시고 빈 게임오브젝트에 Rigidbody 가 어떻게 기능을 추가하는지 확인해
보십시오.( 게임오브젝트의 y-component 는 줄어들기 시작합니다. 이것은 유니티의 물리엔진(physics engine)이 해당
게임오브젝트를 중력 하에 낙하하게 하기 때문입니다).
Rigidbody 컴포넌트가 부착된 빈 게임오브젝트
하나의 게임오브젝트에 사용자는 컴포넌트의 조합을 몇 개라도 부착할 수 있습니다. 어떤 컴포넌트는 다른 컴포넌트와 합하면
최상의 성능을 발휘합니다. 예를 들면, Rigidbody 는 어떤 Collider 와도 작동합니다. Rigidbody 는 NVIDIA PhysX 물리 엔진을 통해
Transform 을 제어하고, 해당 Collider 는 Rigidbody 가 다른 Colliders 와 충돌하고 반응하도록 하여 줍니다. 컴포넌트 조합의 다른
예는 입자 시스템입니다(Particle System). 그 시스템은 Particle Emitter, Particle Animator, 그리고 Particle Renderer 을 사용하여
움직이는 입자 그룹을 생성합니다.
만일 특정 입자 컴포넌트 사용에 대하여 좀 더 알고 싶다면, Component Reference 를 확인하십시오. 사용자는 유니티 내에서
인스펙터의 컴포넌트 해더(header) 위에 작은 “?”을 클릭하여 참조 페이지를 확인 할 수 있습니다.
컴포넌트 편집하기(Editing Components)
컴포넌트의 장점 중 하나는 유연성입니다. 사용자가 게임오브젝트 하나에 컴포넌트 하나를 부착할 때 해당 컴포넌트에는 다양한
속성과 값이 있어 게임 구축 중에 편집기에서 혹은 게임 실행 중에 스크립트로 조절 할 수 있습니다.
아래 이미지를 보십시오. 이것은 오디오 소스 컴포넌트가 하나 부착된 빈 게임오브젝트 입니다. 해당 오디오 소스의 모든 값은
인스펙터에 디폴트 값으로 나타납니다.
이 컴포넌트는 하나의 Reference 속성과 7 개의 Value 속성을 가지고 있습니다. Audio Clip 이 Reference 속성 입니다. 이 오디오
소스가 재생 될 때 Audio Clip 속성에서 가리키고 있는 오디오 파일의 재생을 시도할 것 입니다. 만일 해당 참조가 없으면 재생할
오디오 파일이 없으므로 에러가 발생합니다. 사용자는 해당 파일을 인스펙터 내에서 참조하여야 합니다. 이 작업을 하려면 단지 해당
오디오 파일을 프로젝트 뷰에서 드래그 하여 Reference 속성 위로 놓거나 오브젝트 선택기(Object Selector)을 사용하면 됩니다.
이제 Audio Clip 속성에서 사운드 효과 파일을 가리키고 있습니다.
컴포넌트는 다른 타입의 컴포넌트, 게임오브젝트 혹은 에셋 중 어느 것이든 포함 할 수 있습니다. 더 많은 정보를 확인 하려면
Assigning References 페이지를 참조하시기 바랍니다.
해당 Audio Clip 의 나머지 속성은 모두 Value 속성들입니다. 이 속성들은 인스펙터에서 바로 조절될 수 있습니다. Audio Clip 의 값
속성은 토글, 숫자 값, 드롭 다운 필드가 될 수도 있으며 또한 문자열, 색상, curve, 혹은 다른 타입이 될 수도 있습니다. Value 속성을
변경하고 조절하는 것이 대하여 더 자세한 정보를 알고 싶다면 Editing Value Properties 를 참조하시면 됩니다.
속성 시험하기(Testing out Properties)
사용자 게임이 Play Mode 중이라도, 아무 게임오브젝트 라도 인스펙터에서 자유롭게 속성 값을 변경 할 수 있습니다. 예를 들면,
사용자는 점프의 높이를 여러 가지 다른 높이로 시험해 보고 싶은 경우가 있습니다. 사용자가 스크립트에서 Jump Height 속성을
생성하면 Play Mode 로 들어갈 수 있고, 값을 변경하고 Jump 버튼을 누르고 어떻게 되는지 확인 할 수 있습니다. 그리고 Play
Mode 에서 빠져 나오지 않은 채 다시 값을 바꾸어 수 초 이내로 다시 결과를 볼 수 있습니다. 사용자가 Play Mode 에서 나오게 되면
사용자의 속성은 Play Mode 이전 값으로 회복되어 사용자가 작업한 내용을 잃어버리지 않게 합니다. 이러한 작업 흐름은 사용자가
자유자재로 테스트 할 수 있는 엄청난 성능을 제공합니다. 저희는 사용자의 감동을 보장합니다.
컴포넌트 제거하기(Removing Components)
사용자가 컴포넌트를 제거하고 싶다면, 인스펙터에서 해당 해더(header)이 옵션이나- 오른쪽 클릭을 하여 Remove Component 을
선택하십시오. 혹은 컴포넌트 해더 위에 ? 옆에 위치한 옵션 아이콘을 왼쪽 클릭하십시오. 모든 속성 값은 사라지며 이것은 회복불가
합니다. 그러므로 사용 전에 해당 컴포넌트를 영구 삭제 해야 하는지 신중하게 결정하여야 합니다.
The Component-Script Relationship
script 를 만들고 게임오브젝트에 연결했을 때, 그 스크립트는 게임오브젝트의 인스펙터에 컴포넌트처럼 나타납니다. 이것은
스크립트가 저장될때 컴포넌트가 되기 때문인데 스크립트는 특정 형태의 컴포넌트 인것 입니다. 기술적으로 스크립트는 컴포넌트
형태로 컴파일되고 유니티 엔진에서 하나의 컴포넌트로 다뤄집니다. 즉 기본적으로 스크립트는 사용자가 직접 만드는 컴포넌트
입니다. 그 스크립트의 멤버들을 인스펙터에게 보이도록 정의하며 그것은 사용자가 정의한 어떠한 기능이라도 수행할 것입니다.
스크립트를 생성하고 사용하는 것에 대한 더 자세한 사항은 Scripting 페이지에서 읽을 수 있습니다.
Using the Inspector
인스펙터(Inspector)는 많은 다른 타입의 속성을 보고 편집하는데 사용됩니다.
유니티에서 게임은 메쉬, 스크립트, 사운드 또는 조명과 같은 다른 그래픽적인 요소들을 포함하는 여러개의 게임오브젝트들로
만들어 집니다. 사용자가 계층 뷰나 씬 뷰에서 게임오브젝트들 를 선태할 때, 인스펙터는 그 게임오브젝트들 와 그 안에 있는 모든
컴포넌트 와 재질(Material) 의 Properties 을 보여주고 수정하게 해줍니다. 사용자가 프로젝트 뷰에서 Prefab 를 선택하면 같은 일이
생깁니다. 이런 식으로 사용자는 게임에서 게임오브젝트의 기능을 수정합니다. 이것은 아주 중요하기 때문에 GameObjectComponent relationship 에서 좀더 자세한 것을 읽을수 있습니다.
인스펙터에서 게임오브젝트와 그 안의 컴포넌트, 재료의 속성을 보여줍니다.
사용자가 직접 script 를 작성할 때 이것은 사용자 정의 컴포넌트 타입으로 작동하며 그 스크립트의 멤버 변수는 또한 그 스크립트
컴포넌트가 게임오브젝트에 추가되었을 때 인스펙터에서 직접 편집이 가능한 Properties 으로 드러납니다. 이런 식으로 스크립트의
변수는 스크립트 자체를 바꾸지 않고서도 바뀔수 있습니다.
게다가 인스펙터는 텍스쳐, 3D 모델 그리고 폰트 같은 에셋의 옵션을 보여주는데 사용됩니다. 어떤 씬과 Settings Managers 와 같은
프로젝트 범위의 설정은 또한 인스펙트에서 보여 집니다.
인스펙터에서 보여지는 속성은 직접 수정이 가능합니다. 두 개의 주요 속성 타입이 있습니다: 값(Values)과 참조(References).
•
값(Value) 속성 수정하기
•
참조(Reference) 속성 수정하기
•
인스펙터 옵션
Editing Value Properties
값 속성은 어떤 것도 레퍼런스하지 않고 그들은 그 지점에서 편집될 수 있습니다. 일반적인 값 속성은 숫자, 토글, 스트링 그리고 선택
팝업입니다. 그러나 그들은 색상, 벡터, 커브 그리고 다른 타입일 수도 있습니다.
인스펙터위의 값 속성은 숫자, 체크박스, 스트링 등일 수 있습니다 .
많은 값 속성은 텍스트 필드를 가지고 그들을 클릭하고 키보드를 사용해서 값을 넣고 그 값을 저장하기 위해 Enter 를 누르는 것에
의해 단순히 조정될 수 있습니다.
•
사용자는 또한 숫자 속성옆에 사용자의 마우스를 놓고 왼쪽 클릭할 수 있고 그것을 스크롤 값으로 빠르게 드래그 할 수 있습니다.
•
몇몇의 숫자 속성은 또한 값을 시각적으로 조정하기 위해 사용될 수 있는 슬라이더를 가집니다.
어떤 값 속성은 그 값을 편집하기 위해 사용될 수 있는 작은 팝업창을 엽니다.
Color Picker
Color 타입의 속성은 Color Picker 을 열 것입니다.( Mac OS X 에서 color picker 는 Unity->Preferences 아래의 Use OS X Color
Picker 를 활성화하는 것에 의해 본래의 OS color picker 로 변화시킬 수 있습니다.)
인스펙터에서 Color Picker 레퍼런스는 다음과 같이 나타나 집니다:
인스펙터의 Color Picker reference
그것을 클릭하는 것에 의해 Color Picker 를 오픈합니다:
Color Picker 설명
사용자가 사용자의 마우스를 사용자가 잡고 싶은 색상위로 올려놓는 것에 의해 값을 찾고 싶을 때 Eyedropper Tool 를 사용합니다.
RGB / HSV Selector 는 사용자가 Red, Green, Blue 로부터 사용자 색상의 Hue, Saturation and Value (Strength)로 사용자의 값을
바꾸도록 합니다.
마지막으로 선택된 색의 투명도는 Alpha Channel 값에 의해 컨트롤될 수 있습니다.
Curve Editor
AnimationCurve 타입의 속성은 Curve Editor 오픈할 것입니다. 커브 에디터는 사용자가 하나의 커브를 편집하고 집합으로부터
하나를 선택하도록 합니다. 커브를 편집하는 것에 대한 자세항 정보는 Editing Curves 를 참고하시기 바랍니다.
타입은 AnimationCurve 라고 불려지나 그것은 모든 사용자 정의 커브 함수를 정의하기 위해서 사용될 수 있습니다. 함수는 하나의
스크립트로 부터 실시간으로 평가될 수 있습니다.
AnimationCurve 속성은 작은 미리보기로서 인스펙터에서 보여집니다:
인스펙터에서 AnimationCurve 의 미리보기
그것을 클릭하는 것은 커브 에디터를 오픈합니다:
커브 에디터는 AnimationCurves 를 편집하기 위한 것입니다
Wrapping Mode 는 사용자의 커브 안에 있는 컨트롤 키의 타입을 Ping Pong, Clamp 그리고 Loop 사이에서 원하는 타입으로
선택하도록 해줍니다.
Presets 는 사용자가 커브가 가질 수 있는 기본적인 윤곽으로 커브를 변경하도록 해줍니다.
Assigning References
레퍼런스 속성은 게임오브젝트, 컴포넌트 또는 에셋과 같은 다른 오브젝트들을 레퍼런스하는 속성들 입니다. 레퍼런스 슬롯은 어떤
종류의 오브젝트가 이 레퍼런스를 위해서 사용될 수 있는지 보여줄 것입니다.
Audio Clip property slot 은 그것이 Audio Clip 타입의 오브젝트로 레퍼런스를 허용한다는 것을 보여줍니다.
Audio Clip 파일은 Audio Clip 속성에서 레퍼런스 됩니다.
이런 종류의 참조는 특히 스크립팅을 사용할 때 매우 빠르고 강력합니다. 스크립트와 속성을 사용하는 것에 대해 더 많이 배우기
위해 tutorials 페이지의 Scripting Tutorial 을 참고하시기 바랍니다.
오브젝트 레퍼런스는 Object Picker 을 사용하거나 드래그앤드롭(drag & drop)에 의해서 레퍼런스 속성으로 지정될 수 있습니다.
Drag and Drop
사용자는 단순히 씬 뷰 (Scene View), 계층 뷰 (Hierarchy View), 또는 프로젝트 뷰 (Project View)에서 원하는 물체를 선택하고
그것을 레퍼런스 속성의 슬롯에 드래깅하는 것에 의해 드래그앤드롭을 사용할 수 있습니다.
하나의 레퍼런스 속성이 특정 컴포넌트 타입 (예를 들어 Transform)을 허용한다면 게임오브젝트 또는프리팹을 레퍼런스 속성으로
드래깅하는 것은 올바른 타입의 컴포넌트를 포함하는 게임오브젝트 또는 프리팹이 주어지면 제대로 작동할 것입니다. 그 속성은
그것이 사용자가 그것을 드래그했던 게임오브젝트 또는 프리팹임에도 불구하고 컴포넌트를 레퍼런스할 것입니다.
사용자가 하나의 물체를 레퍼런스 속성으로 드래그하고 물체가 올바른 타입이 아니거나 올바른 컴포넌트를 포함하지 않을 때
사용자는 물체를 레퍼런스 속성에 지정할 수 없을지도 모릅니다.
The Object Picker
사용자는 Object Picker 을 열기 위해 레퍼런스 슬롯 바로 옆의 작은 타겟 아이콘을 클릭할 수 있습니다.
편집기로부터 Object Picker 로의 레퍼런스
Object Picker 는 사용자가 그러한 가능한 것들을 미리 보고 찾도록 한 후에 인스펙터에서 물체를 지정하기 위한 간단한 윈도우
입니다.
Object Picker 가 사용하기 정말로 평이함에도 불구하고 사용자가 반드시 명심해야 하는 것들이 있습니다. 이것들은 아래에 설명이
됩니다.
Object Picker 의 해부
1.
Search: Picker 에 많은 물체들이 있을 때 사용자는 그들을 필터하기 위해 Search 필드를 사용할 수 있습니다. 이 search
필드는 그들의 Labels 을 사용해서 물체를 찾을 수 있습니다.
2.
View Selector: 씬과 에셋에서 물체들 사이에 search 의 베이스를 바꿉니다.
3.
Preview Size: 이 수평적인 스크롤 바는 사용자가 미리보기 윈도우에서 사용자의 미리보기 물체를 증가하고 감소하게
합니다. 이것과 함께 사용자는 어느 순간에든 미리보기 윈도우에서 더 많은 더 적은 물체들을 볼 수 있습니다.
4.
Preview Window: Search 필드에 의해 필터되는 사용자의 Scene/Assets folder 에 있는 모든 물체들이 있습니다.
5.
Object Info: 현재 선택된 물체에 대한 정보를 보여줍니다. 이 필드의 내용은 보여지는 물체의 타입에 기반합니다. 그래서
예를 들어 만약 사용자가 하나의 메쉬를 선택한다면 그것은 사용자에게 꼭지점과 삼각형의 갯수를 말해줄 것입니다.
그리고 그것이 UV’s 를 가지는지 그리고 스킨이 있는지도 말해줄 것입니다. 그러나 사용자가 오디오 파일을 선택한다면
그것은 사용자에게 오디오의 비트 레이트, 길이와 같은 정보를 줄 것입니다.
6.
Object Preview: 이것은 사용자가 보고있는 물체의 타입에 역시 기반합니다. 사용자가 메쉬를 선택하면 그것은 그 메쉬가
어떻게 생겼는지를 보여줄 것이고 사용자가 스크립트 파일을 선택한다면 그것은 파일의 아이콘을 보여줄 것입니다.
Object Picker 는 사용자가 사용자의 프로젝트에서 가지는 모든 에셋에서 작동합니다. 그것은 비디오, 노래, 지형, GUI 스킨,
스크립팅 파일 또는 메쉬일 수 있습니다. 그것은 사용자가 자주 사용할 툴입니다.
Hints
•
사용자의 에셋에서 Labels 을 사용하시고 사용자는 Object Picker 의 search 필드를 사용해서 그들을 찾는 것에 의해 그들을 더욱
쉽게 찾을 수 있을 것입니다.
•
사용자가 물체의 설명을 보고싶지 않다면 미리보기 윈도우 아래의 중간에서 슬라이더를 움직일 수 있습니다.
•
사용자가 물체의 자세한 미리보기를 보고 싶다면 사용자는 미리보기 윈도우의 아래의 중간에서 슬라이더를 드래킹하는 것에 의해
물체 미리보기를 확대할 수 있습니다.
인스펙터 옵션
인스펙터 락(Inspector Lock)과 인스펙터 디버그 모드(Inspector Debug Mode)는 사용자 작업과정에 도움을 줄 수 있는 두개의
유용한 옵션입니다.
Lock
Lock 은 인스펙터에서 다른 게임오브젝트를 선택하는 동안 특정 게임오브젝트에 포커스를 유지하도록 해줍니다. 인스펙터에서
lock 을 토글하려면 인스펙터에서 lock/unlock(
) 아이콘을 누르거나 탭 메뉴를 열고 Lock 을 선택하세요.
탭 메뉴에서 인스펙터 Lock 하기.
하나 이상의 인스펙터를 열 수 있으며 하나의 인스펙터에서는 특정 게임오브젝트를 lock 하고 다른 한 인스펙터에서는 어떠한
선택한 게임오브젝트가 나타날 수 있도록 할수 있음을 명심하세요.
디버그
디버그 모드는 인스펙터에서 보통 보이지 않는 컴포넌트의 개인 변수를 볼 수 있게 합니다. 디버그 모드로 바꾸기 위해서는 탭
메뉴를 열고 Debug 을 선택하세요.
디버그 모드에서 모든 컴포넌트는 보통 모드에서 어떤 컴포넌트에 쓰이는 사용자 정의 인터페이스보단 기본 인터페이스가 사용되어
보여집니다. 예를 들어, Transform 컴포넌트는 디버그 모드에서 보통 모드에서 보여지는 오일러 각도보단 회전
쿼터니언(Quaternion)의 원시값을 줍니다. 사용자 자신의 스크립트 컴포넌트의 개인 변수를 보기위해 디버그 모드를 사용할 수
있습니다.
인스펙터의 디버그 모드는 사용자 스크립트와 다른 컴포넌트의 비공개(Private) 변수를 검사할 수 있게합니다.
디버그 모드는 인스펙터당 설정할 수 있어서 하나가 디버그 모드일때 다른 하나는 아닐 수 도 있습니다.
Using the Scene View
씬 뷰(Scene View)는 사용자와 상호작용하는 모래상자입니다. 플레이어, 카메라, 적 그리고 모든 다른 게임오브젝트를 선택하거나
위치시키기 위해 씬 뷰를 사용합니다. 씬 뷰에서 객체를 움직이고 조작하는 것은 유니티에서 가장 중요한 기능이라서 그것을 빨리
익히는 것은 정말 중요합니다.
•
씬 뷰 네비게이션
•
게임오브젝트 포지션 조정
•
뷰 모드
•
기즈모와 아이콘 시각화
씬뷰 네비게이션
씬뷰 컨트롤로 씬뷰를 빠르고 효율적으로 이동합니다.
화살표 이동
씬에서 이동하기 위해서는 Arrow Keys 를 이용하세요. Shift 를 누르고 있으면 더 빠르게 움직일 수 있습니다.
포커싱
아무 GameObject 나 선택 후 F 키를 누르세요. 그러면 그 객체가 씬뷰의 중심이되고 선택의 기준축 (pivot)이 됩니다. 이것은 프레임
선택이라고도 알려져 있습니다.
회전, 이동, 줌
회전하기, 이동하기 그리고 줌하기는 씬뷰에서의 이동에 있어서 아주 중요합니다. 사용자가 사용하는 설정에 상관없이 이 것을
상요하기 쉽고 접근 가능하게 하기 위해서 이것을 하기위해서 몇가지 다른 방법을 제공합니다.
이 컨트롤은 어떤 툴이 선택되어있어도 사용 가능 합니다. Shift 를 누르고 있면 이동과 줌이 빨라집니다.
세개의 버튼을 가진 마우스
•
Orbit: 현재의 기준축 (pivot) 에서 카메라를 회전하기 위해서는 Alt 를 누르고 클릭 후 드래그 하세요.
•
Move: 카메라를 이동하기 위해서는 Alt 를 누르고 중간 클릭 후 드래그 하세요.
•
Zoom: 카메라를 줌하기 위해서는 Alt 를 누르고 오른쪽 클릭 후 드래그 하세요.
중간 버튼이 없는 마우스
•
Orbit: 현재의 기준축에서 카메라를 회전하기 위해서는 Alt 를 누르고 클릭 후 드래그 하세요.
•
Move: 카메라를 이동하기 위해서는 Alt-Control (맥에서는 Alt-Command 를 누르고 중간 클릭 후 드래그 하세요.
•
Zoom: 카메라를 줌하기 위해서는 Alt 를 누르고 오른쪽 클릭 후 드래그 하세요.
하나의 버튼을 가진 마우스
•
Orbit: 현재의 기준축에서 카메라를 회전하기 위해서는 Alt 를 누르고 클릭 후 드래그 하세요.
•
Move: 카메라를 이동하기 위해서는 Alt-Command 를 누르고 중간 클릭 후 드래그 하세요.
•
Zoom: 카메라를 줌하기 위해서는 Alt-Control 를 누르고 오른쪽 클릭 후 드래그 하세요.
핸드툴(Hand Tool) 사용하기
또한 Hand Tool 을 사용할 수 있는데(단축키: Q), 특히 하나의 버튼만을 가진 마우스를 사용할 때 씁니다. 핸드 툴이 선택되었을 때,
카메라를 드래그하기 위해서는 클릭하고 드래그 합니다.
카메라를 현재 기준축에서 회전 시키기 위해서는 Alt 를 누르고 클릭하고 드래그 합니다.
카메라를 줌하기 위해서는 Control (맥에서는 Command)를 누르고 클릭하고 드래그 합니다.
마우스 휠로 줌하기
사용자는 마우스 휠이나 트랙패드로 항상 카메라를 줌할 수 있습니다.
Flythrough 모드
Flythrough 모드는 사용자가 다른 많은 게임에서 카메라를 이동하듯이 씬뷰를 일인칭 시점에서 날아다니듯 이동할 수 있습니다.
•
마우스 오른쪽 버튼을 누르고 있습니다.
•
이제 마우스를 이용해 뷰를 움직일 수 있고 WASD 키를 이용해서 좌/우/앞/뒤로 움직이고 Q 와 E 키를 이용해서 위 아래고
움직입니다.
•
Shift 키를 누르고 있으면 이동이 빨라집니다.
간단한 씬 조작(Scene Gizmo)
씬뷰의 오른쪽 상단 구석에씬 기즈모(Scene Gizmo)가 있습니다. 이것은 씬뷰 카메라의 현재 방향을 보여주고 뷰의 각도를 빠르게
바꿀 수 있게 해줍니다.
사용자는 씬뷰 카메라를 움직이기 위해 어느쪽 팔이든 누를 수 있고 등측모드(Isometric Mode). 로 바꿀 수도 있습니다. 등측
모드일때 회전하기위해서 오른쪽 클릭후 드래그 할수 있고 카메라를 좌우로 움직이기 위해서 Alt 클릭후 드래그 할 수 있습니다. 그
모드에서 빠져나오기 위해서는 씬 기즈모의 중간을 클릭합니다. 등측모드(Isometric Mode)로 토글하기 위해서는 씬 기즈모를 Shift
클릭하면 됩니다.
원근법 모드
등측(Isometric) 모드. 이 거리에선 객체가 더 작아지지 않습니다!
게임 오브젝트 위치 시키기
게임 빌드시 사용자는 많은 수의 다른 객체들을 사용자의 게임 세계에 위치시키게 될 것입니다.
포커싱
객체를 조작하기 전에 객체의 씬뷰 카메라에 포커스를 두는 것은 유용합니다. 아무 게임오브젝트 선택 후 F 키를 누르세요. 이것은
씬뷰와 기준축(pivot)을 중앙에 오게 합니다. 이것은 프레임 선택이라고도 알려져 있습니다.
해석, 회전 그리고 크기
툴바의 Transform 툴을 이용하여 각각의 게임오브젝트를 해석, 회전 그리고 크기 조절을 하세요. 씬뷰에서 이 각각은 선택된
게임오브젝트 근처에 보이는 기즈모를 가집니다. 사용자는 마우스를 이용해서 게임오브젝트의 Transform 컴포넌트를 바꾸기 위해
어떤 기즈모 축도 조작할 수 있고 또는 값을 Inspector 직접 타입해서 해서 넣을 수도 있습니다.
•
객체의 모든 축을 한번에 조작하려면 기즈모의 중앙을 클릭하고 드래그 합니다.
•
세개의 버튼을 가진 마우스를 가지고 마지막으로 수정된 축(노락색)을 직접 클릭하지 않고 수정하고 싶다면 중간 버튼을 누르면
됩니다.
•
크기조절 툴을 쓴때는조심하세요. 왜냐하면 일정하지 않은 크기(예를들어 1,2,1)는 자식 객체에 비정상적인 크기조절을 초래할 수
있습니다.
•
게임오브젝트의 더 많은 정보를 원하면 Transform Component 를 참고하세요.
기즈모 디스플레이 토글
Gizmo Display Toggles 는 트랜스폼 기즈모의 위치를 정의합니다.
기즈모 디스플레이 토글
•
Position:
o
Center 는 기즈모를 객체 렌더 경계의 중앙에 위치시킵니다.
o
Pivot 은 기즈모를 메쉬의 실제 피벗점에 위치시킵니다.
•
Rotation:
o
Local 은 기즈모의 회전을 객체에 대해 상대적으로 유지합니다.
o
Global 은 기즈모를 세계 공간 방향으로 고정 시킵니다.
단위 스냅핑
이동툴을 이용해서 기즈모축을 드래그 하는 동안 Snap Settings 에서 설정해놓은 만큼씩 증가 시키기 위해서는 Control
키를(맥에서는 Command) 누르고 있으면 됩니다.
단위 스냅핑에 쓰이는 단위 거리를 바꾸기 위해서는 메뉴에서 Edit->Snap Settings... 를 선택합니다.
단위 스냅핑 설정 씬뷰
서피스(표면, Surface) 스냅핑
이동툴을 이용해서 중심으로 드래그 하는 동안 객체를 충돌체(Collider) 의 교차점에 스냅하기 위해서는 Shift 와 Control 키(맥에서는
Command)를 누르고 있습니다. 이것은 객체를 아주 빠른 속도록 정확한 위치 설정을 가능하게 합니다.
Look-At 회전
회전툴을 사용하는 동안 개체를 충돌체의 표면을 향해 회전 하도록 하기 위해서는 Shift 와 Shift 키(맥에서는 Command)를 누르고
있습니다. 이것은 객체 서로의 방향을 간단하게 상대적으로 만들어 줍니다. .
버텍스 스냅핑(Vertex Snapping)
사용자는 Vertex Snapping 을 사용하여 쉽게 세계를 조립할 수 있습니다. 이 기능은 매운 간단하지만 유니티에서 아주 강력한
툴입니다. 이 것은 주어진 메쉬에서 어떤 버텍스라도 선택해서 사용자가 선택하는 어떤 다른 메쉬의 버텍스에 마우스를 가져다
놓음으로써 같은 위치에 놓이게 할수 있습니다.
이 기능으로 세계를 정말 빨리 조립할 수 있습니다. 예를 들어, 레이싱 게임에서 높은 정확도록 길을 위치시키고 메쉬의 버텍스에
파워업 아이템을 추가할 수 있습니다.
버텍스 스냅핑(Vertex Snapping)으로 길 조립하기
유니티에서 버텍스 스냅핑을 아주 쉽습니다. 아래의 스텝을 따르세요:
•
조작하고 싶은 메쉬를 선택하고 이동툴(Transform Tool)이 활성화 되게 하세요.
•
버텍스 스냅핑 모드를 활성화 하기 위해서 V 키를 누르고 있습니다.
•
피벗점으로 쓰고 싶은 메쉬의 버텍스 위에 마우스를 위치시세요.
•
원하는 버텍스위에 커서를 놓았으면 왼쪽 버튼을누르 고 있고 메쉬를드래그해서 다른 메쉬의 버텍스에 가져도 놓으세요.
•
결과에 만족하면 마우스 버튼과 V 키를 놓습니다.
•
Shift-V 는 이 기능의 토글로 사용합니다.
•
버텍스에서 버텍스, 버텍스에서 표면, 피벗에서 버텍스으로 스냅이 가능합니다.
이 동영상에서 어떻게 버텍스 스냅핑이 사용되는지 here에서 찾을 수 있습니다.
View Modes
씬뷰 제어바는 사용자가 씬을 다양한 뷰 모드로 보는 것을 가능하게 해줍니다. - Textured, Wireframe, RGB, Overdraw 그리고
다른것. 그것은 또한 사용자가 게임안의 빛, 게임 요소 그리고 씬뷰의 사운드를 보고(그리고 듣고) 하는 것을 가능하게 합니다.
Draw Mode
첫번째 드롭 다운은 Draw Mode 를 정하는 것입니다. 사용자는 전체 씬을 보는 것을 선택할 수 있는데 Textured, Wireframe, Tex Wire, Render Paths, 또는 Lightmap Resolution 을 선택할 수 있습니다. 이것은 사용자 게임이 출판 되었을 때 영향을 주지 않습니다.
Draw Mode 의 드롭 다운
•
Textured 는 게임에서 텍스쳐와 함께 표면을 보여줍니다.
•
Wireframe 는 씬에서 메쉬의 wireframes 를 보여줍니다.
•
Tex - Wire 는 텍스쳐 위에 wireframes 을 보여줍니다.
•
Render Paths 는 어떤 rendering paths 객체가 사용되고 있는지 보여줍니다. 초록: deferred lighting, 노랑: forward, 빨강: vertex lit.
•
Lightmap Resolution 은 알맞은 해상도를 가지고 있는지 보기위해 라이트맵의 해상도에 해당하는 씬에 눕혀진 체크무늬
그리드(Grid)를 보여줍니다.
렌더 모드(Render Mode)
다음 드롭다운은 네개 중 하나의 렌더 모드(Render Modes)를 선택하기 위한 것입니다. 사용자는 씬뷰를 RGB, Alpha, Overdraw,
또는 Mipmaps 로 채우기 위해 선택할 수 있습니다. 다시, 이것은 사용자가 퍼블리슁한 게임에 영향을 주지 않습니다.
Render Mode 드롭 다운
•
RGB 는 간단히 말하자면 보통으로 렌더링된 사용자 게임의 모든 색상을 말합니다.
•
Alpha 는 튜닝의 투명성 또는 알파 값을 이용하는 전체화면을 위해 모든 알파 값을 렌더링 합니다.
•
Overdraw 는 화면이 얼마나 많은 시간을 overdraw 에 쓰는지 나타내 줍니다.
•
Mipmaps 는 이상적인 텍스쳐 크리를 보여줍니다 --빨강은 특정 텍스쳐가 필요이상으로 큰것을 의미하고(현재의 거리와 해상도에서),
반면 파랑은 텍스쳐가 더 커도 된다는 것을 의미합니다. 물론 이상적인 텍스쳐의 크기는 게임이 실행될 해상도에 따라 다르며
카메라가 각각의 표면에 얼마나 가까이 갈수 있는지에 따라서도 달라집니다.
Scene Lighting, Game Overlay, and Audition Mode
다음은 세가지 버튼이 있습니다: Scene Lighting, Game Overlay, Audition Mode.
•
Scene Lighting 을 활성화하면 기본 씬 뷰의 빛을 사용자의 마지막 빛 설정을 위해 위치시킨 빛으로 덮어씌우게 됩니다.
•
Game Overlay 를 활성화하면 씬 뷰에서 Skyboxes 나 GUI Elements 같은 아디템을 보여주고 또한 그리드를 숨겨줍니다.
•
Audition Mode 를 활성화하면 씬 플레이에 AudioSources 를 만들어서 플레이 모드로 가지 않고서도 들을수 있게합니다.
기즈모(Gizmos)와 아이콘(Icons)
아이콘 셀렉터(The Icon Selector)
아이콘 셀렉터(Icon Selector)를 사용하서 쉽게 사용자 정의 아이콘을 게임오브젝트와 스크립트를 위해 만들수 있는데 스크립트는
씬뷰와 인스펙터에서 사용됩니다. 게임오브젝트의 아이콘을 바꾸기 위해서는 인스펙터에서 아이콘을 클릭하면 됩니다. 스크립트
에셋 이와 같이 인스펙터에서 아이콘을 눌러 작동합니다. 아이콘 셀렉터에는 Label Icon 이라는 특별한 아이콘이 있습니다. 이
타입의 아이콘은 씬뷰에서 게임오브젝트의 이름을 이용한 텍스트 레이블 형태로 나타납니다. 내장된 텀포넌트의 아이콘은 바뀔수
없습니다.
주의: 아이콘이 바뀔때 에셋은 수정되었다고 보이므로 수정 제어 시스템에의해 수정된 에셋으로 여겨집니다.
스크립트를 위한 아이콘 선택하기
Selecting an icon for a script
아이콘과 기즈모 나타내고 숨기기(Showing and Hiding Icons and Gizmos)
Gizmos dropdown 으로 어떤 기즈모와 아이콘이 컴포넌트 타입마다 보여야 하는지를 토글할 수 있습니다. 씬뷰에 기즈모와
아이콘이 늘어가면서 특정 영역에서 일을 할 때 그것을 필터링 해줄 방법이 필요합니다.
현재의 기즈모와 아이콘의 상태를 보여주기 위해서는 씬이나 게임뷰에 있는 컨트롤바에 있는 Gizmos 를 클릭하세요. 그 토글은 어떤
기즈모와 아이콘이 보여야 하는지를 설정합니다.
그 섹션에 있는 Scripts 사용자 정의 아이콘을 가졌거나 OnDrawGizmos ()/OnDrawGizmosSelected ()가 구현된 스크립트 인것에
주의하세요.
Gizmos dropdown 아이콘과 기즈모의 상태를 보여줍니다
컴포넌트 확장 상태(Component Expanded State)
아이콘의 가시성 (Visibility)이 Gizmos dropdown 에서만 제어되는 반면 기즈모의 가시성 (Visibility) 상태는 컴포넌트가
인스펙터에서 확장되었느냐에 따라 달라집니다. 그들은 하나이고 같은 것입니다. 기즈모 드롭다운에 있는 체크박스를 체크하거나
해제하는 것은 인스펙터에서 상응하는 컴포넌트를 확장하거나 없애게 될 것입니다. 그래서 인스펙터에서 상응하는 컴포넌트를
확장하거나 없에는 것은 기즈모를 토글하는 또 하나의 방법입니다. 그 상태는 인스펙터가 현재 보이는지 그렇지 않은지에 상관없이
존재하며 항상 Gizmos dropdown 에서 볼 수 있습니다.
아이콘 스케일링(Icon Scaling)
아이콘 스케일링 슬라이더(Icon Scaling Slider)를 통해 아이콘 세계 크기 (World Scale)를 조정할 수 있습니다. 아이콘이 세계 크기로
설정되었을 때 그것이 가까울 수록 더 크게 보이는데 최대 화면크기 만큼 입니다. 그 슬라이더가 오른쪽으로 갈수록 세계 크기는 더
커집니다. 그것이 맨 오른쪽으로 갔을 때 모든 아이콘은 그들의 최대 화면사이즈를 가지며 맨 왼쪽으로 갔을 때 모든 아이콘이
완전히 숨겨집니다.
검색(Searching)
크고 복잡한 씬에서 작업할 때 특정 객체를 찾는 찾는 기능은 아주 유용합니다. 유니티의 Search 기능을 사용함으로써 사용자가
보고 싶은 객체나 객체 그룹을 걸러낼 수 있습니다. 이름, 컴포넌트 타입 그리고 어떤 경우에는 Labels 로 에셋을 검색할 수 있습니다.
검색 드롭 다운 메뉴에서 선택하여 검색 모드를 지정할 수 있습니다.
씬 검색(Scene Search)
에디터에 씬이 로드되었을 때 씬뷰와 계층 뷰 (Hierarchy)에서 모두 객체를 볼 수 있습니다. 특정 에셋은 이 두 곳에서 공유되는데
“bridge”라는 검색어를 넣으면 필터가 씬뷰와 계층 뷰 (Hierarchy)에서 좀더 전형적인 방법으로 적용됩니다. 씬뷰에서 검색창에
검색어를 넣는 것과 Hierachy 에서 하는 것은 차이가 없고 필터가 두 곳 모두에서 작동합니다.
검색하지 않고 있는 씬뷰(Scene View) 와 계층 뷰 (Hierarchy).
검색어를 필터중인 씬뷰와 계층 뷰 (Hierarchy)
검색어의 필터가 동작 중일 때 계층 뷰 (Hierarchy)는 게임오브젝트 간의 계층적 관계를 보여주지 않습니다. 그러나 어떤
GameObject 도 선택될 수 있으며 그 객체의 씬에서의 계층 경로가 계층 뷰 (Hierarchy) 바닥에 보여질 것입니다.
계층 경로를 보기 위해서는 검색된 리스트에서 게임오브젝트를 클릭하세요.
검색창을 지우고 싶으면 검색 필드의 작은 크로스를 클릭합니다.
씬 검색에서는 이름이나 타입으로 검색할 수 있습니다. 검색 드롭다운 메뉴에서 작은 돋보기를 클릭하고 검색모드를 선택합니다.
이름, 타입 또는 모든 검색
프로젝트 검색(Project Search)
프로젝트 뷰의 에셋을 검색할 때도 같은 원리가 적용됩니다. 검색어를 입력하면 필터에 관련된 에셋이 보일 것입니다.씬 검색에서와
같이 프로젝트 검색에서도 이름과 타입으로 검색 가능하며 추가로 레이블로도 검색이 가능합니다. 검색 드롭다운 메뉴를 열고 검색
모드를 선택하기 위해 검색 필드의 작은 돋보기를 클릭하십시오.
이름, 타입, 레이블 또는 모든 검색
오브젝트 픽커 검색(Object Picker Search)
Object Picker 를 통해 객체를 지정할 때 사용자가 원하는 객체만을 보기위해 어떤 검색어라도 입력할 수 있습니다.
프리팹(Prefabs)
프리팹(Prefab)은 하나의 에셋(asset)으로 프로젝트 뷰에 저장되어 있는 재사용 가능한게임오브젝트로써 프리팹은 여러 개의 씬에
추가될 수 있으며 씬당 여러 번 추가되어질 수 있습니다. 프리팹을 씬에 삽입할 때 그것의 instance 가 생성되어 집니다. 모든 프리팹
인스턴스들은 본래의 프리팹에 연결되어지며 근본적으로 본래의 프리팹의 복제가 되는 것입니다. 프로젝트에 몇 개의 인스턴스가
있는지에 상관없이 프리팹이 수정되면 모든 인스턴스들에 그 변화가 적용됩니다.
프리팹(Prefabs) 생성
프리팹을 생성하기 위해서는 메뉴를 사용해서 새로운 빈 프리팹를 만들어야만 합니다. 이런 빈 프리팹은 게임오브젝트들을
포함하고 있지 않으며 인스턴스를 생성할 수도 없습니다. 새로운 프리팹은 게임오브젝트 데이터로 채워지기를 기다리고 있는 빈
컨테이너로서 생각할 수 있습니다.
새로운 빈 프리팹. 게임오브젝트로 채워지기 전까지 인스턴스를 생성 할 수 없습니다
프리팹을 채우기 위해서는 씬에서 생성되어진 게임오브젝트를 사용합니다.
1.
메뉴바에서 Assets->Create->Prefab 을 선택하고 새로운 프리팹의 이름을 정합니다.
2.
Hierarchy View 에서 프리팹에 만들어 넣고 싶은 게임오브젝트를 선택합니다.
3.
Hierarchy 로 부터 게임오브젝트를 ProjectView 안에 새로운 프리팹으로 끌어 놓기(Drag & drop)를 합니다.
위 과정을 수행한 후에 게임오브젝트와 모든 자식 객체들은 프리팹 데이타 안에 복사되어 집니다. 이제 프리팹은 여러 개의
인스턴스에서 재사용될 수 있습니다. Hierarchy 안의 본래 게임오브젝트는 이제 프리팹의 인스턴스가 됩니다.
프리팹 인스턴스(Prefab Instances)
현재의 씬 에서 프리팹 인스턴스를 생성하기 위해서는 프로젝트 뷰로 부터 씬 또는 Hierarchy View 로 프리팹을 끌어 놓습니다. 그
인스턴스는 프리팹에 연결 되어지며 Hierarchy View 에서 그것의 이름에 사용되어진 파란 텍스트로 표시되어 집니다.
세 개의 게임오브젝트들이 프리팹들에 연결되어 있고 한 개는 연결되어 있지 않습니다.
•
하나의 프리팹 인스턴스가 선택되어 있고 모든 인스턴스에게 영향을 미치는 변화를 주고자 한다면, 소스 프리팹(source Prefab)을
선택하기 위해 인스펙터에 있는 Select 버튼을 클릭합니다.
•
스크립트로 부터 프리팹들을 인스턴스화 하는 것에 대한 정보는 Instantiating Prefabs 페이지에서 찾아 볼 수 있습니다.
상속
상속(Inheritance)은 소스 프리팹(source Prefab)이 변할 때마다 이러한 변화가 모든 연결된 게임오브젝트들에게도 영항을 미친다는
것을 의미합니다. 예를 들어, 프리팹에 새로운 스크립트를 추가하면, 모든 연결된 게임오브젝트에게도 즉시 그 스크립트가 포함
되어질 것입니다. 그러나 모든 연결 관계를 온전히 유지하면서 하나의 인스턴스의 특성을 변화시킬 수 있습니다. 하나의 프리팹
인스턴스의 어떠한 특성을 변화시키면 그 변수의 이름이 굵은 글꼴로 표현되는 것을 보게될 것입니다. 그 변수는 이제 덮어
씌여(override) 진것입니다. 모든 덮어 씌여진(override) 특성은 소스 프리팹(source Prefab)에서의 변화에 영향받지 않을 것입니다.
이것은 프리팹 링크를 깨뜨리지 않으면서 그들의 소스 프리팹들로 부터 그들을 고유하게 만들기 위해 프리팹 인스턴스들을
변경시키는 것을 가능하게 합니다.
어떠한 overrides 도 이루어지지 않은 하나의 연결된 게임오브젝트
여러개의 overrides(굵은 글씨체)가 이루어진 하나의 연결된 게임오브젝트
•
소스 프리팹(source Prefab)을 갱신하고 모든 인스턴스들을 새로운 overridden 값들로 갱신하려면, 인스펙터에 있는 Apply 버튼을
클릭합니다.
•
어떤 특정 인스턴스의 모든 overrides 를 제거하기 위해서는 Revert 버튼을 클릭합니다.
프리팹 연결의 파괴와 복구
하나의 인스턴스와 그것의 소스 프리팹(source Prefab)사이의 연결을 끊는 특정한 방법들이 있지만 그 연결은 항상 다시 복구될 수
있습니다. 그 연결을 파괴하는 방법들에는 다음과 같은 것들이 있습니다:
•
컴포넌트의 추가 또는 제거
•
자식 게임오브젝트의 추가 또는 제거
이러한 방법들은 연결을 파괴하는 것에 대한 주의/확인 메세지를 유발할 것입니다. 확인을 하면 연결은 파괴될 것이며소스 프리팹의
변화는 더이상 그 연결이 파괴된 인스턴스에 영향을 미치지 않을 것입니다. 그 연결을 복구하기 위해서는 그 인스턴스의 인스펙터에
있는 Reconnect 또는 Apply 버튼을 클릭하면 됩니다.
•
Reconnect 는 소스 프리팹과 다른 점들을 모두 버릴 것입니다.
•
Apply 는 소스 프리팹으로 모든 다른 것들을 복사할 것입니다. (그 후에 모든 다른 프리팹 인스턴스들로도)
불러오기한 프리팹(Imported Prefabs)
에셋(Assets) 폴더에 하나의 메쉬 에셋(mesh asset)을 놓을 때, Unity 는 자동으로 그 파일을 불러오고 그 메쉬밖의 하나의 프리팹과
유사하게 보이는 것을 생성합니다. 이것은 실제 프리팹이 아니고 단순히 그 에셋 파일 그 자체입니다. 에셋의 인스턴스화 등의
작업은 보통의 프리팹들에서 작업 시 존재 하지 않았던 제약을 만듭니다.
에셋 아이콘은 프리팹의 아이콘과 다른 것에 주목하세요
에셋은 보통 프리팹 대신 소스 에셋(source asset)에 연결된 게임오브젝트로서 씬에서 인스턴스화 됩니다.
구성요소(Components)들은 이런 게임오브젝트에서 정상적으로 추가되어 지고 제거되어 질 수 있습니다. 그러나 이것은 그 에셋
파일 자체에 데이터를 추가하는 것이기 때문에 그 에셋 자체에는 어떠한 변화도 적용할 수 없습니다. 재사용하고 싶은 어떤 것을
생성하고 싶다면 위 “Creating Prefabs"에 나타나있는 과정들을 실행 하면서 하나의 프리팹안에 에셋 인스턴스를 만들어야만 합니다.
•
하나의 에셋의 인스턴스를 선택했다면, 그 인스펙터의 Apply 버튼은 Edit 버튼으로 대체되어 집니다. 이 버튼을 클릭하면 에셋을
위한 편집 어플리케이션을 시작할 수 있습니다. (Maya 또는 Max)
조명(Lights)
조명(Lights)은 모든 씬의 중요한 부분입니다. 메쉬와 텍스쳐가 씬의 모양을 정의한다면 조명은 3D 환경의 색상과 무드를
정의합니다. 사용자는 각 씬에서 한가지 이상의 조명을 이용할 것입니다. 그 조명들을 같이 작동하게 하기위해서는 약간의 연습이
필요합니만 결과는 아주 놀라울 것입니다.
간단한 두개의 조명 설정
조명은 GameObject->Create Other 메뉴에서 씬에 추가 될수 있습니다. 세 가지의 조명의 타입을 보게될 것입니다. 일단 조명이
추가되면 다른 GameObject 와 같이 조작할 수 있습니다. 그리고 Component->Rendering->Light 을 선택해서 어떤 선택된
GameObject 에도 조명을 추가할 수 있습니다.
Inspector 의 조명 컴포넌트에는 많은 다른 옵션들이 있습니다.
Inspector 의 조명 컴포넌트 속성
조명의 색을 바꿈으로써 씬에 전혀다른 무드를 가져올 수 있습니다.
밝은 태양광
어두운 중세의 조명
으시시한 밤의 조명
이런 식으로 만드는 조명은 실시간 조명입니다. 즉 게임이 진행되는 동안 각 프레임마다 빛이 계산됩니다. 만약 조명이 바뀌지
않는다면 라이트맵핑을 사용하여 게임을 빠르고 더 보기좋게 할 수 있습니다.
렌더링 (Rendering) 경로
유니티는 몇가지 다른 렌더링 경로를 지원하는데 이것은 주로 빛과 그림자에 영향을 주므로 게임 요구사항에 의존하는 올바른
렌더링 경로를 선택하는 것은 사용자 프로젝트의 성능을 향상 시킬수 있습니다. 렌더링 경로에 관한 더 자세한 사항은 Rendering
paths section 을 참조하세요.
추가 정보
조명 이용을 위한 추가정보를 원하시면 Reference Manual 에 있는 Lights page 를 확인하세요.
카메라(Cameras)
카메라가 영화에서 청중에게 이야기를 보여주기 위해 사용되듯 유니티에서 카메라(Cameras)는 플레이어에게 게임세상을 보이기
위해 사용됩니다. 한 씬당 항상 최소 하나의 카메라가 존재하지만 하나 이상을 가지는 것도 가능합니다. 여러 대의 카메라는 두
플레이어의 분리 화면 (Split Screen)이나 고급 사용자정의 효과(Advanced custom effect)를 제공해 줄 수 있습니다. 사용자는
카메라를 애니메이션화 할 수 있고 또는 물리적인 제어도 가능합니다. 사용자가 카메라로 상상 가능한 것은 무엇이든 가능하며
사용자의 게임 스타일에 따라 일반적인 또는 독특한 카메라를 만들수 있습니다.
나머지 글은 Camera Component reference 에서도 확인할 수 있습니다.
카메라(Camera)
카메라(Camera)는 플레이어에게 세상을 캡쳐해서 보여주는 장치입니다. 카메라의 커스터마이징과 조작을 통해 사용자의 게임을
진정으로 특별하게 보여줄 수 있습니다. 하나의 씬에는 무제한의 카메라를 놓을 수 있습니다. 카메라를 씬의 원하는 렌더 순서로,
어떤 위치에서나, 원하는 어떤 특정 부분도 보여줄 수 있도록 설정할 수 있습니다.
유니티의 유연성있는 카메라 객체
Properties
Property:
Function:
화면의 어떤 부분이 제거될지 정합니다. 이것은 다른 게임 요소를 끌어오기 위하여 카메라를
Clear Flags
Background
사용할때 편리합니다.
뷰의 모든 요소가 그려지고 스카이박스(skybox)가 없을 때 화면의 나머지 부분에 적용되는 색.
카메라의 의해 렌더될 객체 레이어를 추가나 삭제합니다. 인스펙터에서 객체에 레이어를
Culling Mask
적용하세요.
Projection
퍼스펙티브(perspective)를 시뮬레이션 하는 카메라 기능을 작동시킵니다.
Perspective
카메라는 퍼스펙티브를 그대로 놔둔 채로 객체를 렌더링합니다.
Orthographic
카메라가 퍼스펙티브에 상관없이 객체를 균일(uniform)하게 렌더링합니다.
Size (when Orthographic is
카메라가 오쏘그래픽(Orthographic)으로 설정되어 있을 때의 뷰포트 크기.
selected)
Field of view
로컬 Y 축을 따라 10 진수 각도(degree)로 측정한 카메라 뷰 각도의 넓이(가로, width)
Clipping Planes
카메라가 렌더링을 시작하고 끝낼때까지의 거리.
Near
드로잉이 일어날 카메라에서 상대적으로 가장 가까운 점.
Far
드로잉이 일어날 카메라에서 상대적으로 가장 먼 점.
Normalized View Port Rect
스크린 좌표 0-1 까지에서 화면 어디에 카메라의 뷰가 그려질지를 나타내는 네개의 값
X
카메라뷰가 그려질 수평의 시작 위치.
Y
카메라뷰가 그려질 수직의 시작 위치
W (Width)
화면에서 카메라 결과의 넓이(가로, width)
H (Height)
화면에서 카메라 결과의 높이.
Depth
그려지는 순서에서 카메라의 위치. 높은 값의 카메라가 낮은 값의 카메라보다 위에 그려집니다.
Rendering Path
카메라에의해 어떤 렌더링 모델이 사용될지 정의하는 옵션.
이 카메라는 무엇이던 플레이어 세팅(Player Setting)에서 정해진 렌더링 경로(Rendering Path)를
Use Player Settings
이용합니다.
Vertex Lit
이 카메라에 의해 렌더된 모든 객체는 버텍스릿(Vertex-Lit) 객체로 렌더됩니다.
Forward
유니티 2.x 에서 표준이었던 데로, 모든 객체는 재질(Material) 당 한개의 패스(pass)로 렌더됩니다.
Deferred Lighting (Unity Pro
모든 객체는 조명없이 한번 그려진 후 렌더 큐(render queue)의 마지막에 모든 객체의 빛이 다 함께
only)
렌더됩니다.
Target Texture (Unity
카메라 뷰의 결과를 포함하게 될 Render Texture 에 대한 참조입니다. 이 참조를 사용시 화면을
Pro/Advanced only)
렌더링할 카메라의 기능이 비활성화됩니다.
Details
카메라는 플레이어에게 게임을 보여주는데 있어 필수입니다. 이것은 상상할 수 있는 모든 효과를 내기위해 사용자 정의되고,
스크립팅, 또는 상속되어질 수 있습니다. 퍼즐 게임에서 카메라는 퍼즐을 전체 뷰에 고정되게 유지할 것입니다. 일인칭 슈팅
게임에서는 카메라를 부모자식관계설정을 하여 그 카메라를 플레이어 캐릭터의 눈의 높이에 위치 시킬수 있습니다. 레이싱
게임에서는 사용자는 카메라가 플레이어의 차를 따라가기를 바랄 것입니다.
사용자는 여러개의 카메라를 생성해서 각 카메라에 다른 깊이(depth) 값을 할당할 수 있습니다. 카메라는 낮은 깊이(depth)부터 높은
깊이(depth)로 그립니다. 다시 말해, 카메라의 깊이 2 는 깊이 1 의 것보다 위에 그려집니다. 사용자는 화면에서의 카메라 뷰의 크기와
위치를 위해 노멀화된 뷰포트 사각형(Normalized View Port Rectangle)의 값을 조정할 수 있습니다. 이것은 미사일 캠, 맵 뷰 또는
백미러 뷰등의 여러 개의 작은 뷰들을 생성할 수 있습니다.
렌더 경로(Render Path)
유니티는 다른 렌더링 경로를 지원합니다. 사용자는 게임의 컨텐츠, 타겟 플랫폼/하드웨어에 따라 어떤 것을 사용할지 정해야 합니다.
다른 렌더링 경로는 다른 기능과 빛과 그림자에 주로 영향을 주는 성능의 특징을 가집니다.
사용자 프로젝트에 의해 사용되는 렌더링 경로는 플레이어 세팅(Player Settings)에서 선택됩니다. 추가로, 사용자는 각 카메라에
그것을 오버라이드(override) 할 수 있습니다.
좀더 자세한 사항은 rendering paths page 를 확인하세요.
클리어 플래그(Clear Flags)
각 카메라는 뷰를 렌더할 때 색과 깊이 정보를 저장합니다. 화면에서 그려지지 않는 부분은 빈 공간으로 기본적으로 스카이박스로
채워집니다. 사용자가 여러 개의 카메라를 사용할 때, 각 카메라는 버퍼(buffers)에 자신의 색과 깊이 정보를 저장하며 각 카메라가
렌더하는 데이터를 쌓아 갑니다. 사용자 씬에서 어떤 특정 카메라가 뷰를 렌더링 할 때, 사용자는 Clear Flags 를 설정하여 버퍼된
정보의 다른 쌓인 정보들을 제거(clear) 할 수 있습니다. 이것은 4 가지 옵션 중에 하나를 택함으로써 행해집니다:
스카이박스(Skybox)
이것이 기본 세팅입니다. 화면의 빈 공간은 현재 카메라의 스카이박스를 보여줄 것입니다. 만약 카메라가 스카이박스 설정을 가지고
있지 않으면 Render Settings (Edit->Render Settings)에서 선택된 스카이박스를 기본으로 사용합니다. 그런 후에
배경색(Background Color)으로 가게 됩니다. 대안으로 Skybox component 가 카메라에 추가될 수 있습니다. 새로운 스카이박스를
만들기를 원하면 스카이박스사용법 가이드를 이용하세요.
단색(Solid Color)
화면의 빈 공간은 카메라의 백그라운드 색(Background Color)으로 그려집니다.
깊이만(Depth Only)
플레이어의 총이 환경(environment) 공간 안에서 짤리지 않게 그려지기를 원하면 환경을 그릴 한 개의 카메라 깊이를 0 으로
설정하고, 무기만을 그릴 카메라 깊이를 1 로 설정하세요. 그 무기 카메라의 클리어 플래그(Clear Flag)는 깊이만(Depth only)으로
설정해야 합니다. 이것은 화면에서 주변 환경을 유지하고 3D 공간에 존재하는 각 객체가 있는 곳의 모든 정보를 버리게 합니다. 총이
그려지면 불투명(opaque)한 부분이 총이 벽에서 얼마나 가깝냐에 상관없이 모든 그려진 것을 커버합니다.
총은 그 전에 있던 카메라의 깊이 버퍼(depth buffer)를 지운 후에 마지막에 그려집니다.
제거하지 않기(Don't Clear)
이 모드는 색상이나 깊이 버퍼 아무 것도 제거하지 않습니다. 결과로 각 프레임이 위에 덮여 씌워지고 이것은 그림이 번진 것
같은(smear-looking) 효과를 냅니다. 이것은 게임에서 잘 사용되지 않으며 사용자 정의된 커스텀 셰이더와 함께 사용하는 것이 가장
좋습니다.
클립 평면 (Clip Planes)
"근접(Near)"과 "원거리 클립 평면(Far Clip Plane)" 속성은 카메라의 뷰가 시작되고 끝나는 지점을 결정합니다. 평면들은 카메라의
방향에 수직으로 놓여있고 그것의 위치에서 측정이 됩니다. 근접(Near) 평면은 렌더될 가장 가까운 곳이며 원거리(Far) 평면은 가장
먼 곳입니다.클립핑 평면은 또한 어떻게 깊이 버퍼 정확도가 화면에 분배되는지를 결정합니다. 일반적으로 높은 정확도를 위해서는
근접 평면을 최대한 멀리 합니다. Near/Far 평면 그리고 카메라의 뷰의 필드에 의해 정의된 평면은 널리 알려진 카메라
프러스텀(시야절두체, frustum)을 설명합니다. 유니티는 객체를 렌더링할 때 완전 이 시야절두체(frustum) 밖에 있는 객체는
보여주지 않습니다. 게임에서 오클루젼 컬링(Occlusion Culling)을 사용하는가에 상관없이 프러스텀 컬링(Frustum Culling)은
일어납니다. 성능상의 이유로 사용자는 작은 객체들을 먼저 선택하기를 원할 것입니다. 예를 들어, 작은 돌과 잔해들은 큰 빌딩보다
훨씬 작은 거리로 보이지 않게 만들 수 있습니다. 이렇게 하기 위해서는 작은 객체를 개별 레이어에 넣고 Camera.layerCullDistances
스크립트 함수를 이용하여 레이어당 컬(cull) 거리를 설정합니다.
컬링 마스크(Culling Mask)
컬링 마스크(Culling Mask)는 레이어를 사용하여 선택적으로 객체 그룹을 렌더링 하는데 사용됩니다. 레이어 사용에 관한 정보는
레이어를 보세요. 일반적으로 유저 인터페이스를 다른 하나의 레이어에 두고 그 UI 레이어만을 위한 카메라로 따로 그것만을
렌더하는 것이 좋습니다. UI 를 다른 카메라 뷰위에 보여지게 하기 위해서는 클리어 플래그(Clear Flag)를 깊이만(Depth only)으로
설정하고 UI 카메라의 깊이가 다른 카메라보다 높게 설정하세요.
노멀화된 뷰포트 사각형(Normalized Viewport Rectangle)
노멀화된 뷰포트 사각형(Normalized Viewport Rectangle)이란 현재 카메라 뷰가 그려질 화면의 특정 부분을 정의하기 위해 있습니다.
사용자는 맵뷰를 화면의 오른쪽 하단에 또는 미사일-끝(Missile-tip) 뷰를 왼쪽 상단에 둘수 있습니다. 약간의 디자인 작업으로 뷰포트
사각형(Viewport Rectangle)을 독특한 행동을 만들어 내는데 쓸 수 있습니다.노멀화된 뷰포트 사각형를 이용하여 이인용 플레이어
스플릿화면 효과를 내는 것은 쉽습니다. 두개의 카메라를 생성한 후 H 값을 모두 0.5 로 설정하고, 플레이어 1 의 Y 값을 0.5 로,
플레이어 2 의 값을 0 으로 설정하면 됩니다. 이것은 플레이어 1 의 카메라를 화면의 중간부터 최상단가지 플레이어 2 의 카메라를
화면의 최하단에서 중간까지에 위치 시킵니다.
노멀화된 뷰포트 사각형을 사용한 두명의 플레이어 화면
오쏘그래픽(Orthographic)
카메라를 오쏘그래픽(Orthographic)으로 제작하면 카메라 뷰에서 모든 퍼스펙티브 투영이 제거됩니다. 이것은 쿼터뷰(isometric)나
2D 게임을 만드는데 아주 유용합니다.안개는 오쏘그래픽 카메라 모드에서 균일(uniform)하게 렌더되므로 예상한대로 보이지 않을
수도 있습니다. 자세한 이유는 component reference on Render Settings 을 보세요.
퍼스펙티브 카메라
오쏘그래픽 카메라. 여기선 객체가 거리에 따라 작아지지 않습니다!
렌더 텍스쳐(Render Texture)
이 기능은 유니티 고급 라이센스에만 있습니다. 이것은 카메라의 뷰를 텍스쳐에 위치시켜서 다른 객체에 적용할 수 있게 합니다.
이것은 스포츠 공간의 비디오 모니터, 감시 카메라, 반사 등을 생성하기 쉽게 합니다.
라이브 공간 카메라(Live arena-cam)를 생성하기 위해 사용된 렌더 텍스쳐.
힌트
•
카메라는 다른 게임오브젝트들처럼 인스턴스화, 부모자식관계설정, 스크립트화 될 수 있습니다.
•
레이싱 게임에서 속도감을 늘리기 위해 높은 시야각(Fild of View)을 사용하세요.
•
카메라는 강체(Rigidbody) 컴포넌트를 추가하면 물리 시물레이션에서 사용 될 수 있습니다.
•
씬에서 사용할 수 있는 카메라 수는 제한이 없습니다.
•
오쏘그래픽 카메라는 3D 유저 인터페이스를 만드는데 유용합니다.
•
만약 바짝 붙은 면들끼리 깜박거리는 깊이 깨짐현상(depth artifacts)이 있다면 근접평면(Near Plane)을 가능한 크게 설정하세요.
•
카메라는 게임 화면과 렌더 텍스쳐에 동시에 렌더할 수 없습니다. 둘 중에 하나에만 가능합니다.
•
프로 라이센스를 가진 사용자에게는 조금 더 특별한 효과를 위해 카메라 뷰를 텍스쳐에 렌더링 할 수 있는 렌더투텍스쳐(Render-toTexture)라는 옵션이 있습니다.
•
유니티는 사전 설치된 카메라 스크립트들을 가지고 있는데 Components->Camera Control 에 있습니다. 무엇이 가능한지 실험해
보세요.
파티클 시스템(Particle Systems)
파티클(Particles)은 근본적으로 3D 공간에서 렌더링 된 2D 이미지들입니다. 그들은 주로 연기, 불, 물, 작은 물방울, 혹은 잎의
효과를 위하여 사용됩니다. 파티클 시스템은 3 개의 별개 컴포넌트로 이루어져 있습니다: 파티클 이미터(Particle Emitter), 파티클
애니메이터(Particle Animator), 그리고 파티클 렌더러(Particle Renderer)입니다. 사용자가 정적(Static) 파티클을 원한다면
파티클 이미터와 렌더러를 같이 사용하면 됩니다. 파티클 애니메이터는 파티클을 여러 방향으로 움직이고 색깔을 변화시킵니다.
사용자는 스크립트를 통해서도 파티클 시스템에서 각 파티클에 접근할 수 있습니다. 그러므로, 사용자가 원하는 방식으로
사용자만의 독특한 행동도 만들어 낼 수 있습니다.
파티클 이미터에서 파티클 스크립팅 레퍼런스를 확인하십시오.
Particle Component Reference 에서도 확인하실 수 있습니다.
Particle Components
Particle Systems
Unity 의 Particle Systems 은 연기, 스트림, 화재의 구름 그리고 다른 대기적인 효과를 만들기 위해 사용됩니다. Particle Systems 은
하나 또는 두 개의 Textures 를 사용해서 그들을 여러번 그리고 혼돈 효과를 만드는 것에 의해 작동합니다.
Standard Assets 에 포함된 Particle System
Unity 의 일반적인 Particle System 은 Particle Emitter, Particle Animator 와 Particle Renderer 를 포함하는 오브젝트 입니다.
Particle Emitter 은 파티클을 생성하고 Particle Animator 은 그들을 시간에 따라 움직이게 하고 Particle Renderer 은 그들을 스크린
위에 그립니다.
만약 세상과 상호 작용하는 파티클을 원한다면 GameObject 에 Particle Collider Component 를 추가합니다.
타원체 입자 방사체(Ellipsoid Particle Emitter)
타원체입자 방사체(Ellipsoid Particle Emitter)는 구 안에 입자를 퍼트립니다. 아래 Ellipsoid 속성을 사용하여 해당 구를 확대하고
확장할 수 있습니다.
타원체 입자 방사체 Inspector
속성
Property:
Function:
Ellipsoid
입자가 내부에 퍼트려지는 구의 X, Y, Z 에 따른 크기.
MinEmitterRange
구의 정 중앙에 빈 공간을 정합니다 – 이 공간을 이용하여 입자가 구의 가장자리에 나타나게 합니다.
상세사항
타원형입자 방사체 (EPEs)는 기본 방사체로, 사용자가 Components->Particles->Particle System 에서 사용자의
장면(Scene)에 Particle System 을 추가하기로 선택하면 포함됩니다. 사용자는 입자가 퍼지는 경계를 정하고, 입자의 최초 속도를
정합니다. 여기서부터는 Particle Animator 을 사용하면 사용자가 흥미로운 효과를 창출하기 위하여 사용자의 입자를 조종할 수 있는
방법을 제공합니다.
최소 배출 범위(Min Emitter Range)
Min Emitter Range 는 타원체 내에서 입자들이 퍼질 수 있는 깊이를 정합니다. 이 값이 0 이 되면 입자들은 타원체의 정 중앙에서
가장 바깥쪽 가장자리까지 어디에든 퍼질 수 있습니다. 1 이 되면, 확산 위치를 타원체의 가장 바깥쪽 범위까지로 제한할 것 입니다.
Min Emitter Range 0
Min Emitter Range 1
메쉬 입자 방사체
Mesh Particle Emitter 는 메쉬 주변에 입자를 방사합니다. 입자는 메쉬의 표면에서부터 퍼지며, 입자가 오브젝트와 복잡한
방식으로 상호작용을 하게 하는데 필요합니다.
메쉬 입자 방사체 Inspector
속성
Property:
Interpolate
Function:
이 속성이 켜지면, 입자는 메쉬의 표면 전체에서 방사됩니다. 꺼지면 입자는 오직 메쉬의 꼭지점들(vertices)에서만
Triangles
방사됩니다.
Systematic
제어하는 것은 드물지만, 대부분의 3D 모델링 응용 프로그램은 프리미티브를 사용하면 매우 시스템적인 설정을
이 속성이 켜지면, 입자는 메쉬에 설정된 꼭지점의 순서대로 퍼집니다. 사용자가 메쉬의 꼭지점 순서를 바로
가지고 있습니다. 중요한 것은 이것이 작동하려면 메쉬에 면이 없어야 합니다.
Min Normal
메쉬로부터 던져진 입자의 최소 개수.
Velocity
Max Normal
메쉬로부터 던져진 입자의 최대 개수.
Velocity
상세사항
메쉬 입자 방사체(MPE)는 사용자가 좀 더 단순한 타원형 입자 방사체 (Ellipsoid Particle Emitter) 보다 퍼지는 위치와 방향을 더
정교하게 제어하고 싶을 때 사용합니다. 이를 사용하면 한 발 더 나아간 효과를 제작할 수 있습니다.
EPS 는 메쉬에 부착된 꼭지점에서 입자를 방사합니다. 그러므로 사용자의 메쉬에서 다각형이 밀집된 부분이 훨씬 더 밀도 높은 입자
방사를 할 수 있습니다.
보간 삼각형
사용자의 방사체에 Interpolate Triangles 을 사용하게 하면 해당 메쉬의 꼭지점 사이에서도 입자들이 방사될 수 있습니다. 이
옵션은 디폴트로는 꺼져 있으므로 디폴트에서는 입자가 꼭지점에서만 방사되게 되어 있습니다.
Interpolate Triangles 이 꺼져있는 구(디폴트)
이 옵션을 사용하면 꼭지점 위와 사이에서 입자가 퍼지며, 본질적으로는 메쉬의 표면 전부에 해당합니다. (아래 참조)
Interpolate Triangles 이 켜져 있는 구
Interpolate Triangles 옵션이 켜지 있는 상태에서도 앞에서 반복 했듯이 사용자 메쉬 상의 입자는 다각형이 많은 영역이 더 입자
밀도가 높습니다.
옵션
Systematic 옵션이 켜지면 사용자의 꼭지점에서 차례대로 입자가 퍼지게 할 수 있습니다. 꼭지점의 순서는 3D 모델링 응용
프로그램에서 정할 수 있습니다.
Systematic 옵션이 켜진 구에 부착된 MPE
노멀 속도(Normal Velocity)
Normal Velocity 는 입자가 퍼져 나와 노멀(normal)을 따라 방사되는 속도를 제어합니다.
예를 들면, 메쉬 입자 시스템(Mesh Particle System)을 생성하고, 큐브 메쉬(cube mesh)를 방사체로 사용하고, Interpolate
Triangles 옵션을 켜고, Normal Velocity Min 와 Max 를 1 로 설정합니다. 이제 사용자는 입자가 큐브의 표면으로부터 직선으로
방사되는 것을 볼 수 있습니다.
추가 참조
•
How to make a Mesh Particle Emitter
Hints
•
MPE 는 장면에 배치된 많은 램프로부터 빛남을 만드는데 사용될 수 있습니다. 단순히 꼭지점이 하나인 메쉬를 각 램프의 중앙에
만들고, 거기서부터 후광(halo) 머티리얼을 가지는 MPE 을 구축합니다. 사악한 과학 공상의 세계에 잘 어울릴 것 입니다.
입자 애니메이터
Particle Animators 는 사용자의 입자를 시간이 지남에 따라 이동시키며, 사용자는 이것을 이용하여 바람에 적용하고 드래그와 색상
순환을 입자 시스템에 적용합니다.
입자애니메이션 Inspector
속성
Property:
Does Animate
Function:
이 속성이 켜지면, 입자들은 생애주기에서 자신들의 색상을 순환 변환합니다.
Color
Color
T 입자들이 순환 변환하는 5 가지 색상. 모든 입자들은 이 색상에서 순환하며 – 어떤 입자들은 다른 입자보다 생애
Animation
주기가 짧고 그런 경우에는 더 빨리 순환합니다.
World Rotation 입자들이 주변을 돌며 회전하는 선택적인 월드 공간의 축. 이것을 사용하면 훨씬 세련된 주문 효과나 소다 버블을
Axis
생생하게 재현할 수 있습니다.
Local Rotation 입자들이 주변을 돌며 회전하는 선택적인 로컬 공간의 축. 이것을 사용하면 훨씬 세련된 주문 효과나 소다 버블을
Axis
생생하게 재현할 수 있습니다.
이 속성을 사용하면 입자의 생애 주기에 걸쳐 크기를 증가하게 할 수 있습니다. 무작위의 힘이 가해져서 사용자의
Size Grow
입자들이 퍼져나가는 만큼 그들의 크기를 키워서 부서지지 않게 하는 것도 유용합니다. 이것을 사용하여 연기가
위로 올라가거나 바람을 재현하는 등에 사용하면 됩니다.
Rnd Force
각 프레임에서 입자에 추가되는 무작위의 힘. 이것을 사용하면 연기를 좀 더 생생하게 재현할 수 있습니다.
Force
각 프레임마다 입자들에 적용되는 힘으로 세상(world)에서 상대적으로 측정합니다.
Damping
각 프레임마다 입자들이 얼마나 느려지는 지를 나타냅니다. 값이 1 이면 전혀 입자들이 느려지지 않고 줄어듭니다.
Autodestruct
이 속성이 켜지만, 입자들이 사라질 때 입자 애니메이터에 부착된 GameObject 도 사라집니다.
상세사항
입자 애니메이터는 사용자의 입자 시스템이 동적으로 될 수 있게 하여 줍니다. 이것을 사용하면 입자 색깔을 바꾸고 힘을 가하고
회전하고 방사가 끝나면 부서지게 할 수도 있습니다. 입자 시스템에 관한 좀 더 자세한 정보를 알고 싶다면 Mesh Particle Emitters,
Ellipsoid Particle Emitters, 그리고 Particle Renderers 을 참조하시오.
애니메이션 색상
사용자의 입자가 색상을 바꾸거나 나타나고 사라지게 하고 싶다면, Animate Color 속성을 켜고 해당 순환을 위한 색상을
지정하십시오. 색상이 변환하는 입자는 사용자가 선택한 5 개의 색상에 따라 변환 할 것 입니다. 그 순환의 속도는 방사기의 Energy
값에 따라 결정됩니다.
사용자의 입자가 즉시 사라지기 보다는 서서히 사라지게 하고 싶다면, 사용자가 첫 번째와 마지막 색상을 매우 낮은 알파 색상으로
설정하면 됩니다.
Animating Color 입자 시스템
회전축
속성 값을 정하는 것은 퍼진 입자들이 지정된 축 주변을 돌게 할 것 입니다 (중앙에 Transform's 의 위치를 가진 축). 이 축 중 한 축의
값이 클수록, 회전은 더 빨라질 것 입니다.
로컬 축(Local Axes) 속성 값을 설정하면 회전 입자는 Transform 의 회전이 변함에 따라 자신의 축을 거기에 맞추어 변화 할 것
입니다.
월드 축(World Axes) 속성 값을 설정하면 Transform 의 회전에 상관없이 입자의 회전이 일정하게 됩니다.
힘과 제동
사용자는 힘을 사용하여 입자들이 힘에서 지정된 방향으로 가속하게 만듭니다.
Damping 는 방향의 전환 없이 가속하거나 감속하게 할 수 있습니다:
•
값 1 은 Damping 이 적용되지 않았으며, 입자는 느려지거나 빨라지지 않을 것 이라는 것을 의미합니다.
•
값 0 은 입자들이 즉시 멈춰질 것을 의미합니다.
•
값 2 는 입자들이 매 초마다 속도를 배로 늘려가는 것을 의미합니다.
입자에 부착된 GameObjects 의 제거
사용자는 AutoDestruct 속성을 사용하여 입자시스템과 거기에 부착된 GameObject 를 제거할 수 있습니다. 예를 들면, 사용자가
기름통이 있다면 거기에 Emit 속성이 꺼지고 AutoDestruct 속성이 켜진 입자 시스템을 부착할 수 있습니다. 충돌 시에 사용자는
Particle Emitter 속성을 켜면 충돌 후 폭발이 발생할 것 입니다. 그 입자시스템과 기름통은 그 장면에서 파괴되고 그 장면에서 사라질
것 입니다.
그 자동파괴는 일부 입자가 방사된 후에야 효과를 발휘할 것 임을 주의하십시오. AutoDestruct 속성이 켜졌을 때 언제 해당
오브젝트가 파괴 될 것인가에 대한 정확한 규칙은:
•
만일 일부 입자가 이미 방사되었으나 지금은 모두 사라졌거나, or
•
해당 emitter 가 어떤 시점에서 Emit 속성이 켜져 있었으나 지금은 꺼져 있는 경우.
Hints
•
Color Animation 을 사용하여 사용자의 입자들이 생애 주기에 걸쳐 나타나고 사라지게 할 수 있습니다. 그렇지 않으면 흉한
모양으로 터지게 됩니다.
•
Rotation Axes 속성을 사용하면 소용돌이 모양의 회전 움직임을 재현할 수 있습니다.
Particle Collider
World Particle Collider 는 씬에서 다른 Colliders 에 대항해서 입자들을 충동하기 위해 사용됩니다.
Mesh Collider 를 사용해서 충돌하는 Particle System
Properties
Property:
Function:
입자들은 그들이 다른 오브젝트에 충돌할 때 빨라지거나 느려질 수 있습니다. 이런 요인은 Particle
Bounce Factor
Animator's Damping 소성과 유사합니다.
Collision Energy
충돌할 때 하나의 입자가 잃어야 하는 에너지의 양 (초 단위). 에너지가 0 아래로 내려가면 입자는
Loss
소멸됩니다.
Min Kill Velocity
입자의 Velocity 가 충돌 때문에 Min Kill Velocity 아래로 떨어지면 그것은 제거될 것입니다.
Collides with
어떤 Layers 에 대항해서 입자가 충돌하는지 나타냅니다.
Send Collision
활성화되면 모든 입자는 사용자가 스크립팅을 통해 알 수 있는 충돌 메세지를 보냅니다.
Message
Details
Particle Collider 와 함께 Particle System 을 생성하는 법:
1.
GameObject->Create Other->Particle System 을 사용해서 Particle System 을 생성합니다.
2.
Component->Particles->World Particle Collider 을 사용해서 Particle Collider 을 생성합니다.
Messaging
Send Collision Message 가 활성화되면 충돌에 있는 어떠한 입자라도 입자의 GameObject 와 GameObject 가 충돌하고 있는
입자에 OnParticleCollision() 메세지를 보낼 것입니다.
Hints
•
Send Collision Message 는 총알을 시뮬레이션 하고 손상을 적용하기 위해 사용될 수 있습니다.
•
Particle Collision Detection 은 많은 입자들과 함께 사용될 때 느려집니다. Particle Collision Detection 를 현명하게 사용하시기
바랍니다.
•
메세지를 보내는 것은 커다란 오버헤드를 낳고 보통의 Particle Systems 을 위해서는 사용되지 않는 것이 좋습니다.
Particle Renderer
스크린 위의 Particle System 을 그리는 Particle Renderer.
파티클 렌더러 Inspector
Properties
Property:
Materials
Camera Velocity
Function:
각 개별적인 파티클의 위치에서 보여질 Materials 의 리스트로 레퍼런스.
Camera 움직임에 기반한 파티클에 적용되는 늘여지는 양.
Scale
Stretch Particles
파티클이 어떻게 렌더되는지를 결정합니다.
Billboard
카메라를 대하는 것처럼 파티클이 렌더해 집니다.
Stretched
파티클들은 그들이 움직이고 있는 방향을 마주하고 있습니다.
SortedBillboard
파티클이 깊이에 의해 정렬됩니다. 재료를 섞는 것을 사용할 때 이것을 사용합니다.
VerticalBillboard
모든 파티클들은 X/Z 축에 따라 평평하게 정렬됩니다.
HorizontalBillboard
모든 파티클들은 X/ Y 축에 따라 평평하게 정렬됩니다.
Stretch Particles 이 Stretched 로 세팅되면 이 값은 파티클이 그들의 모션의 위치에 얼마나 길게
Length Scale
있는지를 결정합니다.
Stretch Particles 이 Stretched 로 세팅되면 이 값은 어떤 파티클이 그들의 움직임 속도에 기반해서
Velocity Scale
어떠한 비율로 늘여질지를 결정합니다.
이것들 중 어떤 하나가 세팅되면 파티클의 UV 좌표는 타일 애니메이션 텍스쳐와 함께 사용을 위해 생성될
UV Animation
것입니다. 아래의 Animated Textures 섹션을 보십시오.
X Tile
X 축을 따라서 위치된 프레임 수.
Y Tile
Y 축을 따라서 위치된 프레임 수.
Cycles
애니메이션 시컨스를 반복하는 횟수.
Details
Particle Renderers 는 스크린 위에 보여지는 어떠한 파티클 시스템을 위해서라도 요구됩니다.
파티클 렌더러는 Gunship 의 엔진을 스크린 Gunship 위에 나타나도록 합니다
Choosing a Material
파티클 렌더러를 셋업할 때 적절한 재료와 재료의 양쪽 사이드를 렌더하는 쉐이더를 사용하는 것이 매우 중요합니다. 대부분의
시간에 사용자는 내장된 파티클 쉐이더의 하나와 함께 하나의 재료를 사용하기를 원합니다. 사용자가 사용할 수 있는 Standard
Assets->Particles->Sources 폴더에서 몇몇의 미리 만들어진 재료가 있습니다.
새로운 재료를 생성하는 것은 평이합니다:
1.
메뉴바에서 Assets->Create Other->Material 를 선택하세요.
2.
Material 은 쉐이더 팝업을 가지고 파티클 그룹의 쉐이더 중 하나를 선택합니다. 예.Particles->Multiply.
3.
하나의 텍스쳐를 지정합니다. 다른 쉐이더는 텍스쳐의 알파 채널을 약간 다르게 사용합니다. 그러나 대부분의 시간에
검정의 값은 그것을 보이지 않게 만들고 알파 채널에서 흰색의 값은 그것을 스크린위에 보여줄 것입니다.
Distorting particles
기본적으로 파티클은 그려집니다. 그것은 간단한 사각형입니다. 이것은 연기와 폭발 그리고 대부분 다른 파티클 효과를 위해서
좋습니다.
파티클은 속도와 함께 늘이기 위해 만들어질 수 있습니다. 이것은 불꽃, 조명 또는 레이저 빔을 위해 유용합니다. Length Scale 과
Velocity Scale 이 그 늘여지는 입자가 얼마나 길지에 영향을 줍니다.
Sorted Billboard 는 모든 파티클을 깊이에 의해 정렬되게 만들기 위해서 사용될 수 있습니다. Alpha Blended 파티클 쉐이더를
사용할 때 때때로 이것이 필요합니다. 이것은 비용이 많이 들 수 있고 그것이 렌더링할 때 질적인 차이를 만든다면 사용되어져야
합니다.
Animated textures
파티클 시스템은 애니메이션된 타일 텍스쳐와 함게 렌더될 수 있습니다. 이 특성을 사용하기 위해서 이미지의 격자 밖으로 텍스쳐를
만듭니다. 파티클이 그들의 라이프 싸이클을 통과하면서 그들은 이미지를 통해 순환될 것입니다. 이것은 사용자의 파티클에 더 많은
라이프를 추가하거나 작은 회전하는 조각 파편들을 만들기 위해 좋습니다.
Hints
•
파티클 렌더러와 함께 있는 파티클 쉐이더를 사용합니다.
Terrain Engine Guide
이 섹션은 Terrain Engine 을 어떻게 사용할 지 설명합니다. 생성, 테크니컬 디테일 그리고 다른 고려사항들도 포함합니다. 다음의
섹션들로 나누어 집니다:
Using Terrains
이 섹션은 Terrains 사용에 대한 가장 기본적인 정보를 다룹니다. 이것은 Terrains 의 생성과 새로운 Terrains 툴과 브러쉬를 어떻게
사용하는지를 다룹니다.
Height
이 섹션은 Terrains 의 높이를 바꾸는 다른 툴과 브러쉬를 어떻게 사용하는지를 설명합니다.
Terrain Textures
이 섹션은 다른 브러쉬를 사용해서 Terrains 텍스쳐들을 추가하고 페인팅하고 그리고 블렌드 하는지를 설명합니다.
Trees
이 섹션은 사용자 자신의 나무 에셋을 생성하기 위한 중요한 정보를 포함합니다. 그것은 또한 사용자의 Terrains 에 나무를 추가하고
그리는 것을 포함합니다.
Grass
이 섹션은 풀들이 어떻게 작동하고 그것을 어떻게 사용하는지를 설명합니다.
Detail Meshes
이 섹션은 바위, 건초더미, 초목등과 같은 디테일 메쉬를 위한 실용적인 사용법을 설명합니다.
Lightmaps
사용자는 Unity 의 내장 lightmapper 를 사용해서 어떠한 다른 물체들같은 terrains 을 lightmap 할 수 있습니다. 도움을
위해서 Lightmapping Quickstart 를 참고하시기 바랍니다.
Other Settings
이 섹션은 Terrains 과 관련된 모든 다른 세팅을 다룹니다.
iOS
성능 히트로 인해, Terrain Engine 사용은 ipad2 이전의 디바이스에서는 권장되지 않습니다.
Android
성능 히트로 인해, Terrain Engine 사용은 고도 성능의 디바이스가 아닌 곳에서는 권장되지 않습니다.
에셋 불러오기와 만들기(Asset Import and Creation)
게임 제작의 큰 부분이 사용자의 에셋 소스 파일들을 사용자의 게임오브젝트(GameObjects)에서 활용하는 것입니다. 이것은 텍스쳐,
모델, 사운드 이펙트와 행동 스크립트를 위한 것입니다. 유니티 안에 프로젝트 뷰(Project View)를 사용하여, 사용자가 사용자의
게임을 구성하는 모든 파일들에 빠른 접근을 할 수 있게 합니다:
프로젝트 뷰는 모든 소스 파일과 생성된 프리팹(Prefabs)을 보여줍니다
이 뷰는 사용자의 프로젝트 에셋 폴더에서 파일들의 구성을 보여줍니다. 사용자가 사용자의 에셋 파일 중 하나를 업데이트할 때마다
변경된 사항이 사용자의 게임에 바로 반영됩니다!
사용자의 프로젝트로 하나의 에셋 파일을 불러오기 위해서 파일을 파인더(Finder) 안의 (사용자의 프로젝트 폴더)->Assets 으로
옮깁니다. 그것은 유니티로 자동적으로 불려와지게 됩니다. 사용자의 에셋을 적용하기 위해서 프로젝트 뷰 윈도우로부터 에셋
파일을 계층뷰(Hierarchy) 또는 씬뷰(Scene View)로 드래그 합니다. 에셋이 또다른 오브젝트에 적용된다면 에셋을 오브젝트 위로
드래그 합니다.
힌트
•
사용자가 큰 프로젝트 작업시 또는 사용자가 모든 에셋을 잘 정리정돈하고 싶을 때 사용자의 에셋에 레이블을 추가하는 것은 좋은
생각입니다. 이렇게 할 경우 사용자는 프로젝트 뷰의 검색창(search field)에서 각 에셋과 연결된 레이블을 검색할 수 있습니다.
•
프로젝트 폴더를 백업하고 있을 때 라이브러리(Library)와 에셋(Assets) 폴더도 항상 백업합니다. 라이브러리 폴더는 모든 메타
데이터(meta data)와 객체들 사이의 모든 연결을 담고 있기 때문에 만약 라이브러리 폴더를 잃게 될 경우 사용자의 씬부터
에셋까지의 참조(references)도 모두 잃게 됩니다. 가장 쉬운 방법은 에셋과 라이브러리 폴더를 포함하고 있는 프로젝트 폴더 전체를
백업하는 것입니다.
•
파일들의 이름을 바꾸고 그것을 프로젝트 뷰 안의 중요 콘텐츠로 옮기세요. 아무 것도 망가지지 않을 것입니다.
•
파인더(Finder) 혹은 다른 프로그램으로부터 이름을 바꾸거나 이동하면 절대 안됩니다; 모든 연결이 망가지게 됩니다. 간단히 말하면
유니티는 각 에셋에 관한 많은 메타 데이터를 저장합니다 (불러오기 세팅, 압축된 텍스쳐의 캐쉬(cache)된 버전 등). 만약 사용자가
하나의 파일을 외부에서 움직인다면 유니티는 더이상 그 이동된 파일을 메타데이터와 연관지을 수 없게 됩니다.
더 많은 정보를 위해서 다음을 읽어보시기 바랍니다:
•
에셋 임포트
•
메쉬
•
애니메이션
•
매터리얼
•
텍스쳐
•
진행형(Procedural) 매터리얼
•
비디오 파일
•
오디오 파일
o
트랙커 모듈
•
스크립팅
•
에셋 스토어
o
에셋스토어 들어가기
o
에셋스토어 네비게이션
o
에셋스토어 다운로드매니져
•
에셋 서버
•
메타데이터 관리 뒷이야기
에셋들 불러오기(Importing Assets)
유니티는 프로젝트 폴더내의 에셋(Assets)폴더에 파일이 추가 될 때 자동으로 감지를 합니다. 에셋(Asset) 폴더에 어떠한 에셋을
넣게 되면 프로젝트 뷰(Project View)에 에셋이 보이게 되는 것을 알 수 있습니다.
프로젝트 뷰는 에셋 폴더의 내부를 보는 창이며, 보통 파일 매니져(File Manager)를 통하여 접근합니다
프로젝트 뷰를 정리정돈시, 한 가지를 특히 주의하셔야 합니다:
윈도우의 익스플로러(Explorer) 또는 OS X 의 파인더(Finder)로 이 폴더를 건들거나 에셋(asset)을 이동시키면 절대 안됩니다. 항상
프로젝트 뷰(Project View)를 사용하여 해당 작업을 수행해야 합니다!
유니티 내부에는 에셋 파일들 사이의 관계에 관한 수많은 메타 데이터가 저장되어 있습니다. 이 데이터들은 유니티가 이러한
에셋들을 어디서 찾을수 있느냐에 영향을 받습니다. 만약 프로젝트 뷰에서 에셋이 옮겨졌다면, 이러한 관계들은 유지가 됩니다.
하지만 유니티 밖에서 옮겨졌다면 이러한 관계들이 끊어지게 됩니다. 이 경우 이들 관계(dependencies)의 많은 부분을 수동으로
재연결해야 하는데, 이는 결코 원하는 상황이 아닐 것입니다.
그러므로, 다른 어플리케이션으로부터는 오직 에셋 폴더에만 에셋을 저장하는 것이 괜찮다는 것을 명심하세요. 유니티 밖에서는
파일들의 이름을 바꾸거나 파일을 옮기지 말고 항상 프로젝트 뷰를 사용하세요. 물론 파일 수정을 위해 파일을 안전하게 여는 것은
어느 곳에서나 가능합니다.
에셋들 생성과 업데이트(Creating and Updating Assets)
게임을 만들 때 어떤 종류의 에셋을 추가하길 원하는 경우는 에셋을 생성하고 에셋 폴더 내에 저장을 하면 됩니다. 유니티로
돌아오거나 실행 시키면, 추가된 파일들이 감지되어 지고 불러와질 것입니다.
추가적으로, 에셋들을 업데이트하고 저장할 때 변화들은 자동 감지되고, 유니티 내에서 에셋은 다시 불러오기 되어집니다. 이는
유니티와 에셋과의 호환성에 신경을 쓰지 않고 에셋을 더 다듬는 것에 집중할 수 있게 해줍니다. 원래 어플리케이션에서 일반적으로
에셋들을 업데이트하고 저장하는 것은 최적화 되고 무리가 없는 자연스런 작업 방식(workflow)입니다.
에셋 종류들(Asset Types)
게임에 들어갈 수 있는 기초적인 에셋 종류들이 있습니다. 종류들은 아래와 같습니다:
•
메쉬 (Mesh) 파일들과 애니메이션(Animations)들
•
텍스쳐(Texture) 파일들
•
사운드(Sound) 파일들
이러한 파일 타입들을 가져오는 세부 사항들과 그들이 어떻게 사용되는지 알아보겠습니다.
메쉬와 애니메이션(Meshes & Animations)
어떤 3D 패키지를 사용하더라도, 유니티는 각각의 파일로부터 메쉬들과 애니매이션 들을 불러오기를 할 것입니다. 유니티에서
지원되는 어플리케이션들의 목록을 보기 위해서는 오브젝트 불러오기를 참조하십시오.
메쉬 파일은 불러오기 할 애니메이션을 가질 필요가 없습니다. 애니메이션을 사용하면, 단일 파일로부터 모든 애니메이션들을
불러오기 선택을 할 수 있습니다. 또는, 각각 하나의 애니메이션을 가지는 분리된 파일들을 불러오기 할 수 있습니다. 애니메이션을
불러오는 것에 대한 더 많은 정보를 원하시면 Animation Import 페이지를 참조 하시기 바랍니다.
메쉬가 유니티로 불러와 지면, 메쉬를 씬뷰(Scene)이나 계층뷰(Hierarchy)로 드래그 해서 메쉬의 인스턴스를 만들 수 있습니다.
또한, 컴포넌트를 인스턴스에 추가할 수 있으며, 이는 메쉬 파일 자체에 부착 되지는 않습니다.
메쉬들은 UV 와 몇몇 기본 재질(Materials) (UV 당 한 개의 재질)을 사용해서 불러오게 됩니다. 이 재질들에 알맞은 텍스쳐 파일들을
지정하여, 유니티의 게임엔진에서 메쉬의 기본적인 외관설정을 완료할 수 있습니다.
텍스쳐들(Textures)
유니티는 모든 종류의 이미지 포맷들을 지원합니다. 레이어들이 적용된 (layered) 포토샵 파일들 작업을 할 때도, 포토샵 포맷을
훼손하지 않고 불러옵니다. 이는 하나의 텍스쳐 파일로 더 능률적으로 작업할 수 있게 해줍니다.
텍스쳐를 만들 치수는 2 의 지수 승 이어야 합니다. (예: 32x32, 64x64, 128x128, 256x256, 등.) 텍스쳐들을 프로젝트의 에셋(Asset)
폴더에 위치시키는 것만으로 충분하며 그러면 텍스쳐들이 프로젝트 뷰에 보일 것입니다.
텍스쳐이 불러와 졌을 때는 Material 에 할당하셔야 합니다. 그 재질(Material)은 메쉬와 파티클 시스템, 또는 GUI 텍스쳐(GUI
Texture)에 적용될 것입니다. 불러오기 세팅(Import Settings)을 사용해서, 게임 내부에서 다른 종류의 어플리케이션들을 위한
큐브맵(Cubemap)이나 노멀맵(Normalmap)으로 변환되어 질 수 있습니다. 텍스쳐 불러오기에 대한 더 많은 정보를 보기 위해서는
Texture Component page 페이지를 보시길 바랍니다.
사운드(Sounds)
Desktop
유니티 기능들은 두 종류의 오디오를 지원합니다: 비압축 오디오(Uncompressed Audio) 또는 Ogg Vorbis 입니다. 프로젝트로
가져와진 어떤 종류의 오디오 파일 타입도 이 포맷들 중의 하나로 변환되게 됩니다.
파일 종류 변환
.AIFF
불러오기 시 비 압축된 오디오로 변환, 짧은 사운드 효과에 최상.
.WAV
불러오기 시 비 압축된 오디오로 변환, 짧은 사운드 효과에 최상.
.MP3
불러오기 시 Ogg Vorbis 로 변환, 더 긴 음악 트랙에 최상.
.OGG
오디오 압축 포맷, 더 긴 음악 트랙에 최상.
불러오기 설정(Import Settings)
Ogg Vorbis 로 이미 압축되어 있지 않은 파일을 불러오기 할 때는, 오디오 클립의 불러오기 설정(Import Settings)에 몇가지
옵션들이 있습니다. 프로젝트 뷰에서 오디오 클립을 선택하고, 인스펙터의 오디오 불러오기(Audio Importer)의 옵션을 수정합니다.
여기서 오디오 클립을 Ogg Vorbis 포맷으로 압축하여, 모노(Mono)또는 스테레오 재생(Stereo playback)으로 만들 수 있고, 다른
옵션들도 수정할 수 있습니다. 이들은 모두 Ogg Vorbis 와 비압축 오디오 모두에게 긍정과 부정적인 면이 있습니다. 각각은 자신의
최상의 사용 시나리오가 있으며, 일반적으로 한가지만 배타적으로 사용하시는 것은 권장하지 않습니다.
Ogg Vorbis 또는 비압축 오디오의 사용을 위해서는 Audio Clip Component Reference page 페이지를 읽으시길 바랍니다.
iOS
유니티 기능들은 두 종류의 오디오를 지원합니다: 비압축 오디오(Uncompressed Audio) 또는 MP3 Compressed audio 입니다.
프로젝트로 불러와진 어떤 종류의 오디오 파일 타입도 이 포맷들 중의 하나로 변환되게 됩니다.
파일 타입 변환(File Type Conversion)
.AIFF
짧은 사운드 효과들을 위한 비 압축 오디오로 불러오기. 필요 시 에디터에서 압축 가능.
.WAV
짧은 사운드 효과들을 위한 비 압축 오디오로 불러오기. 필요 시 에디터에서 압축 가능.
더 긴 음악 트랙을 위한 Apple 네이티브 압축 포맷으로 불러오기. 디바이스 하드웨어에서 재생 가능.
.MP3
OGG 압축 오디오 포맷, iPhone 디바이스들과는 비호환. iPhone 에서는 MP3 압축 사운드(MP3 compressed sounds)들을
.OGG
사용해 주십시오.
불러오기 설정 (Import Settings)
오디오 파일을 불러오기 할 때, 최종 포맷을 선택 할 수 있으며, 스테레오 또는 모노 채널로 되도록 선택할 수 있습니다. 불러오기
세팅에 접근 하려면, 프로젝트 뷰에서 오디오 클립(Audio Clip)을 선택합니다. 그리고 인스펙터 탭에서 오디오 임포터(Audio
Importer)를 찾습니다. 여기서, 오디오 클립을 Ogg Vorbis 으로 압축할 수 있으며, 모노 또는 스테레오 재생으로 되게 할 수 있으며,
다른 옵션들을 수정(예: “Decompress On Load” 설정) 할 수도 있습니다.
MP3 압축 또는 비 압축 오디오에 대해서는 Audio Clip Component Reference page 페이지를 참조하시길 바랍니다.
Android
유니티 기능들은 두 종류의 오디오를 지원합니다: 비압축 오디오(Uncompressed Audio) 또는 MP3 Compressed audio 입니다.
프로젝트로 불러와진 어떤 종류의 오디오 파일 타입도 이 포맷들 중의 하나로 변환하게 됩니다.
File Type Conversion
.AIFF
짧은 사운드 효과들을 위한 비 압축 오디오로 불러오기. 필요 시 에디터에서 압축 가능.
.WAV
짧은 사운드 효과들을 위한 비 압축 오디오로 불러오기. 필요 시 에디터에서 압축 가능.
더 긴 음악 트랙을 위한 MP3 압축 포맷(MP3 compressed format)으로 불러오기.
.MP3
OGG 압축 오디오 포맷, 몇몇 안드로이드(Android) 기기들과는 비호환. 유니티는 안드로이드 플랫폼을 위한 OGG 압축
.OGG
포맷을 지원하지 않습니다. MP3 압축 사운드들을 대신 사용해 주십시오.
불러오기 설정(Import Settings)
오디오 파일을 불러오기 할 때, 최종 포맷을 선택 할 수 있으며, 스테레오 또는 모노 채널로 되도록 선택할 수 있습니다. 불러오기
설정에 접근 하려면, 프로젝트 뷰에서 오디오 클립(Audio Clip)을 선택합니다. 인스펙터 탭에서 오디오 임포터(Audio Importer) 를
찾습니다. 여기서, 오디오 클립을 Ogg Vorbis 으로 압축할 수 있으며, 모노 또는 스테레오 재생으로 되게 할 수 있으며, 다른 옵션들을
수정(예: “Decompress On Load” 설정) 할 수도 있습니다.
MP3 압축또는 비 압축 오디오에 대해서는 Audio Clip Component Reference page 페이지를 참조하시길 바랍니다.
사운드 파일들을 불러오면 게임오브젝트에 부착 시킬 수 있습니다. 오디오 파일은 게임오브젝트로 오디오 파일을 드래그 할때 Audio
Source Component 를 자동으로 생성합니다.
Meshes
3D 게임의 핵심은 메쉬입니다。 Meshes 는 삼각형들과 질감들이 적용된 오브젝트들입니다.
유니티에서 메쉬들은 renderer 컴포넌트들로 렌더됩니다. 많은 변형들이 있지만, 메쉬 렌더러 Mesh Renderer 가 가장 흔히
쓰입니다.
•
렌더러는 GameObject 의 위치에서 메쉬를 표시합니다.
•
메쉬의 외형은 렌더러의 Materials 를 통해 컨트롤됩니다.
Mesh Renderer 와 함께 쓰인 Mesh Filter 는 모델을 스크린에 보이게 합니다.
메쉬
Meshes 는 사용자의 3D 작업에 많은 비중을 차지합니다. 사용자는 메쉬를 유니티에서 구축하지 않고 다른 어플리케이션에
구축합니다.
유니티서는 이 과정을 최대한 단순하게 하려고 최선을 다 하였습니다. 더 많은 상세 정보가 있지만 다음에 페이지에 오는 사항들은
일반적은 3D 아트 패키지의 모든 상세사항을 언급하고 있습니다:
•
Maya
•
Cinema 4D
•
3ds Max
•
Cheetah3D
•
Modo
•
Lightwave
•
Blender
다른 어플리케이션
유니티는 .FBX, .dae (Collada), .3DS, .dxf 그리고 .obj 읽을 수 있으므로, 만일 사용자 프로그램이 이 포맷으로 내보내기가 될 수
있다면 사용자의 작업은 성공적이라고 볼 수 있습니다. Collada 내보내기도 많은 패키지를 위해 사용 가능합니다.
텍스처
유니티는 자동으로 사용자가 들여온 장면(scene)에 material 을 연결하려고 시도할 것 입니다. 이것을 이용하려면, 사용자의
텍스처를 장면(scene) 파일 옆에 있는 "Textures" 라는 폴더나 혹은 그 상위 폴더 어디에든 두면 됩니다.
해당 에셋 혹은 그 상위 레벨 Textures 폴더에 사용자의 텍스처를 둡니다
들어오기 설정.
3D 메쉬 파일을 위한 Import Settings 을 사용하려면, Inspector 에 나타나는 설정과 관련 설정을 선택하십시오.
메쉬 들여오기 설정 대화창
Property:
Function:
Meshes
유니티의 물리 시스템은 들여온 파일에서 게임월드에서의 1 단위는 1 미터라고 가정합니다. 만일 사용자가
Scale Factor
다른 단위를 사용하였다면, 여기에서 고치면 됩니다.
이 옵션은 오직 3dsMax 파일에서만 사용할 수 있습니다. 이 속성이 켜지면 3dsMax 을 1FileUnit=1UnityUnit 로
Use File Units
들여오고, 그렇지 않으면 1cm=1UnityUnit 으로 들여옵니다.
이 속성을 올리면 메쉬의 크기가 줄어들게 되고 비일정성(irregularities)이 생길 수도 있습니다. 이 속성을
Mesh Compression
최대한으로 올리되 메쉬가 비압축 버전보다 크게 다르게 보이지 않는 선까지 올립니다. 이 속성은 optimizing
game size 에서도 유용하게 사용됩니다.
이 속성이 켜지면, 사용자의 메쉬는 메쉬 콜라이더(Mesh Colliders )가 자동 부착된 채 들여올 것 입니다. 이것은
Generate
Colliders
환경기하에서 콜리전(collision) 메쉬를 빠르게 생성할 대 유용하나, 사용자가 이동해야 할 지리에서는 피하여야
합니다. 더 자세한 정보를 보려면, 아래 Colliders 를 참조하십시오.
만일 라이트맵(lightmapped) 오브젝트가 잘못된 UV 채널을 선택할 때 사용합니다. 이는 사용자의 주요 및 보조
Swap UVs
Generate
UV 채널을 맞교환 합니다.
라이트매핑(Lightmapping)에 사용 될 UV2 을 생성하는 데 사용합니다.
Lightmap UVs
Advanced Options Lightmapping UVs document 을 참조하십시오.
Normals &
Tangents
Normals
노멀(normal,)이 만일 또는 어떻게 계산 될지를 설정합니다. optimizing game size 을 위해 유용합니다.
Import
디폴트 옵션으로, 파일로부터 normal 을 들여옵니다.
Calculate
Smoothing angle 를 기준으로 노멀을 계산합니다. 이 속성이 선택되면, Smoothing angle 이 켜 집니다.
Tangents 와 binormals 속성을 끕니다. 이 메쉬는 Tangents 를 가지지 않으므로, 노멀맵 쉐이더(normal-mapped
None
shaders)와는 작동하지 않습니다.
tangents 와 binormals 이 만일 그리고 어떻게 연산되어야 하는지를 설정합니다. 게임 사이즈 최적화
Tangents
Import
[[ReducingFilesize | optimizing game size]에 유용합니다].
탄젠트(tangent, 접선)와 바이노멀(binormal, 종법선)을 파일로부터 불러들입니다.
디폴트 옵션이며 탄젠트와 바이노멀을 계산합니다. 이 옵션은 노멀이 들여왔거나 계산되었을 때만 사용할 수
Calculate
있습니다.
Tangents 와 binormals 속성을 끕니다. 이 메쉬는 Tangents 를 가지지 않으므로, 노멀맵 쉐이더(normal-mapped
None
shaders)와는 작동하지 않습니다.
단단한 가장자리로 간주되려면 가장자리가 얼마나 뾰족한지를 설정합니다. 노멀 맵 탄젠트(normal map
Smoothing Angle
tangents)를 분리하는 데 사용됩니다.
만일 노멀 맵 조명이 사용자 메쉬의 경계(seam),에 의해 부서지면 이 속성을 켭니다. 이것은 일반적으로
Split Tangents
문자에만 적용합니다.
Materials
Generation
Off
머티리얼(material)이 어떻게 생성되는지를 통제합니다:
이 속성을 사용하면 머티리얼이 전혀 생성되지 않을 것 입니다.
이 속성을 켜면, 찾은 텍스처 파일 주위에 머티리얼 파일을 생성합니다. 이 속성이 켜지면, 서로 다른
Per Texture
장면(scene)도 같은 텍스처를 사용하는 경우에는 같은 머티리얼 설정을 공유합니다. 정확한 규칙을 보려면,
아래의 머티리얼 생성(Material Generation) 참조하십시오.
Per Material
이 속성을 사용하면 장면마다 머티리얼을 생성하므로, 해당 장면 만 그것을 사용합니다.
Animations
Generation
Don't Import
Store in
Original Roots
애니메이션이 어떻게 들여오는지를 통제합니다:
애니메이션이나 스키닝(skinning)은 들여오지 않습니다.
애니메이션을 사용자 애니메이션 패키지의 루트 오브젝트에 저장합니다 (유니티에서의 루트 오브젝트와는
다를 수 있습니다).
애니메이션이 같이 동작하는 오브젝트와 함께 저장됩니다. 사용자의 애니메이션 설정이 복잡하고 사용자가
Store in Nodes
완전한 스크립트 제어를 원한다면 이 속성을 사용하면 됩니다.
애니메이션이 장면(scene)의 트랜스폼 루트 오브젝트에 저장됩니다. 계층 구조가 있는 무엇이든 애니메이션을
Store in Root
할 때 이 속성을 사용하면 됩니다.
사용자의 애니메이션 패키지에서 IK 나 시뮬레이션을 사용할 때, 이 속성을 켜면 됩니다. 유니티가 들여오기
Bake Animations
Animation Wrap
mode
실행 시에 FK 로 변환할 것 입니다. 이 옵션은 Maya, 3dsMax 그리고 Cinema4D 파일에만 사용 가능합니다.
들여오기를 실행하는 메쉬에 있는 애니메이션을 위한 디폴트 Wrap Mode
Split Animations 만일 하나의 파일에 여러 개의 애니메이션이 있다면, 사용자는 여러 개의 클립으로 나눌 수 있습니다.
Name
나누어지는 애니메이션 클립의 이름
Start
해당 모델 파일 내 해당 클립의 첫 프레임
해당 모델 파일 내 해당 클립의 마지막 프레임
End
WrapMode
애니메이션의 끝에 다다르면 나누어진 클립이 무엇을 하는 지를 정합니다
애니메이션이 생성된 방식에 따라, 나누어진 클립이 룹을 하려면 추가로 하나의 프레임이 더 필요할 수
Loop
있습니다. 만일 사용자 애니메이션 룹에 문제가 있어 보이면, 이 옵션을 켜면 됩니다.
Animation
Compression
Anim.
해당 메쉬의 애니메이션에 적용될 압축 타입
Compression
애니메이션 압축 속성을 끕니다. 이렇게 하면 유니티는 들여오기 실행 시 키프레임을 줄이지 않고, 최고의
선명한 애니메이션을 생성하지만, 이것은 또한 느린 성능과 더 큰 파일 크기와 더 큰 실행 메모리 크기를
Off
의미합니다. 만일 사용자가 더 높은 선명도의 애니메이션이 필요로 한다면 이 속성은 권고하지 않으며, 그
대신에 사용자는 키프레임 감소(keyframe reduction) 속성을 켜고 Animation Compression Error 에 더 낮은
값을 허용해야 합니다.
Keyframe
Reduces keyframes on import. If selected, the Animation Compression Errors options are displayed.
Reduction
Keyframe
Reduction and
Compression
들여오기 실행 시 키프레임(keyframe)을 감소시키고 애니메이션 파일을 저장할 때 키프레임을 압축합니다.
이렇게 하면 파일 사이즈만 영향을 받고, 실행 시 메모리 크기는 Keyframe Reduction 와 같은 값을 가집니다.
이 속성이 선택되면 Animation Compression Errors 옵션이 나타납니다.
Animation
Compression
이 옵션은 Keyframe Reduction 이 켜질 때만 사용 할 수 있습니다.
Errors
회전 커브가 얼마나 감소되어야 하는지를 정합니다. 사용자가 적은 값을 사용할수록, 더 높은 선명도를 가지게
Rotation Error
됩니다.
위치 커브가 얼마나 감소되어야 하는지를 정합니다. 사용자가 적은 값을 사용할수록, 더 높은 선명도를 가지게
Position Error
됩니다.
스케일 커브가 얼마나 감소되어야 하는지를 정합니다. 사용자가 적은 값을 사용할수록, 더 높은 선명도를
Scale Error
가지게 됩니다.
머티리얼 생성
Materials 은 다음 규칙에 따라 머티리얼을 찾아냅니다:
•
유니티는 장면(scene)안에 있는 오브젝트에 구속된 주 분산 머티리얼(main diffuse material)의 이름을 얻어옵니다.
•
유니티는 장면(scene) 옆에 Materials 이라 불리는 폴더 내에서 같은 이름을 가지고 있는 머티리얼을 검색 합니다.
•
유니티는 프로젝트 폴더에 가서 가는 길에 각 Materials folder 마다 해당 머티리얼이 있는지를 검색합니다.
만일 유니티가 해당 머티리얼을 찾지 못하면, 텍스처에서 직접 하나를 생성을 시도합니다:
•
Unity 유니티는 장면과 같은 폴더 내에서 정확한 이름을 가진 텍스처를 체크합니다.
•
유니티는 장면 옆에 Textures 라고 불리는 폴더 내에서 정확한 이름을 가진 텍스처를 체크합니다.
•
유니티는 프로젝트 폴더로 올라가며 가는 길에 각 Textures 폴더마다 정확한 텍스처를 검색합니다.
•
해당 텍스처를 찾으면, 그 옆에 Materials 폴더를 생성하고 그 안에 머티리얼을 생성합니다.
콜라이더(Colliders, 충돌자)
유니티에는 두 가지 성질의 주요 콜라이더가 있습니다: Mesh Colliders 와 Primitive Colliders 로, 메쉬 콜라이더는 들여온 메쉬
데이터를 사용하는 컴포넌트로 주변 환경의 충돌에 사용할 수 있습니다. 사용자가 들여오기 설정에서 Generate Colliders$$ 속성을
켜면, 메쉬 콜라이더는 해당 장면에 메쉬가 추가 될 때 메쉬 콜라이더는 자동으로 추가 되며, 물리 시스템 상으로는 단단한 성질로
간주 됩니다.
만일 사용자가 오브젝트를 움직인다면 (예를 들면 자동차 같은 경우), 메쉬 콜라이더는 움직일 수 없습니다. 그 대신 사용자는
프리미티브 콜라이더를 사용하여야 합니다. 이 경우, 사용자는 Generate Colliders 설정을 꺼야 합니다.
Animations
애니메이션은 장면으로부터 자동적으로 들여오기가 실행됩니다. 애니메이션 들여오기 옵션에 대한 더 자세한 정보를 보려면
Animation Import 장을 참조하세요.
일반 매핑과 문자
사용자가 하이 폴리곤(high-polygon) 버전의 모델에서 생성된 노멀 맵(normal map)의 문자를 가지고 있다면, 사용자는 Smoothing
angle 를 180 도로 하는 게임 품질 버전(game- quality version)을 들여쓰기 해야 합니다. 이렇게 하면 tangent splitting 로 인해
조명에서 경계(seam)가 이상하게 보이는 것을 방지할 수 있습니다. 해당 경계(seam)가 이렇게 해도 보인다면, Split tangents
across UV seams 을 켜야 합니다.
흑백 이미지를 노멀 맵으로 전환 중이라면, 이러한 문제는 관련이 없습니다.
Hints
•
사용자의 메쉬들은 가능한 많이 합치십시오. 메쉬끼리 머티리얼과 텍스처를 공유하게 하면, 엄청난 성능 혜택이 있을 것 입니다.
•
사용자가 유니티에서 사용자 오브젝트를 더 설정해야 한다면 (물리(physics) 추가, 스크립트 혹은 다른 coolness), 사용자의 3D
어플리케이션에서 의미 있는 이름을 사용하여 혼선을 피하십시오. 많은 수의 pCube17 혹은 Box42 같은 오브젝트로 작업을 하는
것은 상당히 힘들어질 수 있습니다.
•
사용자의 3D 응용 프로그램에서 사용자 메쉬가 월드 오리진 상의 중심에 위치하도록 하십시오. 이렇게 하면 유니티에서 손쉽게
이들을 배치할 수 있습니다.
유니티 편집기는 너무 많은 삼각형을 보여준다(사용자의 3D 응용 프로그램 보다)
옳은 말 입니다. 사용자가 보는 것은 실제로 랜더링을 위해 OpenGLES 로 보내지는 삼각형의 수입니다. 머티리얼이 그것을 두 번
보내야 하는 경우 등 뿐만 아니라 하드-노멀이나 비인접 UV 증가(non contiguous UV increase) 꼭지점/삼각형(vertex/trangle)도 모델
응용프로그램이나 유니티가 사용자에게 이야기하는 것보다 훨씬 상당합니다. 삼각형(Triangles)은 3D 와 UV 공간 모두
스트립(strip)을 형성하려면 인접성이 있어야 합니다. 그러므로 사용자가 UV 경계를 가진다면, 퇴보 삼각형(degenerate triangle)이
스트립으로부터 만들어져야 합니다 – 이것 또한 숫자를 증가시킵니다. 이전에는 유니티가 삼각형의 수를 부정확하게
보고했었습니다. 이 숫자는 실행 시 첫째로 정정되고, 편집기에도 최근에 정정되었습니다. 이제 둘 다 랜더링을 위하여
OpenGLES 로 *실제로* 보낸 삼각형의 숫자를 정확하게 보고합니다.
추가 참조
•
Modeling Optimized Characters
•
Normal maps 어떻게 사용하나요?
•
들여온 모델의 회전을 어떻게 고치나요?
애니메이션들
유니티 애니메이션 시스템은 사용자에게 멋지게 애니메이트된 스키닝 된 캐릭터를 만드는 것을 가능하게 합니다. 애니메이션
시스템은 애니메이션 블렌딩(blending), 믹싱(mixing), 가산(additive) 애니메이션, 걷기 싸이클 시간 동기화(walk cycle time
synchronization), 애니메이션 레이어, 애니메이션 플레이백의 모든 면에 대한 제어 (시간, 속도, 블렌드웨이트(blend-weights)),
버텍스 당 1, 2, 혹은 4 개 본(bone)의 메쉬 스키닝, 그리고 마지막으로 물리적 기반의 랙돌(ragdoll)을 지원합니다.
유니티에서 최적의 성능으로 리깅된 캐릭터를 만들기 위한 가장 좋은 방법들이 있습니다. Modeling Optimized Characters 에 있는
테크닉에 대해 읽기를 권합니다.
원한다면 이 페이지에서 다루는 다음의 내용들로 빠른 이동을 할 수 있습니다:
•
캐릭터 애니메이션 불러오기
o
애니메이션 나누기
o
복수 파일들
o
역운동학(Inverse Kinematics)
•
유니티 씬에 집어넣기
캐릭터 애니메이션 불러오기
처음에 할 것은 캐릭터를 불러오는 것입니다. 유니티는 자연적으로 Maya 파일(.mb 또는 .ma), Cinema 4D 파일(.c4d) 그리고
대부분의 애니메이션 패키지에서 내보내기 할 수 있는 fbx 파일을 불러옵니다.
애니메이션 나누기를 이용한 애니매이션 불러오기
애니메이터가 가장 쉽게 작업하게 만드는 방법은 모든 애니메이션을 포함하는 한 개의 모델을 갖추는 것입니다. 애니메이션 모델을
불러올때 어떤 프레임이 애니매이션의 각 부분을 만드는지 정의할 수 있습니다. 유니티는 자동으로 애니메이션을 여러 부분으로
나누고 그것을 애니메이션 클립(Animation Clips)이라 부릅니다.
For example:
•
걷는 애니메이션. 프레임 1 - 33
•
뛰는 애니메이션. 프레임 41 - 57
•
차는 애니메이션. 프레임 81 - 97
애니메이션을 불러오기 위해서는 모델을 프로젝트의 에셋(Assets) 폴더에 위치시킵니다. 유니티는 자동으로 그것을 불러옵니다.
프로젝트 뷰(Project View)에서 그것을 하이라이트하고 불러오기 설정(Import Settings) 에서 인스펙터(Inspector)를 수정합니다.
메쉬를 위한 불러오기 설정 대화창
불러오기 설정(Import Settings) 에서, 애니메이션 나누기(Split Animations)테이블은 사용자가 유니티에게 사용자 에셋 파일의
어떤 프레임이 어떤 애니메이션 클립을 만드는지 말해 줍니다. 여기서 지정하는 이름은 게임에서 그들을 활성화 시키는데
사용됩니다.
Property:
Function:
Name
유니티 안에서 애니메이션 클립의 이름을 정의합니다.
start
애니메이션의 첫번째 프레임. 이 프레임 숫자는 해당 애니메이션을 만드는데 사용되었던 3D 프로그램의 프레임과
frame
같습니다.
stop frame 애니메이션의 마지막 프레임.
WrapMode
어떻게 클립의 플레이백 범위를 벗어난 시간을 다룰것인가를 정의함 (Once, Loop, PingPong, ClampForever).
이것이 활성화 되면 추가적인 룹 프레임(Loop frame)이 애니메이션 끝에 추가됩니다. 이 프레임은 클립의 첫 프레임과
loop frame
동일합니다. 반복되는 애니메이션을 원할때 처음과 끝 프레임이 일치하지 않을때 사용합니다.
복수개의 모델 파일을 이용하여 애니메이션 불러오기
애니메이션을 불러오는 다른 방법은 @ 애니메이션 이름 체계를 따르는 것입니다. 별개의 모델 파일을 만들고 다음과 같은 방식으로
이름을 짓습니다: $$모델이름@애니메이션이름.fbx&&
하나의 애니메이션 캐릭터를 위한 네 개의 애니메이션 파일의 예
유니티는 자동으로 모든 네개의 파일을 불러오고 모든 애니메이션을 @ 싸인 인(sign in) 없이 그 파일에 모읍니다. 위 예제에서
goober.mb 파일은 자동적으로 정지, 점프, 걷기 그리고 벽점프를 참조하도록 설정되게 됩니다.
역운동학 (Inverse Kinematics) 불러오기
IK 를 이용해 만든 마야 애니메이션 캐릭터를 불러올 때는 불러오기 설정(Import Settings)에 있는 Bake IK & simulation 박스를
체크해야 합니다. 그렇지 않으면 사용자 캐릭터는 정확한 애니메이션을 보여 주지 않을 것입니다.
캐릭터를 씬으로 불러오기
사용자 모델을 불러올때는 객체를 프로젝트 뷰에서 씬뷰(Scene View) 또는 계층뷰(Hierarchy)로 드래그 합니다.
씬으로 드래그된 애니메이션 캐릭터
위의 캐릭터는 애니메이션 리스트에 세 개의 애니메이션을 가지고 있고 기본(default) 애니메이션은 가지고 있지 않습니다. 사용자는
애니메이션 클립을 프로젝트 뷰에서 (씬뷰나 계층뷰의) 캐릭터로 드래그 해서 캐릭터에 더 많은 애니메이션을 추가할 수 있습니다.
이것은 또한 기본(default) 애니메이션을 정하게 됩니다. 플레이(Play) 버튼을 누르면 기본 애니메이션이 재생 될 것입니다.
팁: 사용자는 이것을 애니메이션이 바르게 재생되는지 빠르게 테스트 하기 위하여 사용할 수 있습니다. 또한 랩모드(Wrap Mode)를
사용해 반복(Looping)같은 애니메이션의 다른 행동들을 보세요.
재질들과 셰이더들(Materials and Shaders)
유니티 에서는 재질(Materials)과 셰이더(Shaders)가 긴밀한 관계에 있습니다. 셰이더들은 어떤 속성과 어떤 애셋(asset)들을
사용할지 정의하는 코드를 포함합니다. 재질은 사용자가 속성들을 조절(adjust)하고 에셋 지정(assign)하는 것을 가능하게 합니다.
재질을 통해 구현된 셰이더
새로운 재질을 만들기 위해서는, 메인 메뉴의 Assets->Create->Material 을 사용하거나 프로젝트 뷰(Project View)의
컨텍스트(context) 메뉴를 사용하시면 됩니다. 재질이 일단 생성되면, 오브젝트에 적용할 수 있고, 인스펙터(Inspector) 내에서
속성들을 변경하실 수 있습니다. 그것을 오브젝트에 적용시키려면 프로젝트 뷰에서 그것을 드래그하여 씬(Scene)이나
계층(Hierarchy)의 아무 오브젝트로에게나 드래그하시면 됩니다.
재질 속성들 설정 (Setting material properties)
원하는 셰이더와 사용할 특정 재질을 선택 할 수 있습니다. 인스펙터의 셰이더(Shader) 드롭다운을 펼치세요. 그리고 새로운
셰이더를 선택합니다. 선택된 셰이더는 변경 가능한 속성들을 요구할 것입니다. 속성들은 색상, 슬라이더들, 질감들, 숫자들,
벡터들입니다. 만약, 씬(Scene)에서 재질을 활성화된 오브젝트로 적용하면, 실시간으로 속성의 변화가 오브젝트에 적용되는 것을 볼
수 있습니다.
텍스쳐(Texture)를 어느 속성(property)에 적용하는 것에는 두 가지 방법이 있습니다.
1.
텍스쳐를 프로젝트 뷰로부터 끌어서 텍스쳐 사각형(Texture square)의 위에 논다.
2.
셀렉트(Select) 버튼 클릭 후 보이는 드롭다운 리스트로부터 재질 선택
각 텍스쳐(Texture)에는 두 개의 위치(placement) 옵션이 존재합니다:
Property:
Function:
Tiling
차이에 따라 텍스쳐를 스케일.
Offset
텍스쳐를 옆이나 위로 이동.
내장 셰이더들(Built-in Shaders)
유니티의 모든 설치에 표준으로 따라오는 built-in Shaders 라이브러리가 있습니다. 30 개 이상의 built-in Shaders 가 있으며, 6 개의
기본적 타입(family)들이 있습니다.
•
표준 Normal: 불투명한 질감의 오브젝트를 위함.
•
투명 Transparent: 어느 정도 투명한 오브젝트들을 위함. 텍스쳐의 알파 채널이 투명도의 레벨을 정의합니다.
•
TransparentCutOut: 완전히 불투명하고 완전히 투명한 지역을 함께 갖는 오브젝트들을 위함(예: 펜스).
•
자체발광 Self-Illuminated: 빛을 방출하는부분이 있는 오브젝트들을 위함.
•
반사 Reflective: 환경(environment) 큐브맵(Cubemap)을 반사하는 불투명한 텍스쳐 오브젝트들을 위함.
각각의 그룹에서 내장 셰이더들은 복잡도에 의해서 간단한 버텍스릿(VertexLit)으로부터, 복잡한 패럴랙스 범프드 위드
스페큘러(Parallax Bumped with Specular)에 이릅니다. 셰이더들의 성능에 관한 더 많은 정보는, 내장 셰이더 성능 페이지
performance page 를 참조하세요.
이 그리드는 내장셰이더의 썸네일을 표시합니다:
내장 유니티 셰이더 매트릭스
셰이더 기술적 세부사항(Shader technical details)
유니티는 광범위한 셰이더 시스템을 가지고 있어서, 모든 게임 내부의 그래픽들의 외관적인 모습을 변경할 수 있게 합니다. 이것은
다음과 같이 작동합니다:
셰이더는 기본적으로 게임 내부 셰이딩이 어떻게 보일지를 식(formula)을 통하여 정의합니다. 주어진 셰이더 안에는 속성들(특히
텍스쳐들)이 있습니다. 셰이더들은 재질(Materials)을 통하여 구현되며, 각각의 게임오브젝트에 직접 부착됩니다. 재질들 안에서
셰이더를 선택하고, 셰이더에 쓰일 속성들(일반적으로는 텍스쳐와 색상, 그러나 속성들은 다양할 수 있음)을 정의합니다.
이는 매우 복잡하므로, 작업 순서도의 도면을 살펴봅시다:
그래프의 왼편에는 차바디 셰이더(Carbody Shader)가 있습니다. 이로부터 두 개의 다른 재질들이 생성됩니다. Blue car
Material 과 Red car Material 입니다. 이들 재질들 각각에게는 두 개의 텍스쳐가 할당됩니다. 차 텍스쳐(Car Texture)는 그 차의
메인 텍스쳐와 색상 FX 텍스쳐(Color FX texture)를 정의합니다. 이들 속성들은 차가 투톤(2-tone) 으로 페인트 칠해진 것으로
보이게 하기 위해 셰이더에 의해 사용되어집니다. 이는 빨강 차의 앞에서 볼 수 있습니다. 그것은 카메라 정면에서 보이는 노란색
부분이고 각이 증가할수록 보라빛으로 변하면서 바래집니다. 차의 텍스쳐들은 2 개의 차들에 부착됩니다. 차의 바퀴, 조명, 그리고
창문은 색상 변화 효과를 보여주지 않기 때문에 다른 재질을 사용해야 합니다. 그래프의 아래 부분에는 간단한 메탈 셰이더(Simple
Metal Shader)가 있습니다. 바퀴 재질(Wheel Material)에는 이 셰이더를 사용합니다. 비록 같은 차 텍스쳐(Car Texture)가
재사용 되었지만, 재질에서 사용된 셰이더가 다르기 때문에 최종 결과는 아까 차량의 본체(car body)와는 사뭇 다릅니다.
더 정확히 파고들자면 셰이더(Shader)는 다음을 정의합니다:
•
오브젝트를 렌더하는 방법. 사용자의 그래픽 카드에 의존하는 다른 방법을 사용하는 것을 포함합니다.
•
렌더를 위해 사용된 버텍스(vertex)와 프래그먼트(fragment) 프로그램들.
•
재질들 안의 할당 가능한 몇몇 텍스쳐 속성들.
•
재질들 안의 할당 가능한 색상과 숫자 설정들.
재질(Material)은 다음을 정의합니다:
•
렌더링을 위해서 어떤 질감을 사용할 것인가를 정의.
•
렌더링을 위해서 어떤 색상을 사용할 것인가를 정의.
•
렌더링을 위해 셰이더에 의해 요구된 큐브맵(cubemap) 같은 다른 에셋들
셰이더들은 그래픽 프로그래머들에 의해 쓰여지도록 의도 되었습니다. 셰이더들은 굉장히 간단한 쎼이더랩(ShaderLab) 언어를
사용하여 생성되었습니다. 그러나 다양한 그래픽 카드에서 잘 동작하는 셰이더를 얻는 것은 전문적인 일이고, 그래픽 카드가 어떤
식으로 동작하는지를 알아야 하는 등의 지식을 요구합니다.
몇몇 셰이더 들은 유니티에 내장되어있고 더 많은 것이 Standard Assets 라이브러리에도 있습니다. 원하신다면 Built-in Shader
Guide 페이지에서 더 많은 정보를 보실 수 있습니다.
텍스쳐(Texture) 2D
텍스쳐(Textures)는 사용자의 메쉬(Meshes), 파티클(Particles) 그리고 인터페이스에게 생명을 가져다줍니다. 그것은 사용자 객체
위에 덮거나 둘러 싸는 이미지나 동영상 파일 입니다. 이것은 아주 중요하기 때문에 많은 속성을 가지고 있습니다. 이 글을 처음 보는
것이면 Details 로 먼저 가시고 참조가 필요할 때 실제 설정으로 돌아오시기 바랍니다.
사용자가 객체를 위해 사용하는 쉐이더는 어떤 텍스쳐를 쓰는지를 정밀하게 요구하는데 기본적으로 사용자 프로젝트에 아무 아미지
파일이나 넣을 수 있습니다. 만약 그것이 크기 요구조건과 맞으면(아래 기술됨) 불려오기 된 후 게임에 맞도록 최적화 될 것입니다.
이것은 다중레이어 포토샾이나 TIFF 파일도 포함됩니다. 이들은 불려올때 플래튼(flatten) 되어지므로 사용자의 게임에서 파일
크기로 인한 문제는 없습니다.
Properties
텍스쳐 인스펙터(Texture Inspector)는 대부분의 것들과는 조금 다릅니다:
맨 위 섹션은 몇가지 설정을 포함하며 맨 아랫 부분은 텍스쳐 임포터(Texture Importer)와 텍스쳐 미리보기(Texture Preview)가 포함
됩니다.
Property:
Function:
Aniso
텍스쳐를 가파른 각도로 볼 때 텍스쳐의 퀄리티를 높입니다. 마루층(floor)이나 지면(ground) 텍스쳐에 좋습니다.
Level
아래를 보세요.
Filter
텍스쳐가 3D 변환(transformations)에 의해 늘려졌을 때 텍스쳐가 어떻게 필터되는지를 선택:
Mode
Point
텍스쳐가 가까이에서 뭉툭(blocky)하게 됩니다
Bilinear
텍스쳐가 가까이에서 흐려(blurry)지게 됩니다
Trilinear
Bilinear 같지만 텍스쳐가 다른 밉(mip) 레벨들 사이에서 블러(blur)해집니다
Wrap Mode
텍스쳐가 타일(tile)화 되었을 때 어떻게 행동하는지 선택합니다:
Repeat
텍스쳐가 타일화되어 반복됩니다
Clamp
텍스쳐의 가장자리(edge)가 늘려집니다(stretched)
텍스쳐 임포터(Texture Importer)
텍스쳐는 사용자 프로젝트 폴더(Project Folder)의 이미지 파일에서 옵니다. 그것이 어떻게 불려오는지는 텍스쳐 임포터(Texture
Importer)에 의해 명시됩니다. 사용자는 프로젝트 뷰(Project View)에서 파일 텍스쳐를 선택하고 인스펙터(Inspector)에서 텍스쳐
임포터(Texture Importer)를 수정함으로써 이것을 바꿀수 있습니다.
유니티 3D 에서는 사용자를 위해 모든 설정을 간략화했습니다. 사용자는 이제 텍스쳐를 어디에 사용할 지와 선택하고 유니티가
사용자가 선택한 타입의 텍스쳐를 위한 기본 파라미터(default parameter)를 설정합니다. 물론 사용자가 텍스쳐의 완전한 제어를
원하고 특정한 수정을 가하길 원하면 텍스쳐 타입(Texture Type)을 고급(Advanced)으로 설정합니다. 이것은 사용자에게 가능한
모든 가능한 옵션을 보여줍니다.
Property:
Texture
Function:
텍스쳐의 목적에 따라 기본적인 파라미터(basic parameters)를 설정하기 위해 선택합니다.
Type
Texture
모든 텍스쳐에 일반적으로 사용되는 가장 공통된 설정.
이것은 색상 채널(color channels)을 포맷에 맞는 실시간 노멀맵핑(real-time normal mapping)으로 전환할 때
Normal Map
GUI
선택하세요. 좀 더 많은 정보는 Normal Maps 를 보세요.
이것은 사용자 텍스쳐가 어떤 HUD/GUI 제어에 사용될 때 이용하세요.
큐브맵(Cube map)이라고도 알려져 있으며 텍스쳐에 반사(reflection)를 나타내기 위해 사용됩니다. 좀 더 많은 정보는
Reflection
Cookie
Cubemap Textures 를 확인하세요.
이것은 사용자의 빛(lights)의 쿠키(Cookies)를 위해 사용되는 기본적인 파라미터로 텍스쳐를 설정합니다.
Advanced
이것은 사용자가 텍스쳐에 어떤 특정 파라미터를 포함시키길 원하고 텍스쳐의 완전한 제어를 원할 때 선택하세요.
기본적인 텍스쳐 설정 선택됨
Generate Alpha From
활성화 시, 알파 투명 채널(alpha transparency channel)은 이미지의 기존의 밝고 어두운 명암값에
의해 생성 됩니다.
Grayscale
텍스쳐 임포터(Importer)의 노멀맵(Normal Map) 설정
Generate from Greyscale
Bumpiness
울퉁불퉁함(bumpiness)의 정도를 제어.
Filtering
울퉁불퉁함(bumpiness)이 계산되는 방법을 결정:
Smooth
굉장히 부드러운 노멀 맵 생성.
Sharp
Sobel 필터로도 알려져 있으며 이것은 보통보다 날카로운(sharp) 노멀맵을 생성합니다.
텍스쳐 임포터(Importer)를 위한 GUI 설정
이 경우 사용자는 아무 값도 설정할 필요가 없습니다. 유니티가 모든 값을 설정합니다.
텍스쳐 임포터(Importer)의 반사(Reflection) 설정
Mapping
Sphere Mapped
Cylindrical
Simple Sphere
Nice Sphere
이것은 어떻게 텍스쳐가 큐브맵에 맵핑되는지 결정합니다.
텍스쳐를 "구모양(sphere like)같은" 큐브맵에 맵핑합니다.
텍스쳐를 실린더에 맵핑합니다. 실린더 모양의 객체에 반사를 사용하고 싶을 때 사용합니다.
텍스쳐를 회전시 반사를 변형하는 간단한 구(sphere)에 맵핑합니다.
텍스쳐를 구(sphere)에 매핑합니다. 회전시 변형이 되지만 여전히 텍스쳐가 감싸진 것을 보실 수 있습니다.
사용자 씬에 더 많은 시각적인 디테일을 더하는 흥미로운 방법으로는 게임안의 빛의 정확함을 제어하기 위한회색톤(greyscale)
텍스쳐인 쿠키(Cookies)를 사용하는 것입니다. 이것은 움직이는 구름을 만들고 짙은 안개의 인상을 줄 때 아주 편리합니다. 이 모든
것의 좀더 자세한 사항은 Light 를 보세요. 그러나 여기의 핵심은 쿠키를 위해 사용될 수 있는 텍스쳐를 위해서 사용자는 텍스쳐
타입(Texture Type)을 단지 쿠키(Cookie)로만 설정하면 됩니다.
텍스쳐 임포터(Importer)의 쿠키 설정
텍스쳐가 적용될 빛의 종류(이것은 스팟라이트(spot light), 포인트라이트(point light) 또는
디렉셔널라이트(directional light)가 될 수 있습니다). 디렉셔널 라이트를 위해서는 이 텍스쳐는 타일화 될 것입니다.
그를 위해서 텍스쳐 인스펙터에서 사용자는 가장자리 모드(Edge Mode)를 반복(Repeat)으로 설정합니다.
Light Type
스팟라이트를 위해서 사용자는 적절한 효과를 얻기 위해 쿠키 텍스쳐의 가장자리(edges)를 완전히 검정 단색으로
유지합니다. 텍스쳐 인스펙터에서는 가장자리(edge) 모드를 클램프(Clamp)로 설정합니다.
Generate
Alpha from
활성화 되면, 알파 투명 채널 (alpha transparency channel)은 이미지의 기존의 밝고 어두운 명암값에 의해 생성
됩니다.
Greyscale
고급 텍스쳐 임포터 (Advanced Texture Importer) 설정 대화창
Non Power of
2
None
만약 텍스쳐 이미지 크기가 2 의 제곱수의 크기를 가지지 않으면 이것은 불러오기를 할때 크기변환 행동(Scaling
behavior)을 정의할 것입니다.(더 자세한 사항은 아래 Texture Sizes 섹션을 보세요):
텍스쳐가 GUITexture 컴포넌트 사용을 위해 두번째로 제일 큰 2 의 제곱수 크기에 맞게 패딩됩니다.
텍스쳐가 불려올 때 가장 가까운 2 의 제곱수 크기에 맞춰집니다. 예를 들어 257x511 크기의 텍스쳐는 256x512 가 될
To nearest
것입니다. PVRTC 형식은 정사각형 텍스쳐를 요구하므로 최종 크기가 512x512 로 맞춰집니다.
텍스쳐가 불려올 때 다음으로 큰 2 의 제곱수의 크기에 맞춰집니다. 예를 들어 257x511 텍스쳐는 512x512 가 될 것
To larger
입니다.
텍스쳐가 불려올 때 다음으로 작은 2 의 제곱수에 크기가 맞춰집니다. 예를 들어 257x511 텍스쳐는 256x256 가
To smaller
Generate
될것입니다.
다른 생성 방법을 이용해 텍스쳐에서 큐브맵을 생성합니다.
Cube Map
스크립트(GetPixels, SetPixels 그리고 다른 Texture2D (script ref 참조) 함수들)들로부터 텍스쳐 데이터에 대한
Read/Write
Enabled
접근을 가능케하기 위해 선택합니다. 그러나 텍스쳐 데이터의 카피가 생성되며 텍스쳐 에셋을 위해 두배의 메모리가
필요함에 주의하세요. 꼭 필요한 경우에만 사용하세요. 이것은 비압축(uncompressed)과 DTX 압축 텍스쳐에서만
유효합니다, 다른 타입의 압축 텍스쳐는 읽히지 않습니다. 기본으로 비활성화 되어 있습니다.
Generate Mip
Maps
Correct
밉맵 (mip-map) 생성을 활성화하기 위해 선택하세요. Mip map 들은 텍스쳐가 화면에서 아주 작은 부분일 때
사용되는 더 작은 버전의 텍스쳐 입니다. 자세한 사항은 Mip Maps 를 보세요.
밉-레벨 당 감마 코렉션(per-mip-level gamma correction)을 활성화 할 때 선택하세요.
Gamma
Border Mip
색이 낮은 밉 (Mip) 레벨들의 가장자리에서 새어나오는 것을 피할때 설정합니다. (아래를 참조하세요.)
Maps
Mip Map
이미지 퀄리티를 최적화 하기위한 밉맵 필터링의 두가지 방법이 있습니다:
Filtering
Mipmap 들을 서서히 사라져 가게(fade out) 하기 위한 가장 쉬운 방법입니다. 밉 레벨이 크기가 작아 질수록 점점 더
Box
부드러워집니다.
날카로운 Kaiser algorithm 이 크기가 점점 작아지는 mip 맵에서 실행됩니다. 사용자 텍스쳐가 멀리서 너무 흐릿하면
Kaiser
이 옵션을 택하세요.
밉 레벨들이 진행되면서 밉맵들이 회색으로 변하게 하기 위해 이것을 활성화 시킵니다. 이것은 디테일 맵(detail map)
Fade Out
Mips
Generate
으로 사용됩니다. 가장 왼쪽의 스크롤은 사라져 갈 첫 밉 레벨입니다. 가장 오른쪽의 스크롤은 텍스쳐가 완전히
회색으로 되었을 때의 밉 레벨을 정의합니다.
색상 채널을 실시간 노멀맵핑(Normal Mapping)에 적합한 형식으로 바꾸는 것을 활성화합니다. 더 많은 정보를
Normal Map
위해서 Normal Maps 를 보세요.
Bumpiness
울퉁불퉁함(bumpiness)의 정도를 제어.
Filtering
울퉁불퉁함(bumpiness)이 계산되는 방법을 결정:
Smooth
꽤 부드러운 노멀맵을 생성.
Sharp
Sobel 필터로도 알려져 있으며 이것은 표준보다 날카로운 노멀맵을 생성합니다.
Normal Map
노멀맵이 어떻게 텍스쳐에 적용될 지 보고 싶다면 선택하세요.
텍스쳐를 라이트맵(Lightmap)으로 사용하고 싶다면 선택하세요.
Lightmap
플랫폼별 오버라이드(Per-Platform Overrides)
다른 플랫폼에서 빌드할 때 타겟 플랫폼의 텍스쳐 해상도, 크기, 그리고 퀄리티에서의 텍스쳐를 생각해야 합니다. 유니티 3 에서는 이
옵션들을 오버라이드 할 수 있으며 사용자가 배포하는 플랫폼에따라 특정 값을 할당할 수 있습니다. 사용자가 오버라이드를 위한
값을 선택하지 않으면 프로젝트가 빌드될때 에디터가 기본 값을 적용합니다.
모든 플랫폼들을 위한 기본 세팅
Max Texture
Size
Texture
Format
불려올 최대 텍스쳐 크기. 그래픽 작업자는 보통 아주 큰 텍스쳐로 작업하는 것을 선호합니다. 이 옵션으로
텍스쳐를 적당한 크기로 맞추세요.
텍스쳐에 어떤 내부 표현이 사용되었는가. 이것은 크기와 퀄리티간의 절충(trade-off)이 필요합니다. 아래 예에서는
게임 내 텍스쳐의 최종 크기(256x256 픽셀)를 보여줍니다.
압축된 RGB 텍스쳐. 이것은 디퓨즈(diffuse) 텍스쳐의 가장 흔한 형식입니다. 픽셀 당 4bits (256x256 텍스쳐에
Compressed
32KB).
낮은 퀄리티의 트루컬러(True color). 빨강, 녹색, 파랑(Red, Green, Blue) 그리고 알파(alpha)의 16 가지 레벨이
16 bit
Truecolor
있습니다.
최상의 퀄리티인 트루컬러. 256x256 텍스쳐에 256 KB.
만약 사용자가 텍스쳐 타입(Texture Type)을 고급(Advanced)으로 하면 텍스쳐 포맷(Texture Format)은 다른 값을 가집니다.
Desktop
Texture
텍스쳐에 어떤 내부 표현이 사용되었는가. 이것은 크기와 퀄리티간의 절충(trade-off)이 필요합니다. 아래 예에서는
Format
게임 내 텍스쳐의 최종 크기(256x256 픽셀)를 보여줍니다.
RGB
압축된 RGB 텍스쳐. 이것은 디퓨즈(diffuse) 텍스쳐의 가장 흔한 형식입니다. 픽셀 당 4bits (256x256 텍스쳐에
Compressed
32KB).
DXT1
RGBA
압축된 RGBA 텍스쳐. 이것은 디퓨즈(diffuse) & 스페큘러(specular) 제어 텍스쳐의 가장 주요 형식입니다. 1
Compressed
byte/pixel (256x256 텍스쳐에서 64KB).
DXT5
알파(alpha) 없는 65,000 가지 색상. 압축 DXT 포맷은 더 적은 메모리를 사용하면서도 보통 더 좋아보입니다.
RGB 16 bit
256x256 텍스쳐에 128KB.
RGB 24 bit
알파 없는 트루 컬러. 256x256 텍스쳐에서 192KB.
Alpha 8 bit
색상 없는 높은 퀄리티의 알파 채널. 256x256 텍스쳐에서 64KB.
낮은 퀄리티의 트루컬러. 16 가지 레벨의 빨강(R), 초록(G), 파랑(B) 그리고 알파. 압축된 DXT5 형식은 적은
RGBA 16 bit
메모리를 사용하면서도 보통 더 좋아보입니다. 256x256 텍스쳐에서 128KB.
알파 있는 트루 컬러 – 이것은 가장 높은 퀄리티를 가집니다. 256x256 텍스쳐에서 256KB 를 가지며 이것은 아주 큰
용량을 가집니다. 대부분 DXT5 는 훨씬 작은 크기에서도 충분한 퀄리티를 제공합니다. 보통 노멀맵쪽에서의
RGBA 32 bit
DXT 압축은 상당한 퀄리티의 손실을 수반하기 때문에 이것이 주로 사용되는 곳은 노멀맵(Normal Map)에서 입니다.
iOS
텍스쳐에 어떤 내부 표현이 사용되었는가. 이것은 크기와 퀄리티간의 절충(trade-off)이 필요합니다. 아래
Texture Format
RGB Compressed
예에서는 게임 내 텍스쳐의 최종 크기(256x256 픽셀)를 보여줍니다.
압축된 RGB 텍스쳐. 이것은 디퓨즈(diffuse) 텍스쳐의 가장 흔한 형식입니다. 픽셀 당 4bits (256x256
텍스쳐에 32KB).
PVRTC 4 bits
RGBA Compressed
PVRTC 4 bits
RGB Compressed
PVRTC 2 bits
RGBA Compressed
압축된 RGBA 텍스쳐. 이것은 디퓨즈(diffuse) & 스페큘러(specular) 제어 텍스쳐의 가장 주요 형식입니다.
픽셀당 1 바이트(1 byte/pixel) (256x256 텍스쳐에서 32KB).
압축된 RGB 텍스쳐. 디퓨즈(diffuse) 텍스쳐에 가장 적합한 낮은 퀄리티의 포맷. 픽셀당 2 비트 (256x256
텍스쳐에서 16KB).
압축된 RGBA 텍스쳐. 디퓨즈(diffuse) & 스페큘러(specular) 제어 텍스쳐에 가장 적합한 낮은 퀄리티의 포맷.
픽셀당 2 비트 (256x256 텍스쳐에서 16KB)
PVRTC 2 bits
RGB Compressed
DXT1
RGBA Compressed
DXT5
압축된 RGB 텍스쳐. 이 형식은 iOS 에서 지원되지 않지만 데스크탑 프로젝트의 호환성을 위해 가지고
있습니다.
압축된 RGBA 텍스쳐. 이 형식은 iOS 에서 지원되지 않지만 데스크탑 프로젝트의 호환성을 위해 가지고
있습니다.
알파(alpha) 없는 65,000 가지 색상. RVRTC 형식보다 메모리를 더 사용하지만 UI 또는
RGB 16 bit
그레이디언트(gradient)없는 날카로운(crisp) 텍스쳐에 더욱 적합합니다. 256x256 텍스쳐에서 128KB.
RGB 24 bit
알파 없는 트루컬러. 256x256 텍스쳐에서 192KB.
Alpha 8 bit
높은 퀄리티의 알파 채널. 256x256 텍스쳐에서 64KB.
RGBA 16 bit
낮은 퀄리티의 트루컬러. 16 레벨의 빨강(R), 초록(G), 파랑(B) 그리고 알파(alpha). RVRTC 형식보다
메모리를 더 사용하지만 사용자가 정확한 알파 채널을 원할때 편리합니다. 256x256 텍스쳐에서 128KB.
알파 있는 트루컬러 – 이것은 가장 높은 퀄리티를 가집니다. 256x256 텍스쳐에서 256KB 를 가지며 이것은
RGBA 32 bit
아주 비쌉니다. 대부분 PVRTC 는 훨씬 작은 크기에서도 충분한 퀄리티를 제공합니다.
Android
텍스쳐에 어떤 내부 표현이 사용되었는가. 이것은 크기와 퀄리티간의 절충(trade-off)이 필요합니다. 아래
Texture Format
예에서는 게임 내 텍스쳐의 최종 크기(256x256 픽셀)를 보여줍니다.
압축된 RGB 텍스쳐. 엔비디아 (Nvidia) Tegra 에 의해 지원됩니다. 픽셀당 4 bits (256x256 텍스쳐에서
RGB Compressed DXT1
32KB).
압축된 RGBA 텍스쳐. 엔비디아 (Nvidia) Tegra 에 의해 지원됩니다. 픽셀당 6 bits (256x256 텍스쳐에서
RGBA Compressed DXT5
64KB).
RGB Compressed ETC 4
압축된 RGB 텍스쳐. 이것은 디퓨즈(diffuse) 텍스쳐의 가장 흔한 포맷입니다. 픽셀당 4bits (256x256
텍스쳐에서 32KB).
bits
RGB Compressed PVRTC
압축된 RGB 텍스쳐. 이매지네이션 (Imagination) PowerVR GPUs 에 의해 지원됩니다. 픽셀당 2bits
(256x256 텍스쳐에서 16KB)
2 bits
RGBA Compressed
압축된 RGBA 텍스쳐. 이매지네이션 (Imagination) PowerVR GPUs 에 의해 지원됩니다. 픽셀당 2bits
(256x256 텍스쳐에서 16KB)
PVRTC 2 bits
RGB Compressed PVRTC
압축된 RGB 텍스쳐. 이매지네이션 (Imagination) PowerVR GPUs 에 의해 지원됩니다. 픽셀당 4bits
(256x256 텍스쳐에서 32KB)
4 bits
RGBA Compressed
압축된 RGBA 텍스쳐. 이매지네이션 (Imagination) PowerVR GPUs 에 의해 지원됩니다. 픽셀당 4bits
(256x256 텍스쳐에서 32KB)
PVRTC 4 bits
RGB Compressed ATC 4 압축된 RGB 텍스쳐. 콸콤(Qualcomm) Snapdragon 에 의해 지원됩니다. 픽셀당 4bits (256x256 텍스쳐에서
bits
RGBA Compressed ATC
8 bits
32KB).
압축된 RGBA 텍스쳐. 콸콤(Qualcomm) Snapdragon 에 의해 지원됩니다. 픽셀당 6bits (256x256
텍스쳐에서 64KB).
알파 없는 65,000 가지 색상. RVRTC 형식보다 메모리를 더 사용하지만 UI 또는 gradient 없는 주름진
RGB 16 bit
텍스쳐에 더욱 적합합니다. 256x256 텍스쳐에서는 128KB.
RGB 24 bit
알파 없는 트루컬러. 256x256 텍스쳐에서 192KB.
Alpha 8 bit
높은 퀄리티의 알파 채널. 256x256 텍스쳐에서 64KB.
RGBA 16 bit
낮은 퀄리티의 트루컬러. 알파 채널이 있는 텍스쳐에서의 기본 압축. 256x256 텍스쳐에서 128KB.
RGBA 32 bit
알파 있는 트루컬러 - 알파 있는 텍스쳐를 위한 가장 높은 퀄리티의 압축. 256x256 텍스쳐에서 256KB.
사용자가 Tegra 같은 어떤 특정 하드웨어를 목표로 하지 않는다면 저희는 ETC1 압축 사용을 권장합니다. 필요할 경우 외부(external)
알파 채널을 저장할 수 있으면서도 낮은 텍스쳐 종류의 이득을 받을 수 있습니다. 만약 사용자가 반드시 텍스쳐에 알파 채널을
저장하길 원하면 모든 하드웨어 공급 업체에서 지원하는 압축인 RGBA16 bit 을 사용하세요.
사용자 앱이 지원되지 않는 텍스쳐 압축(compression)을 사용하면 그 텍스쳐는 RGBA32 로 무압축(uncompressed)되며 압축된
것들과 함께 메모리에 저장이 됩니다. 그래서 이 경우 텍스쳐의 압축을 푸는데 시간을 잃게되며 두번의 저장으로 인해 메모리 손실을
봅니다. 이것은 또한 렌더링 성능에도 아주 부정적인 영향을 줄 수 있습니다.
상세 설명 (Details)
지원 포맷 (Supported Formats)
유니티는 다음의 파일 형식을 읽을 수 있습니다: PSD, TIFF, JPG, TGA, PNG, GIF, BMP, IFF, PICT. 유니티는 멀티 레이어의 PSD &
TIFF 파일도 불러올 수 있습니다. 이들은 불러오기 될때 자동으로 합쳐(flatten)지지만 레이어는 에셋에서 그대로 유지되므로 이 파일
타입 자체를 그대로 사용할 때 사용자는 아무런 작업도 잃지 않습니다. 이것은 사용자가 포토샾에서 사용하는 텍스쳐 하나를 3D
모델링 프로그램 또는 유니티에서도 쓸 수 있게 하기 때문에 중요합니다.
텍스쳐 크기 (Texture Sizes)
이상적으로 텍스쳐의 크기는 측면이 2 의 제곱수 이어야 합니다. 이 크기는 다음과 같습니다: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024
또는 2048 픽셀들. 텍스쳐는 정사각형일 필요는 없습니다. 즉 넓이가 높이와 달라도 괜찮습니다.
유니티에서 다른 크기(2 의 제곱수가 아닌것)를 사용하는 것도 가능합니다. 2 의 제곱수가 아닌 크기의 텍스쳐는 GUI Textures 에서
사용될 때 가장 좋으나 기타 다른 곳에서 쓰일 경우 무압축 (uncompressed) RGBA32bit 형식으로 변환됩니다. 이 말은 그것이
PVRT(iOS)/DXT(Desktop) 압축 텍스쳐들에 비교해서 더 많은 비디오 메모리를 차지하며 로드(load)하거나 렌더링하는데 더 오래
걸릴 것입니다 (iOS 모드일때). 보통은 GUI 의 목적일때만 2 의 제곱수가 아닌 크기를 사용합니다.
2 의 제곱수가 아닌 텍스쳐 에셋은 불러오기 할때 불러오기 설정의 고급 텍스쳐 타입의 Non Power of 2 옵션을 사용하여 크기(scale)
확대를 할 수 있습니다. 유니티는 요청된 바에 따라 텍스쳐 컨텐츠의 크기를 조절하며 게임 상에서 그것들은 다른 텍스쳐와 같이
문제없이 행동하므로 압축이 여전히 가능하며 로드할때 아주 빠르게 될 수 있습니다.
UV 맵핑 (UV Mapping)
2D 텍스쳐를 3D 텍스쳐 위에 맵핑할 때 감싸기(wrapping) 같은 형태의 행동을 하게됩니다. 이것은 UV 맵핑 (UV mapping)이라고
불리며 사용자 3D 모델링 프로그램에서 행해집니다. 유니티 안에서는 Materials 을 이용해 텍스쳐의 크기를 조절하고 이동시킬 수
있습니다. 노멀(Normal) & 디테일(Detail) 맵을 스케일 변화 시키는 것은 굉장히 유용합니다.
밉 맵 (Mip Maps)
밉맵은 실시간 3D 엔진 게임에서 성능을 최적화 하기 위해 쓰이는, 어떤 이미지의 점차적으로더 작은 버전들의 리스트입니다.
카메라로부터 더 멀리 떨어진 객체는 더 작은 텍스쳐 버젼을 쓰게 됩니다. 밉맵을 사용하는 것은 33%의 메모리를 더 사용하는지만,
사용하지 않을 경우 더 큰 성능 손실을 봅니다. 사용자는 항상 밉맵을 게임 내부 텍스쳐로 사용해야 합니다. 단 한가지 예외는 GUI
텍스쳐처럼 작게 스케일 되지 않는 텍스쳐들 뿐입니다.
노멀 맵 (Normal Maps)
노멀맵은 노멀맵 셰이더에 의해 낮은 폴리곤 모델들이 조금 더 많은 디테일을 포함하는 것처럼 만들기 위해 사용됩니다. 유니티는
RGB 이미지들로 코드화된 노멀맵을 사용합니다. 사용자는 그레이스케일(grayscale)의 높이맵(height map) 이미지로부터
노멀맵(Normal Map)을 생성할 수 있는 옵션이 있습니다.
디테일 맵 (Detail Maps)
만약 사용자가 어떤 지형을 만들고 싶으면 잔디, 바위, 모래 등이 어디에 있는지 보여주기 위해 사용자의 메인 텍스쳐를 주로 사용할
것입니다. 사용자 지형이 꽤 있는 크기이면 그것은 아주 흐릿(blurry) 해지고 말 것입니다. Detail textures 는 이런 사실을 메인
텍스쳐가 가까이 올수록 작은 디테일(세부사항)들이 서서히 사라지게 함으로써 숨깁니다.
디테일 맵을 그릴 때는 중간 회색(neutral grey)은 보이지 않고 흰색은 메인 텍스쳐를 두배 더 밝게 보이게 하며 검정은 메인 텍스쳐를
완전히 어둡게 만듭니다.
반사 Reflections (Cube Maps)
사용자가 리플렉션(반사)맵을 위해 텍스쳐를 (가령 반사되는 (Reflective) 내장셰이더를 사용) 사용하길 원하면 Cubemap
Textures 를 사용해야 합니다.
애니소트로픽 필터링 (Anisotropic filtering)
애니소트로픽 필터링 (Anisotropic filtering) 은 렌더링(이것은 완전 그래픽 카드 성능에 달림)에 영향을 미치긴 하지만, 방목(grazing)
각도에서 볼때 텍스쳐의 퀄리티를 향상시킵니다. 보통 땅(ground)이나 바닥(floor) 텍스쳐를 위해 애니소트로피 (anisotropy) 레벨을
높이는 것은 좋은 생각입니다. Quality Settings 에서 애니소트로픽 필터링 (anisotropic filtering)은 모든 텍스쳐가 사용하도록
강제화하거나 완전히 비활성화하는것이 가능합니다.
anisotropy 없을 때 (왼쪽) / 최대의 anisotropy (오른쪽) 가 그라운드 텍스쳐에 쓰였을 때
프로시져럴 재질들 (Procedural Materials)
유니티 3.4 는 프로시져럴 재질들 (Procedural Materials)로 알려진 새로운 애셋 (asset) 타입을 통합했습니다. 이들은 기본적으로
기본 재질들과 같지만, 사용하는 텍스쳐(textures)들이 미리 정의되어서 저장된 것이 아니라 실시간으로 생성 되는 것 입니다.
텍스쳐들을 순차적으로 생성하는 스크립트 코드 들은 저장된 비트맵 이미지보다 보통 더 적은 메모리 공간을 가질 것입니다.
그러므로, 프로시져럴 재질들(Procedural Materials)은 다운로드 시간을 줄이는 것을 도울 수 있습니다. 추가적으로, 생성(generation)
스크립트는 실행(runtime)시 재질의 시각적 속성들을 바꾸기 위해서 변할 수 있는 매개변수(parameters)들이 포함되어 질 수
있습니다. 이러한 속성들은 색상 변화로부터 벽의 벽돌들의 크기까지 어떤것이든 될 수 있습니다. 이는 많은 변형들이 하나의
프로시져럴 재질들(Procedural Materials)로부터 생성될 수 있으나, 재질들은 프레임 단위로 애니메이션 될 수 있음을 의미합니다.
많은 흥미 있는 시각적 효과들도 가능합니다. 캐릭터가 점점 돌로 바뀌거나, 산(acid)이 닿아 있는 표면을 부식시키는 것을
상상해보십시오.
유니티의 프로시져럴 재질들 (Procedural Materials) 시스템은 업계 표준 제품인 Allegorithmic 사의 섭스턴스(Substance)에
기반합니다.
지원 플랫폼들(Supported Platforms)
유니티 3.4 에서는 프로시져럴 재질들이 스탠드얼론(standalone) 플랫폼을 지원하며, 웹플레이어(webplayer)는 타겟들만
빌드합니다 (Windows 와 Mac OS X). 모든 다른 플랫폼들에 대해서는, 유니티는 빌드시에 그들을 미리 렌더(pre-render) 하거나
베이크(bake)합니다. 비록 이것은 순차적 생성(procedural generation)의 실행 이득을 상쇄시키지만, 에디터에서 어떤 한 기본 재질에
대해 변형들을 생성하는 데는 매우 유용합니다.
순차적 자료들을 프로젝트에 추가하기
프로시져럴 재질들은 다른 에셋들 처럼 사용자가 불러오기 할 수 있는 섭스턴스 아카이브 Substance Archive (SBSAR) 파일로
제공됩니다 (에셋 폴더 바로 위로 드래그앤드롭 혹은 Assets->Import New Asset...를 사용). 섭스턴스 아카이브 (SBSAR) 에셋은
하나 또는 다수의 프로시져럴 재질들을 포함하며, 이들에 의해 필요되는 모든 스크립트들과 이미지들을 포함합니다. 컴파일 되지
않은 SBS 파일들은 지원하지 않습니다.
비록 그들은 다르게 구현되지만, 유니티는 다른 재질들 처럼 프로시져럴 재질을 다룹니다. 프로시져럴 재질을 메쉬에 할당하려면,
(예를 들어서) 메쉬를 다른 재질에서와 마찬가지로 드래그 앤 드롭을 합니다.
프로시져럴 속성들(Procedural Properties)
각각의 프로시져럴 속성은 특정 타입의 재질을 생성하는 사용자 기반 스크립트(custom script)입니다. 이 스크립트들은 인스펙터
내에서 할당을 위해 노출(expose)된 변수들을 가질 수 있다는 점에서 유니티 스크립트들과 비슷합니다. 예를 들어 "Brick Wall"
프로시져럴 재질은 벽돌 들의 진로의 개수를 정하고, 벽돌들의 색깔, 그리고, 벽돌 사이 반죽의 색상을 정하는 속성을 표시합니다.
이는 하나의 애셋으로부터 무한대의 재질 변형을 제공합니다. 이러한 속성들은 MonoBehaviour 스크립트의 공용 변수(public
variable)들과 마찬가지로 실행 시에 스크립트로부터 설정됩니다.
프로시져럴 재질들은 복잡한 텍스쳐 애니메이션들도 통합할 수 있습니다. 예를 들어, 시계 바늘이나, 벽을 가로지르는 바퀴벌레를
애니메이션 할 수 있습니다.
프로시져럴 재질들을 기초부터 생성하기(Creating Procedural Materials From Scratch)
프로시져럴 재질들은 순차적으로 생성된 텍스쳐들이나 저장된 비트맵들과의 어떤 조합과도 작용합니다. 추가적으로, 추가된 비트맵
이미지들은 사용 전에 필터 될 수 있거나 변경 될 수 있습니다. 스탠다드 재질들과는 달리, 프로시져럴 재질은 해상도와 무관한
텍스쳐을 허용하는 SVG 파일들 형태의 벡터 이미지들을 사용할 수 있습니다.
프로시져럴 재질들을 기초부터 생성하는데 사용 가능한 디자인 툴들은 예술에 사용되는 툴들과 유사한 시각적, 노드(node) 기반의
에디팅을 사용합니다. 이는 코딩 경험이 전혀 없는 예술가들에게도 위 재질의 생성을 만드는 것이 가능하게 해줍니다. 예를 들어,
건설 중인 "brick wall" 프로시져럴 재질을 보여주는 Allegorithmic 사의 섭스턴스 디자이너의 스크린 샷이 있습니다:
프로시져럴 재질들을 구하기
유니티의 프로시져럴 재질들은 산업 표준 섭스턴스 제품에 기반하고, 프로시져럴 재질 애셋들은 유니티의 애셋 스토어(Asset
Store)를 포함한 인터넷 자료들로부터 구할 수 있습니다. Allegorithmic 의 섭스턴스 디자이너(Substance Desinger)는 프로시져럴
재질들을 생성하는데 사용됩니다. 하지만, 섭스턴스 기술을 포함하지만 유니티와 함께 작업하는데 문제가 없는 다른
어플리케이션들(3D 모델링 프로그램 등)도 있습니다.
성능과 최적화
프로시져럴 재질들은 근본적으로 비트맵 이미지들보다 더 적은 저장 공간을 사용하는 경향이 있습니다. 그렇지만, 절충이 필요한
부분은 프로시져럴 재질들은 스크립트들에 기반하고 있고, 재질들을 생성하기 위해서 그 스크립트들을 실행하는 것은 CPU 와
GPU 의 자원들이 요구됩니다. 프로시져럴 재질들이 더 복잡할 수록, 실행 시 오버헤드(overhead)는 더 커집니다.
프로시져럴 재질들은 그 매개변수들이 마지막에 생성된 이후로 변하였을 때만 업데이트되는 캐슁(caching)의 형태를 지원합니다.
더욱이, 몇몇 재질들은 많은 속성들 이론적으로 변할 수는 있지만, 실행 시에는 소수만이 실제 변화가 필요한 속성들을 가질 수
있습니다. 그러한 경우, 사용자는 재질의 이전 생성으로부터 가능한 많은 데이터를 캐쉬를 이용하여 사용할 수 있도록 유니티에게
변하지 않을 변수들에 대해서 미리 알릴 수 있습니다. 이는 종종 성능의 현저한 상승을 이끕니다.
프로시져럴 재질들은 경과 시간이나 프로시져럴 재질들의 인스턴스(이 데이터는 애니메이션 등에 유용할 수 있습니다) 개수 등,
숨겨진 (시스템 전체의) 변수들을 참조합니다. 이 변수들의 값의 변화들은 프로시져럴 재질로 하여금 명백히 정의된 변수들이 바뀌지
않더라도 업데이트 할 수 있도록 강제 시킵니다.
프로시져럴 재질들은 에디터에서 편의용으로도 사용될 수 있습니다. (예를 들어, 스탠다드 재질을 프로시져럴 재질의 매개 변수들을
설정해서 형성한 후 베이크 처리할 수 있습니다.) 이는 재질 생성의 런타임 오버헤드를 제거하지만, 당연히 베이크된 재질들은
게임플레이 중에 변화되거나 애니메이션이 될 수 없습니다.
성능을 분석하기 위해서 섭스턴스 플레이어 사용하기 (Using the Substance Player to analyze Performance)
프로시져럴 재질의 복잡도가 실행(runtime) 성능에 영향을 주므로, Allegorithmic은 그 섭스턴스 플레이어(Substance Playe)r 툴에
프로파일링 (profiling) 기능들을 포함 시켰습니다. 이 툴은 Allegorithmic�s website 에서 무료로 다운로드 가능합니다.
섭스턴스 플레이어는 유니티 3.4 에 통합된 것과 같은 최적화된 렌더링(rendering) 엔진을 사용합니다. 그래서 그것의 렌더링 측정은
섭스턴스 디자이너 자체의 성능을 나타낸다기 보다는 유니티의 성능을 나타냅니다.
무비 텍스쳐 (Movie Texture)
주의: 이것은 Pro 제품 만 지원하는 기능입니다.
데스크톱 Desktop
%div 데스크톱 desktop apply=div%
무비 텍스쳐 Movie Textures 는 비디오 파일로부터 만들어진 동영상화된 텍스쳐 Textures 입니다. 비디오 파일을 사용자
프로젝트의 에셋 폴더 Assets Folder 에 위치시킴으로써 사용자는 일반 Texture 를 사용하듯이 똑같은 방법의 사용을 위해 비디오를
불러오기 import 할 수 있습니다.
비디오 파일은 애플 퀵타임 QuickTime 을 통하여 들여옵니다. 지원되는 파일 종류들은 퀵타임 설치로 재생할 수 있는 파일 타입과
같습니다. (일반적으로 .mov, .mpg, .mpeg, .mp4, .avi, .asf). 윈도우에서는 무비 불러오기를 실행하려면 Quicktime 설치가
필수입니다. (download here).
속성
무비 텍스쳐 인스펙터 Inspector 는 일반 텍스쳐 인스펙터와 매우 유사합니다.
유니티에서 비디오 파일은 무비 텍스쳐입니다
Property:
Aniso Level
Filtering Mode
Loop
Quality
Function:
텍스쳐를 가파른 각도에서 볼 때 텍스쳐 품질을 향상시킵니다. 바닥 및 지면 텍스쳐에 적합합니다.
3D 변형(transformation)에 의해 확장할 때 해당 텍스쳐가 어떻게 필터링 되는가를 선택할 수 있습니다.
이 속성이 켜지면, 무비가 재생을 종료하면 룹 Loop 으로 반복재생 합니다.
Ogg Theora 비디오 파일의 압축. 높은 값은 높은 품질을 의미하나 파일 사이즈도 더욱 커집니다.
상세사항 Details
비디오 파일이 사용자 프로젝트에 추가될 때, 해당 비디오는 자동적으로 불려온 후 Ogg Theora 포맷으로 변환됩니다. 일단 사용자의
무비 텍스쳐가 불려오고 나면, 사용자는 일반 텍스쳐와 마찬가지로 그것을 게임 오브젝트 GameObject 나 재질 Material 에 부착할
수 있습니다.
무비의 재생 Playing the Movie
사용자의 무비 텍스쳐는 게임 시작 시 자동적으로 재생되는 것은 아닙니다. 사용자는 짧은 스크립트를 사용하여 언제 재생할 지를
알려주어야 합니다.
// this line of code will make the Movie Texture begin playing
renderer.material.mainTexture.Play();
스페이스 바를 눌러 무비 재생을 껐다 켰다 하는 토글 toggle 기능을 추가하려면 다음 스크립트를 첨부하세요:
function Update () {
if (Input.GetButtonDown ("Jump")) {
if (renderer.material.mainTexture.isPlaying) {
renderer.material.mainTexture.Pause();
}
else {
renderer.material.mainTexture.Play();
}
}
}
무비 텍스쳐 재생하기에 대하여 더 알아보시고 싶다면 Movie Texture Script Reference (ScriptRef:MovieTexture.html) 페이지를
참조하세요.
무비 오디오 Movie Audio
무비 텍스쳐가 불려올(import) 때, 영상을 동반하는 오디오 트랙도 같이 불러와 집니다. 이 오디오는 무비 텍스쳐의 오디오 클립
AudioClip 자식 child 으로 나타납니다.
이 비디오의 오디오 트랙은 해당 프로젝트 뷰 Project View 내 무비 텍스쳐의 자식 child 으로 나타납니다
이 오디오를 재생하려면, 오디오 클립이 다른 여타의 오디오 클립처럼 게임 오브젝트에 부착 attach 되어야 합니다. 프로젝트 뷰에서
오디오 클립을 드래그하여 씬 scene 이나 계층 Hierarchy 뷰 안의 아무 게임오브젝트 위에 놓으면 됩니다. 일반적으로, 이것은
무비를 보여주는 게임오브젝트와 동일합니다. 그리고는 audio.Play() (ScriptRef: GameObject-audio.html) 를 사용하여 해당 무비의
오디오 트랙이 비디오와 나란히 재생될 수 있도록 해 줍니다.
iOS
무비 텍스쳐는 iOS 에서는 지원되지 않습니다. 대신 풀스크린 스트리밍 재생 playback 이 iPhoneUtils.PlayMovie와
iPhoneUtils.PlayMovieURL (ScriptRef:iPhoneUtils.PlayMovie.html)을 통하여 제공됩니다.
사용자는 비디오 파일을 일반 에셋처럼 불러오기 할 수 있고 아니면 다른 방법으로 원격 서버에 있는 무비를 재생하기 위하여
네트워크 기반의 URL 을 지정할 수도 있습니다.
사용자는 사용자의 Project 디렉토리에 위치한 StreamingAssets 폴더 내에 사용자 비디오를 보관할 필요가 있습니다.
유니티 iOS 는 iPod 이나 iPhone 에서 이미 정상 재생되는 무비라면 모두 지원하며, 이는 일반적으로 .mov, .mp4, .mpv, .3gp
확장자를 가지는 파일이며 다음 압축 표준을 사용하는 파일을 의미합니다:
•
H.264 Baseline Profile Level 3.0 video
•
MPEG-4 Part 2 video
지원하는 압축 표준에 대하여 추가 정보를 알고 싶으시면, iPhone SDK MPMoviePlayerController Class Reference를 참고하세요.
iPhoneUtils.PlayMovie (ScriptRef:iPhoneUtils.PlayMovie.html) 혹은 iPhoneUtils.PlayMovieURL
(ScriptRef:iPhoneUtils.PlayMovie.html) 을 호출 하자마자, 해당 스크린은 현재 콘텐츠에서 지정된 배경 background 색깔로 페이드
(fade) 하며 사라질 것입니다. 무비의 재생을 준비하는 데는 얼마간의 시간이 소요될 수 있으며, 그 동안 플레이어 player 는 계속해서
배경 색깔을 디스플레이 하거나 진행 표시바 (progress indicator) 를 보여주어 해당 무비가 로딩 중이라는 것을 사용자에게
알려줍니다. 재생이 끝나면, 스크린 화면이 사용자의 콘텐츠로 다시 바뀔 것입니다.
비디오 플레이어는 비디오 재생 중 음소거로 전환하는 것을 허용하지 않습니다
위에서 적힌 대로, 애플의 내장 embedded 플레이어(현재 3.2 와 iPhone OS 3.1.2 와 이전버젼)를 사용하여 비디오 파일이 재생
되므로, 이것에 대해서 취할 수 있는 조치가 없으며 이것은 애플 소프트웨어의 버그입니다. 그러므로 여 경우 음소거는 가능하지
않습니다.
비디오 플레이어는 기기의 기울임 orientation 을 허용하지 않습니다
애플 비디오 플레이어와 iPhone SDK 는 비디오의 기울기 방향을 조정하는 방법을 제공하지 않습니다. 이에 대해일반적인 대안은
가로모드와 세로모드 용으로 두 개의 무비를 직접 만든 후, 재생 전에 기기의 방향 orientation 을 확인하여 둘 중 하나의 무비모드를
선택합니다.
Android
무비 텍스쳐는 안드로이드에서는 지원되지 않습니다. 대신 iPhoneUtils.PlayMovie (ScriptRef:iPhoneUtils.PlayMovie.html) 와
iPhoneUtils.PlayMovieURL (ScriptRef:iPhoneUtils.PlayMovie.html) 을 사용한 풀스크린 스트리밍 재생이 제공됩니다.
사용자는 비디오 파일을 일반 에셋처럼 불러오기 할 수 있고 아니면 다른 방법으로 원격 서버에 있는 무비를 재생하기 위하여
네트워크 기반의 URL 을 지정할 수도 있습니다.
사용자는 사용자의 Project 디렉토리에 위치한 StreamingAssets 폴더 내에 사용자 비디오를 보관할 필요가 있습니다.
유니티 안드로이드는 안드로이드 플랫폼에서 지원하는 모든 무비를 지원하며, 일반적으로 이것은 .mp4 나.3gp 확장자와 다음 압축
표준 중 하나를 사용한다는 것을 의미합니다:
•
H.263
•
H.264 AVC
•
MPEG-4 SP
어쨌거나 기기 판매자들은 지원 포맷 리스트를 확장하는 데 민감하므로, 일부 안드로이드 기기는 HD 비디오나 리스트 된 파일 포맷
이외의 포맷도 지원할 수 있습니다.
지원하는 압축 표준에 대하여 더 자세한 정보를 알고 싶으시다면, Android SDK Core Media Formats documentation을 참조하세요.
사용자가 iPhoneUtils.PlayMovie (ScriptRef:iPhoneUtils.PlayMovie.html) 혹은 iPhoneUtils.PlayMovieURL
(ScriptRef:iPhoneUtils.PlayMovie.html) 을 호출 하자 마자, 해당 스크린은 현재 콘텐츠에서 지정된 배경 색깔로 사라질 것 입니다.
무비를 재생하기 위하여 준비하는 데에는 얼마간의 시간이 소요되며, 그 동안 플레이어는 계속해서 배경 색깔을 디스플레이 하거나
진행 상태바 progress indicator 를 보여주어 해당 무비가 로딩 중이라는 것을 사용자에게 알려줍니다. 재생이 끝나면, 스크린은
사용자의 콘텐츠로 다시 복귀하게 됩니다.
오디오 파일들 Audio Files
메쉬(Mesh)나 텍스처(Texture)를 사용할 때와 마찬가지로 오디오 파일 Audio File 에셋의 작업방식 workflow 도 사용자가 빠르고
쉽게 작업할 수 있도록 설계 되었습니다. 사용자는 오디오 파일을 원하는 어떠한 포맷으로도 만들 수 있고, 유니티는 그것을 불러온
후 다시 재생할 수 있습니다. 그러나 사용자가 오디오 파일 작업을 하기 위해 꼭 알아야 할 몇 가지 사항들이 있습니다.
유니티의 오디오는 네이티브 Native 아니면 압축 Compressed 형태입니다. 유니티의 가장 일반적인 포맷들 (아래 리스트 참조)을
지원합니다. 파일을 불러오려면 해당 파일을 그냥 에디터 Editor 로 드래그 하면 됩니다. 디폴트 모드는 Native 이고 유니티는 원본
파일을 그대로 사용하지만, 제공한 파일을 압축 할 수도 있습니다. 불러오기에서 Compressed 옵션을 사용하면 됩니다. (유니티
아이폰은 하드웨어 디코더 Hardware Decoder 를 사용할 수 있습니다. 이것은 아이폰의 관련 문서를 참조) 네이티브와 압축 형태의
차이는 다음과 같습니다:
•
압축 Compressed: 에디터 안에서 압축 compressed 옵션을 선택하여 사운드들을 압축합니다. 오디오 데이터는 작을 것이나 재생
시 디코드 decode 하기 위해 CPU 싸이클들이 소요될 것입니다. 타겟에 따라서, 유니티는 오디오를 Ogg Vorbis (Mac/PC/콘솔) 나
MP3 (모바일 플랫폼) 형태로 인코딩 encoding 할 것입니다. 최상의 음향을 원한다면 오디오를 WAV 혹은 AIFF (PCM data 포함)
등의 무압축 포맷으로 가져와서 유니티가 인코딩을 하게 하면 됩니다. 만약 MAC/PC (스탠드얼론, 웹플레이어) 만을 타겟으로
한다면 Ogg Vorbis 파일 불러오기 importing 는 음향의 질에 영향을 끼치지 않을 것입니다. 하지만 모바일 플랫폼으로 변환하는 것은
MP3 로 재인코딩 re-encode 할 수 밖에 없고, 이 경우 약간의 음질 저하가 생깁니다. 모바일 플랫폼 만을 타겟으로 하는 경우 MP3
불러오기도 마찬가지입니다.
•
네이티브 Native: 짧은 사운드 이펙트를 위해서 네이티브 (WAV, AIFF) 오디오를 사용하세요. 오디오 데이터 용량은 더 클지
모르지만, 사운드가 재생 시에 디코딩 decoding 될 필요가 없습니다.
유니티에 불러들인 모든 오디오 파일은 오디오 클립 Audio Clip 이 됩니다. 오디오 클립은 오디오 소스 Audio Sources 와 오디오
리스너 Audio Listener 와 함께 작동합니다. 클립들은 단지 오디오 데이터라고 생각하세요. 게임에서 사용자의 클립을 오브젝트에
붙이면 (attach) 그때부터 그것은 오디오 소스가 되고 볼륨 Volume, 음높이 Pitch, 등의 다양한 다른 속성들을 가지게 됩니다. 한 소스
Source 가 재생되는 동안, 오디오 리스너 Audio Listener 는 충분히 가까이 있는 모든 소스를 “듣기”할 수 있고 바로 사용자 스피커를
통하여 그 소리를 듣게 됩니다. 사용자의 씬(scene)에는 단 한 개의 오디오 리스너만 존재할 수 있고, 이것은 일반적으로 메인 카메라
Main Camera 에 부착되어 있습니다. 대부분의 경우, 사용자는 클립이나 리스너 보다는 오디오 소스와 작업을 하게 될 것입니다.
지원 포멧
포맷
!Mac/PC 로 압축 !모바일로 압축
MPEG(1/2/3)
Ogg Vorbis
MP3
Ogg Vorbis
Ogg Vorbis
MP3
WAV
Ogg Vorbis
MP3
AIFF
Ogg Vorbis
MP3
MOD
-
-
IT
-
-
S3M
-
-
XM
-
-
유니티에서의 사운드 사용에 대한 추가 정보를 보시려면 이 매뉴얼의 Sound chapter 부분의 Creating Gameplay 을 참조하세요.
오디오 클립 Audio Clip
오디오 클립 Audio Clips 은 오디오 소스에 의해 사용되는 오디오 데이터 입니다. 유니티는 모노, 스테레오 그리고 멀티 (최대 8)
채널 오디오 에셋들을 지원합니다. 유니티는 다음의 오디오 파일 포맷들을 불러오기 importing 지원합니다 : .aif, .wav, .mp3,
와 .ogg, 그리고 다음의 tracker module file formats: .xm, .mod, .it, and .s3m. 트래커 모듈 에셋들의 경우 파형 미리보기 (waveform
preview)가 에셋 불러오기 인스펙터(asset import inspector)에서 렌더링 되지 않는다는 것 외에는 유니티에 있는 모든 다른 오디오
에셋들과 같은 방식으로 작동합니다.
오디오 클립인스펙터
속성 Properties
Property:
Function:
Audio Format
실행시 소리를 위해 사용될 특정 포맷.
Native
파일 용량이 클수록 더 높은 퀄리티. 매우 짧은 음향 효과에 최적.
Compressed
파일이 작을 수록 더 낮고 변동(variable)이 많은 퀄리티. 중간 길이의 사운드 이펙트나 음악에 최적.
3D Sound
활성화되면, 소리가 3D 공간에서 재생됩니다. 모노와 스테레오 사운드 둘 다 3D 로 재생될 수 있습니다.
Force to mono 활성화되면, 오디오 클릭은 하나의 채널 사운드로 다운믹스 down-mix (여러 개가 더 적은 수로 믹스) 될 것입니다.
Load Type
유니티가 실행시 오디오 에셋을 로드하는 방법.
로드할 때 사운드 압축을 풉니다(decompress). 즉석 비압축 decompressiong 으로 인한 성능의 오버헤드를 피하기
Decompress on 위해서 더 작은 압축 사운드들에 이것을 사용합니다. 로딩시 사운드 압축풀기는 그것을 메모리에 압축된 채로
load
놔두는 것보다 10x 정도 더 많은 메모리를 사용한다는 것을 주의하셔야 합니다. 그러므로 커다란 파일들에는
이것을 사용하지 마시길 바랍니다
Compressed in 사운드를 메모리에 압축된 채로 두었다가 재생시 압축을 풉니다. 이것은 약간의 성능에 오버헤드가 (특히
memory
Ogg/Vorbis 압축파일들에) 가해집니다. 그러므로 이것은 오직 더 큰 파일들에만 사용하세요.
오디오 데이터를 디스크로 부터 직접 스트림 stream. 이것은 메모리의 본래 사운드 사이즈의 약간을 사용합니다.
Stream from
disc
사용자의 음악 또는 매우 긴 트랙을 위해서 사용하세요. 하드웨어에 따라서 일반적으로 이것을 1 개에서 2 개의
동시간 simultaneous 스트림 정도로 적은 수로 유지하는 것이 낫습니다.
압축 compress 된 클립에 적용되는 압축의 양. 파일 사이즈에 대한 통계는 슬라이더 아래에 나타납니다.
Compression
슬라이더는 사용자의 파일 크기/배포의 요구사항에 적합한 작은 사이즈면서도 재생이 충분히 ‘’괜찮은’’ 곳에 그
슬라이더를 가져다 놓는 것이 좋습니다.
(오직 iOS 에서만) iOS 장치 위에서 압축된 오디오에 사용가능. CPU 소모적 비압축 (intensive decompression)을
Hardware
Decoding
완화시키기 위해서 애플의 하드웨어 디코더를 사용합니다. 더 많은 정보를 위해서 특정 플랫폼 관련 내용을
살펴보세요.
(오직 Android 와 iOS 에서만) 룹 Loop (반복재생) 을 지속시키기 위해 완벽히 룹핑 looping 이 되는 (압축되지 않은
Gapless
looping
PCM 포맷에서의) 오디오 소스 파일을 압축할 때 이것을 사용합니다. 스탠다드 MPEG 인코더는 룹 포인트 주변에 작은
“클릭” 이나 “팝”으로 재생되는 조용한 무음이 있는데 유니티는 사용자를 위해 이것을 매끄럽게 처리합니다.
오디오 에셋들을 불러오기 Importing Audio Assets
유니티는 압축 compressed 또는 네이티브 native 오디오를 둘다 지원합니다. MP3/Ogg Vorbis 를 제외하고는 어떤 파일 타입이던
처음에는 네이티브로 불려오게 됩니다. 압축된 오디오 파일은 게임이 실행되고 있는 동안 CPU 에 의해 압축이 풀려야 하기는 하나
파일 사이즈에서는 더 작습니다. 스트림 stream 이 체크되면 오디오는 즉시 압축이 풀리게 되나 (decompressed) 그렇지 않을 경우
로딩할때만 완전히 압축이 풀리게 됩니다. 네이티브 PCM 포맷 (WAV, AIFF)은 CPU 에 부담을 증가시키는 것 없이 더 높은 완성도를
가지는 장점이 있으나 훨씬 더 큰 파일을 생성한다는 단점이 있습니다. 모듈 파일들 (.mod,.it,.s3m..xm)은 굉장히 적은 사용공간을
사용하면서도 매우 높은 퀄리티를 제공합니다.
일반적인 규칙에 따라서 압축된 오디오(또는 모듈)은 배경 음악이나 대화같은 긴 파일들에 가장 좋고 무압축 uncompressed 된
것들은 짧은 사운드 이펙트에 더 좋습니다. 압축 Compression 슬라이더로 압축의 양(amount)을 사운드 퀄리티의 차이가 눈에 띄기
바로 전 정도로 조절합니다.
3D 오디오 사용하기 Using 3D Audio
오디오 클립이 3D 사운드로 표시 mark 되면 그것은 게임 환경 3D 공간에서의 위치를 시뮬레이션 하기 위해 재생될 것입니다. 3D
사운드는 스피커를 따라서 볼륨 volume 과 패닝 panning (왼쪽과 오른쪽 스피커의 음량 조절)을 약하거나 강하게 조절하는 것에
의해 소리의 거리와 위치를 모방 emulation 하게 됩니다. 모노와 멀티 채널 사운드 둘 다 3D 에 위치시킬 수 있습니다. 멀티 채널
오디오를 위해서 스피커 공간에서 분리된 개별 채널을 펼치고 나누기 위해서 오디오 소스 Audio Source 의 ’스프레드’ 옵션을
사용하세요. 유니티는 3D 공간에서 오디오 행동을 제어하고 미세조정하기 위한 다양한 옵션들을 제공합니다. 오디오 소스를
살펴보시기 바랍니다.
플랫폼별 상세정보 Platform specific details
iOS
모바일 플랫폼에서 압축된 오디오는 더 적은 CPU 소모적 압축풀기 (intensive decompression)을 위해서 MP3 로 인코드 됩니다.
성능상의 이유로 오디오 클립은 애플 하드웨어 코덱을 사용해서 재생될 수 있습니다. 이것을 활성화하기 위해서는 오디오 불러오기
Audio Importer 에서 "하드웨어 디코딩 Hardware Decoding" 체크박스를 클릭해 주세요. 배경에서 실행중인 iPod 오디오를 포함해 한
번에 오직 한 개의 하드웨어 오디오 스트림만이 비압축 decompression 가능합니다.
하드웨어 디코더를 사용 가능하지 않다면 압축풀기는 소프트웨어 디코더에게로 돌아갈 것입니다 (iPhone 3GS 나더 새로운 애플의
소프트웨어에서 디코더가 유니티의 (FMOD) 디코더보다 더 우선적으로 사용됩니다).
Android
모바일 플랫폼에서 압축된 오디오는 보다 적은 CPU 소모적 압축풀기를 위해서 MP3 로 인코드 됩니다.
트랙커 모듈 (Tracker Modules)
트래커 모듈은 프로그램적으로 모델(model) 되어지고, 정돈(arrange) 되어지고, 순서(sequence) 지어진 오디오 샘플 패키지라 말할
수 있습니다. 파일 포멧은 80 년대 아미가 (Amiga) 컴퓨터에서 처음으로 소개되었으며 초반 게임 개발이나 데모 문화에서 크게
유행하였습니다.
트래커 모듈 파일은 MIDI 파일과 여러모로 유사합니다. 트랙은 언제 샘플, 어떤 음높이, 볼륨, 효과 등에서 재생될지 정보를 담고
있는 악보 같은 것으로써, 가장 중요한 것은 어떤 멜로디와 리듬을 각 악기가 재생하여야 하는지에 대한 정보를 포함하는 악보입니다.
그러나 MIDI 의 단점은 소리가 그 소리를 내는 하드웨어안의 사운드 뱅크(sound bank)에 의존 한다는 것입니다. 그래서 MIDI 음악은
다른 컴퓨터에서 다른 소리가 날 수 있습니다. 트래커 모듈 파일의 강점은 모든 하드웨어에서 비슷한 소리를 낼 수 있게 해주는
고품질의 PCM 샘플파일에 삽입되어 있다는 것입니다.
지원 포맷 (Supported formats)
유니티는 가장 많이 사용되는 네가지 형식을 지원하는데, 그것은 임펄스(Impulse) 트래커 (.it), 스크림(Scream) 트래커 (.s3m), 확장
모듈 파일 포맷 (.xm), 그리고 오리지날 모듈 파일 포맷 (.mod) 입니다.
트랙터 모듈의 장점 (Benefits of Using Tracker Modules)
트래커 모듈은 사운드 퀄리티에도 불구하고 굉장히 작다는 점에서 널리 사용되어 지고 있는 PCM (.aif, .wav, .mp3, and .ogg)
형식과 구분되어 집니다. 게임 개발자는 그런 점에서 이익을 얻을수 있는데 왜냐하면 하나의 모듈이 많은 공간과 대역폭을 사용하지
않고서도 넓은 소리의 스펙트럼을 구성할수 있는 하나의 아주 작은 샘플을 포함할 수 있기 때문입니다. 동일한 소리를 내는 하나의
PCM 파일은 그에 비해 더 많은 공간과 대역폭을 사용합니다.
타사(3rd Party) 도구와 추가 참조 (3rd Party Tools and Further References)
현재 트래커 모듈을 생성하고 수정하는 가장 인기있는 툴은 OSX에는 MilkyTracker, Windows에는 OpenMPT가 있습니다. 더 많은
정보를 원하시면 2010 년 6 월의 .mod in Unity 블로그 포스트를 참조하세요.
스크립트들 사용하기 Using Scripts
이 페이지는 한 프로젝트에서 어떻게 스크립트들을 생성하고 활용하는지에 관한 짧은 소개입니다. 더 자세한 스크립팅 API 에 관한
정보는 Scripting Reference 를 참조하시길 바랍니다. 스크립팅을 통한 게임 플레이 생성에 관해 더 자세한 정보는 이 매뉴얼의
Creating Gameplay 페이지를 참조하십시오.
유니티 내에서의 스크립팅은 JavaScript, C#, 또는 Boo. 에서 간단한 행동 스크립트(behavior script)를 작성함으로써 이루어 집니다.
한 프로젝트에서 하나 또는 여러 개의 스크립팅 언어들을 같이 사용할 수 있고, 하나 이상을 사용한다고 해서 문제점이 생기지
않습니다. 특별히 언급되지 않는 한, 여기에 사용된 모든 스크립팅의 예들은 자바 스크립트로 사용됩니다.
새로운 스크립트들 생성하기 Creating new scripts
메쉬들이나 텍스쳐들과 같은 다른 에셋 들과는 달리, 스크립트 파일들은 유니티 내부에서 생성될 수 있습니다. 새로운 스크립트를
생성하기 위해서는 메인 메뉴로부터 Assets->Create->JavaScript 를 엽니다 (또는 Assets->Create->C Sharp Script 또는 Assets>Create->Boo Script). 이는 NewBehaviourScript 라고 불리는 새로운 스크립트를 생성하고 프로젝트 뷰 Project View 내의 선택된
폴더로 이 스크립트를 위치시킵니다. 프로젝트 뷰에서 아무 폴더도 선택되지 않으면, 스크립트는 루트 레벨 (root level) 에서
생성됩니다.
사용자는 프로젝트 뷰에서 스크립트를 더블클릭 해서 수정할 수 있습니다. 이는 유니티의 환경설정 (Preferences)에서 디폴트로
선택된 에디터를 실행시킬 것입니다. 사용자는 스크립팅을 유니티 안에서 직접 하는 것이 아니라, 어떤 외부 텍스트 에디터에서 하게
됩니다. 디폴트 스크립트 에디터를 설정하기 위해서는, Unity->Preferences->External Script editor 에서 드롭다운 (drop-down)
아이템을 변경하십시오.
다음은 새롭게 생성된 비어있는 행동 스크립트(behavior script)의 콘텐츠들입니다:
function Update () {
}
새로운 빈 스크립트는 혼자서는 할 수 있는 것이 많지 않습니다. 그러므로 몇몇 기능들을 추가해 보겠습니다. 스크립트들이 다음을
읽도록 변경합니다:
function Update () {
print("Hello World");
}
실행 시에, 이 코드는 콘솔에 "Hello World"를 출력 print 할 것입니다. 그러나, 코드를 실행시키는 것은 아직 없습니다. 사용자는
스크립트를 실행 하기 위해 스트립트를 씬 Scene 에서 활성화된 게임 오브젝트 GameObject 에 야 (attach) 합니다.
스크립트를 객체에 붙이기 Attaching scripts to objects
위의 스크립트를 저장하고 GameObject->Create Other->Cube 를 선택해서 씬에서 새로운 객체를 만드세요. 이것은 "Cube"라는
새로운 게임오브젝트를 생성하게 될 것입니다.
이제 스크립트를 프로젝트 뷰에서 큐브(씬이나 계층 뷰 Hierarchy View 나 상관 없음)로 드래그하세요. 사용자는 또한 큐브를
선택하고 Component->Scripts->New Behaviour Script 를 고를 수도 있습니다. 이들 중 어떤 방법이든 스크립트를 큐브에 붙일
(attach) 수 있습니다. 사용자가 생성한 모든 스크립트는 Component->Scripts 메뉴에 보일 것 입니다. 만약 사용자가 해당
스크립트의 이름을 바꿨다면, 그 새 이름이 보일 것입니다. 만약 사용자가 큐브를 선택하고 인스펙터 Inspector 를 본다면, 사용자는
스크립트를 이제 볼 수 있음을 알 수 있습니다. 이는 스크립트가 붙여졌음을 의미합니다.
만약, 큐브를 선택하고 Inspector 를 본다면, 스크립트가 이제 보여짐을 알 수 있습니다. 이는, 스크립트가 부착되었음을 의미합니다.
만든 것을 테스트 하려면, Play 를 누르세요. Play/Pause/Stop 버튼들 옆에 "Hello World" 텍스트가 보이는 것을 알 수 있습니다. 그게
보이면 플레이모드에서 나오세요.
게임오브젝트 다루기 Manipulating the Game Object
print()스테이트먼트 statement 는 사용자의 스크립트를 디버깅할 때 매우 유용합니다. 하지만 자신이 붙어있는 게임오브젝트를
조정하지는 않습니다. 몇몇 기능을 추가하기 위해서 이 스크립트를 변경해 봅시다:
function Update () {
transform.Rotate(0, 5*Time.deltaTime, 0);
}
사용자가 스크립팅이 처음이라면, 혼란스러울 수도 있습니다. 다음은 꼭 이해해야 할 중요한 개념들입니다:
1.
function Update () {} 는 유니티가 초 당 여러번 (프레임당 한번) 실행시키는 코드의 컨테이너 container 입니다).
2.
transform 은 게임오브젝트의 트랜스폼 컴포넌트 Transform Component 로의 참조입니다.
3.
Rotate()는 트랜스폼 컴포넌트 Component 안에 포함되어 있는 함수입니다.
4.
콤마 사이의 숫자들은 3D 공간에서 각 축(X, Y, Z) 주위의 회전 정도를 나타냅니다.
5.
Time.deltaTime 는 1 초동안의 움직임을 균등하게 나누는 시간(Time) 클래스의 멤버로, 사용자의 컴퓨터가 얼마나 많은
초당 프레임 (frames per second) 들을 렌더링 하는지에 관계없이 항상 같은 속도로 회전할 것입니다. 그러므로, 5 *
Time.deltaTime 는 초당 5 도를 의미 합니다.
그렇다면 이것의 의미는 이렇게 해석됩니다: “모든 프레임에서 이 게임오브젝트의 트랜스폼 컴포넌트를 초 당 Y 축으로 5 도가
움직여지도록 조금씩 회전시킨다”
사용자는 방금 transform 에 접근했었던 것처럼 많은 다른 종류의 컴포넌트들에도 접근 access 할 수 있습니다. 사용자는 컴포넌트
Component 메뉴를 사용해서 게임 오브젝트에 컴포넌트들을 추가해야 합니다. 사용자가 쉽게 접근할 수 있는 모든 컴포넌트들은
GameObject Scripting Reference Page 의 변수들 Variables 항목에 리스트가 나열되 있습니다.
게임오브젝트들과, 스크립트들, 그리고 컴포넌트들 사이의 관계에 대한 더 많은 정보를 원하신다면 앞으로 건너 띄어 이 매뉴얼의
GameObjects 페이지나 Using Components 페이지를 참조하시기 바랍니다.
변수들의 파워 The Power of Variables
사용자가 방금 만든 스크립트는 항상 큐브를 초 당 5 도씩 회전시킬 것입니다. 하지만 사용자는 초 당 다른 도수의 회전을 원할 수도
있습니다. 해당 수를 바꿔서 저장할 수도 있는데, 그러면 스크립트가 재컴파일 recompile 하도록 기다려야 하며, 결과들을 보기 위해
플레이 모드로 들어가야 합니다. 이것을 위해 훨씬 더 빠른 방법이 있습니다. 플레이 모드 동안 회전 속도를 실시간으로 실험해 볼 수
있는 매우 쉬운 방법이 있습니다.
Rotate() 함수에 5 를 타이핑 하는 대신에, speed 변수를 선언하고, 해당 함수에서 사용합니다. 스크립트를 다음과 같이 수정하고
저장하세요:
var speed = 5.0;
function Update () {
transform.Rotate(0, speed*Time.deltaTime, 0);
}
이제 큐브를 선택하고, 인스펙트를 살펴보세요. 사용자의 speed 변수가 어떻게 보이는지 주목하세요.
이 변수는 이제 파일 익스플로러에서 파일을 이름 바꾸기 rename 하는 것처럼 쉽게 인스펙터에서 직접 변경이 가능합니다. 해당
변수를 선택하고 리턴 Return 을 누른 후 값을 변경합니다. 사용자는 해당 값 위에 마우스 우클릭이나 옵션클릭(option-click)을 할 수
있고, 마우스를 위아래로 드래그 할 수도 있습니다. 해당 변수는 어느 때나 수정 가능합니다. 설사 게임이 실행 중이라도 가능합니다.
Play 를 누르고, speed 값을 조정해 보세요. 큐브의 회전 속도는 즉시 변경될 것입니다. 하지만 플레이 모드를 나온 순간, 변경
사항들이 플레이모드로 들어가기 이전의 값으로 되돌아간 걸 확인 할 수 있습니다. 이 방식을 통해 사용자는 원하는 값을 찾기 위해
여러가지 값을 충분히 실험해 본 후 그 값을 완전히 적용시킬 수 있습니다.
인스펙터내에서 변수의 값을 변경하는 이같은 방법은 사용자가 하나의 스크립트를 많은 오브젝트들에 각각 다른 변수 값으로
재사용할 수 있음을 의미합니다. 만약 사용자가 스크립트를 여러 개의 큐브들에 붙인 후 각 큐브의 speed 를 바꾸면, 이 큐브들이
비록 같은 스크립트를 사용함에도 각각 다른 속도로 회전할 것입니다.
다른 컴포넌트들 접근하기 Aceessing Other Components
스크립트 컴포넌트를 작성할 때, 그 스크립트 안의 게임오브젝트 상의 다른 컴포넌트들에 접근할 수 있습니다.
게임오브젝트 멤버들 사용하기 Using the GameObject members
사용자는 게임오브젝트 클래스의 어떤 멤버에도 직접 접근할 수 있습니다. 모든 게임 오브젝트 클래스 맴버들의 리스트는 여기서 (here)
보실 수 있습니다. 만약 지정된 클래스들중 어떤 하나가 컴포넌트로써 게임오브젝트에 붙게 (attach) 되면, 그 컴포넌트의 멤버
이름을 타이핑해서 직접 스크립트를 통해 해당 컴포넌트에 접근할 수 있습니다. 예를 들어, transform 을 타이핑하는
것은 gameObject.transform 에 상응합니다. 사용자가 따로 다른 게임오브젝트를 특별히 참조 reference 하지 않는 이상,
컴파일러는 자동으로 gameObject 로 인식을 하게 됩니다.
this 를 타이핑하는 것은 사용자가 현재 작성하는 스크립트 컴포넌트에 접근하는 것입니다. this.gameObject 를 타이핑하는 것은
그 스크립트가 붙어 있는 게임 오브젝트를 말하는 것입니다. 사용자는 간단히 gameObject 를 타이핑해서 같은 게임오브젝트에
접근할 수 있습니다. 논리적으로 this.transform 라고 타이핑하는 것은 transform 을 타이핑 하는 것과 같습니다. 게임오브젝트
멤버로서 포함되지 않은 컴포넌트로의 접근을 원하면, 다음 페이지에 설명된 gameObject.GetComponent()를 사용하셔야 합니다.
유니티에는 어떤 스크립트에서도 직접 접근할 수 있는 수많은 컴포넌트들이 있습니다. 예를 들어 사용자가 트랜스폼 컴포넌트의
이동 Translate 함수에 접근하려면, 단지 transform.Translate() 혹은 gameObject.transform.Translate()를 쓰면 됩니다.
이것은 모든 스크립트들이 게임오브젝트에 붙게 되므로 가능한 일입니다. 그래서 사용자가 transform 을 쓸 때, 사용자는
암묵적으로 스크립트 된 게임오브젝트의 트랜스폼 컴포넌트로 접근을 하게 되는 것입니다. 이것을 외부적으로 나타내고 싶다면,
gameObject.transform 이라고 적으시면 됩니다. 어느 한 방법이 다른 방법보다 더 나은 것은 아니고, 이것은 스크립트를 짜는
사용자의 성향에 달려 있습니다.
암묵적으로 (implicitly) 접근 할 수 있는 모든 컴포넌트들의 리스트를 살펴보시려면 스크립팅레퍼런스(영문) 내의 GameObject
페이지를 참조하시기 바랍니다.
GetComponent()사용하기
컴포넌트들 중에는 GameObject 클래스의 멤버들로서 직접 참조되지 않는 컴포넌트들이 많이 있습니다. 그래서 암묵적으로(implicitly)
접근 할 수 없고, 외부적으로 명확히 (explicitly) 접근해야 합니다. 사용자는 GetComponent("component name") 를 호출하고
레퍼런스를 결과물에 저장함으로써 이것을 할 수 있습니다. 이는 사용자가 해당 게임오브젝트에 부착된 또 다른 스크립트에 참조
reference 를 만들고자 할 때, 가장 보편적으로 사용되는 방법입니다.
사용자가 Script B 를 작성하고 같은 게임오브젝트에 부착된 Script A 에 레퍼런스를 만든다고 가정해 보십시오. 사용자는 해당
레퍼런스를 만들기 위해서 GetComponent()를 사용해야만 할 것입니다. 스크립트 B 에서는 사용자는 간단히 다음과 같이 작성할
것입니다:
scriptA = GetComponent("ScriptA");
그러면 스크립트 B 내에서 scriptA.variableName 를 작성함으로 인해서 스크립트 A 변수들의 어떤 것들에도 접근을 할 수 있게
됩니다. GetComponent()의 사용에 관련해 더 많은 도움을 원하시면 GetComponent Script Reference page 를 참조해 주시길
바랍니다.
이 시점으로부터 나아갈 방향은
에디터내에서 스크립트들을 사용하는 짧은 개요들을 살펴보았습니다. 더 많은 예들은, 유니티와 함께 소개된 Tutorials을
참조하십시오. 또한, 스크립트 레퍼런스 내에 Scripting Overview 페이지를 읽으십시오. 해당 페이지는 유니티를 사용한 스크립팅에
대한 더 많은 소개가 있고, 더 깊은 정보를 위한 참조들 혹은 참조 포인터들(pointers into the reference itself)을 포함합니다. 만약,
난관에 봉착하게 되면 Unity Answers나 Unity Forums를 방문하셔서 질문하시길 바랍니다. 누군가는 항상 기꺼이 도와 주려 할
것입니다
에셋 스토어 Asset Store
유니티 에셋 스토어는 프로젝트를 위한 에셋을 구매하고 다운로드 받을 수 있게 에디터에 내장되 있는 상점입니다. 에셋 스토어는
유니티 유저들과 유니티 테크놀로지스가 만들어 나아가는 계속 번창하는 무료와 유료 에셋 라이브러리를 포함합니다.
에셋 스토어는 유니티 에디터안에 바로 내장된 간단한 인터페이스를 통해 접근할 수 있는 텍스쳐, 모델, 애니메이션부터 모든
프로젝트 예제들, 튜토리얼, 에디터 익스텐션까지 모든 것들을 포함합니다
•
에셋스토어 들어가기
•
에셋스토어 네비게이션
•
에셋스토어 다운로드매니져
에셋 스토어 들어가기 Accessing the Asset Store
에셋 스토어 창을 열기 위해서는, 메인 메뉴에서 Window->AssetStore 를 선택하십시오. 그럼 에셋 스토어창이 열릴 것입니다. 만약
처음 이 창을 여는 거라면 로그인 창이나 프리유저 계정을 만드는 창이 뜰 것입니다.
에셋스토어 프론트 페이지.
에셋 스토어 탐색 Navigating the Asset Store
에셋 스토어는 브라우저 같은 인터페이스를 사용하여 탐색할 수 있습니다. 탐색은 자유 텍스트 검색 또는 추천 팩키지와 카테고리를
검색하여 하실 수 있습니다. 에셋 스토어창은 탐색 버튼과 에셋 스토어 팩키지 관리자 package manager 에 접속하고 사용자의 현재
쇼핑 카트 내용을 볼 수 있는 버튼들이 있는 툴바를 가지고 있습니다.
에셋 스토어 탐색 버튼 -- 브라우징 히스토리 내에서 이동하는데 사용.
다운로드 관리자 download manager 와 쇼핑 카트 -- 이전에 다운로드 받았던 팩키지를 관리하고 구매를 위해 선택한
팩키지의 리스트를 보기 위해서 다운로드 관리자를 사용하십시오.
이전 구매나 다운로드한 팩키지 관리 Managing previous downloads and purchases
에셋 스토어 다운로드 관리자 Asset Store Download Manager 에서 사용자가 에셋 스토어에서 이미 구매하였거나 다운로드 받았던
팩키지를 보실수 있습니다. 이것은 또한 유니티와 함께 배포됬던 모든 표준 팩키지를 보여줍니다. 다운로드 관리자를 보기 위해서는
에셋 스토어 툴바에서 “Download Manager” 버튼을 누릅니다.
다운로드 관리자.
다운로드 관리자는 이미 스토어에서 가져온 팩키지 리스트를 보여줄 뿐만 아니라 이미 구매하거나 다운로드 받은 팩키지에 대한
업테이트를 확인하고 다시 다운로드 받을 수 있게 해줍니다. 또한 다운로드 관리자를 통해 다운로드 받은 팩키지를 사용자의 현재
프로젝트로 불러올 수 있게 합니다.
에셋 서버 가이드 Asset Server Guide
유니티 에셋 서버 개요 Unity Asset Server Overview
유니티 에셋 서버 Asset Server 는 유니티에 통합된 그래픽컬 유저 인터페이스 (GUI) 이 들어간 에셋과 버젼 관리 시스템입니다.
이것은 서로 모여있거나 혹은 원격으로 서로 다른 컴퓨터에서 공동으로 프로젝트를 수행하는 팀원들을 돕기 위해 만들어졌습니다.
에셋서버는 수 기가 바이트의 대용량 프로젝트 폴더들을 다루기 위해 대량의 바이너리(binary) 에셋을 처리하는데 최적화 되어
있습니다. 에셋을 업로드 할 때, 불러오기 설정 Import Settings 과 각 에셋에 대한 다른 메타데이터도 에셋 서버에 업로드 됩니다.
파일 이름바꾸기와 이동은 시스템의 핵심이며 원활히 지원되고 있습니다.
이 기능은 유니티 프로 Unity Pro 에서만 지원되며, 한 클라이언트 당 추가적인 라이센스가 필요합니다. 에셋 서버 클라이언트
라이센스를 구매하시려면, 유니티 코리아 http://www.unity3dkorea.com/ 상점을 방문하세요.
소스 관리가 처음이십니까? New to Source Control?
사용자가 이전에 소스 관리 Source Control 를 해 본 적이 없다면, 어떤 버전 관리 시스템을 시작하더라도 약간생소 할 수 있습니다.
소스 관리 Source Control 는 어떤 서버 같은 곳 데이터베이스에 사용자가 가지고 있는 모든 에셋들 – 메쉬 meshes, 텍스처 textures,
재질 materials, 스크립트 scripts 등등 –을 데이터베이스에 저장하여 작동합니다. 그 서버는 사용자가 유니티를 실행하고 있는 집
컴퓨터가 될 수도 있고, 사용자의 로컬 네트워크 상의 다른 컴퓨터 일 수도 있습니다. 혹은 지구 반대 편에 있는 기기일 수도 있고,
심지어는 가상 기기 virtual machine 일 수도 있습니다. 선택은 다양하지만, 서버의 위치는 어디에든지 상관이 없습니다. 중요한 것은
사용자가 네트워크를 통하여 해당 서버에 접속할 수 있다는 것이고, 그 서버가 사용자의 게임 데이터를 저장한다는 것입니다.
어떤 면에서는 에셋 서버는 사용자 프로젝트 폴더의 백업 역할을 합니다. 사용자는 개발 중에는 에셋 서버의 콘텐츠를 직접적으로
만지지는 않습니다. 사용자는 사용자 프로젝트를 국부적으로 로컬 영역에서만 변경하고, 작업이 종료되면 그때 비로소 서버 상의
프로젝트에 변화 적용 Commit Changes 을 실행합니다. 이것으로 사용자의 로컬 프로젝트와 에셋 서버 프로젝트가 동기화됩니다.
이제 사용자의 동료 개발자들이 변경을 가하는 경우, 에셋 서버는 그 들의 프로젝트와 동기화되지만 사용자와는 아닙니다. 사용자의
로컬 프로젝트와 동기화를 하려면, 사용자는 서버에서 업데이트 Update from Server 를 요청합니다. 그러면 이제 사용자의 팀원이
가한 수정사항들이 서버로부터 사용자의 로컬 프로젝트로 다운로드 됩니다.
이것이 에셋 서버를 사용하기 위한 기본 작업 흐름입니다. 이러한 기본 기능 이외에도, 에셋 서버는 에셋의 이전 버전으로 되돌리는
롤백 rollback, 파일 상세 비교, 두 개의 다른 스크립트의 병합 merge, 충돌 해결, 삭제된 에셋들의 복구를 지원합니다.
에셋 서버 설치 Setting up the Asset Server
에셋 서버를 설치하려면 한 번의 서버 셋업과 각 사용자 별로 클라이언트 구성 configuration 이 필요합니다. 이것을 수행하는 방법을
알아보려면 Asset Server Setup page 를 참조하세요.
이 가이드의 남은 부분은 에셋 서버를 어떻게 배치 deploy, 관리하고 주기적으로 사용하는지 설명합니다.
에셋 서버의 일상적 사용 Daily use of the Asset Server
이 단원은 에셋 서버를 매일 사용하는 데 있어 흔한 작업, 워크플로우(작업흐름), 그리고 가장 적절한 사용 예에 대해 설명합니다.
시작하기 Getting Started
만약 사용자가 이미 많은 작업을 에셋 서버에 저장한 팀에 사용자가 가입을 하는 것이라면, 아래 설명하는 방법이 가장 빠르게
적응하고 시작하는 방법입니다. 사용자가 사용자 자신의 프로젝트를 완전히 처음부터 시작하는 것이라면 아래의 Workflow
Fundamentals 단원으로 이동하셔도 됩니다.
1.
아무 패키지도 불러오지 않은 새 프로젝트를 만드세요.
2.
메뉴바에서 Window->Asset Server 을 선택하세요.
3.
Connection 버튼을 클릭하세요.
4.
사용자의 이름과 비밀번호 (사용자 에셋 서버의 관리자가 제공) 를 입력하고 엔터키를 누르세요.
5.
Show Projects 을 누르시고 원하시는 프로젝트를 선택하세요.
6.
Connect 을 누르세요.
7.
Update 탭을 누르세요.
8.
Update 버튼을 누르세요.
9.
만일 충돌이 발생하면, 모든 로컬 버전을 버리세요.
10. 업데이트 완료를 기다립니다.
11. 이제 실행 준비가 완료 되었습니다.
에셋 서버를 매일 효과적으로 사용하는 방법에 대해 더 자세히 알고 싶다면, 아래 내용을 계속해서 보세요.
작업흐름의 기본사항들 Workflow Fundamentals
여러 사람이 공동 작업하는 팀에서 에셋 서버를 사용할 때, 사용자는 작업 시작 시에 서버로부터 모든 수정된 에셋들을 업데이트 할
것을 권고드리며 하루를 마감하거나 혹은 언제라도 작업 종료 시에는 사용자의 변경사항을 적용 Commit 하세요. 일의 중간
시점이라도 무언가 상당한 진행이 있다면 변경사항을 적용(Commit) 하는 것이 바람직 합니다. 사용자의 변경을 정기적으로 자주
변경하는 것을 추천합니다.
서버 뷰의 이해 Understanding the Server View
서버 뷰 Server View 는 사용자가 연결된 에셋서버로의 창 역할을 합니다. "Window->Asset Server"를 선택하여 서버 뷰를 엽니다.
오버뷰 Overview 탭
서버 뷰는 오버뷰 업데이트 Overview Update 와 적용 Commit 텝으로 구분되어 있습니다. 오버뷰 Overview 는 사용자의 로컬
변경사항을 빨리 적용 commit 하거나 최신 업데이트를 다운로드 할 수 있는 옵션들과 함께 사용자의 로컬 프로젝트와 서버에 올라와
있는 가장 최근 버전 사이의 차이를 보여줄 것입니다. 업데이트 Update 는 서버상의 최근 원격으로 변경된 사항을 보여주고,
그것들을 사용자의 로컬 프로젝트로 다운로드 할 수 있게 해줍니다. 적용 Commit 은 사용자가 Changeset 을 생성하고 서버에
적용하여 다른 사람들이 다운로드 할 수 있게 해 줍니다.
서버에 연결하기 Connecting to the server
사용자가 에셋 서버를 사용하려면, 사용자는 반드시 서버에 연결되어야 합니다. 이 작업을 수행하기 위해 Connection 버튼을
클릭하면 연결 connection 스크린이 나타납니다:
에셋 서버 연결 화면
여기서 사용자는 다음 사항을 입력합니다:
1.
서버 주소 Server adress
2.
사용자 이름 Username
3.
비밀번호 Password
Show projects 를 클릭하면 사용자는 에셋 서버상에 사용 가능한 프로젝트를 모두 볼 수 있습니다 Connect 를 클릭하여 연결할
프로젝트를 선택합니다. 여기서 사용자 이름과 비밀번호는 사용자의 시스템 관리자 system administrator 에게서 받을 수 있다는
것을 있습니다. 시스템 관리자는 에셋 서버를 설치 할때 사용자 계좌들을 생성하게 됩니다.
서버로부터 업데이트
서버로부터 모든 업데이트를 다운로드 받으려면, Overview 탭에 있는 Update 탭을 선택하면 최근에 적용 commit 된 변경세트
Changesets 리스트를 볼 수 있습니다. 그 중 하나를 선택함으로써 사용자는 프로젝트에 무엇이 바뀌었는지와 남겨진 적용 메시지를
함께 볼 수 있습니다. Update 를 클릭하면 모든 변경세트 Changeset 업데이트의 다운로드가 시작됩니다.
업데이트 탭
서버에 변경사항 적용하기 Committing Changes to the Server
사용자가 로컬 프로젝트에 변경사항을 만들고 그 변경사항을 서버에 저장하고 싶다면, 상단의 Commit 탭을 사용합니다.
Commit 탭
이제 사용자는 자신의 마지막 업데이트 이후에 만들어진 모든 로컬 변경 사항들을 볼 수 있고, 서버에 업데이트 하고 싶은
변경사항을 선택할 수 있습니다. 변경사항 Change 을 수동으로 변경세트 Changeset 박스 안으로 드래그하여 변경에 추가하거나
적용 메시지 commit message 필드 아래에 위치한 버튼들을 사용할 수도 있습니다. 나중에 사용자가 버전들을 비교하거나 이전
변경으로 돌아가려 할 때 적용 메시지를 입력했던 것들이 도움이 되니 항상 메세지를 남기시길 바랍니다. 이 두 가지는 아래에 더
자세히 기술되어 있습니다.
충돌 해결 Resolving conflicts
여러 사람이 같은 데이터들로 작업하게 되면 충돌은 피할 수 없게 됩니다. 하지만 불안해 하실 필요는 없습니다. 만일 충돌이
발생하면, 사용자의 프로젝트 업데이트 시 충돌 해결 Conflict Resolution 대화창이 뜨게 됩니다.
충돌 해결 Conflict Resolution 스크린
여기서 사용자는 각 개별적인 충돌에 대해 알림을 받을 것이고, 각각의 충돌을 해결하기 위해 여러가지 옵션들이 주어질 것입니다.
각 충돌에 대하여, 사용자는 에셋 건너띄기 Skip Asset(서버로부터 에셋을 다운로드 받지 않음), 사용자 변경사항 버리기 Discard My
Changes (사용자 로컬 버전의 에셋이 완전히 덮어 씌어짐) 혹은 서버 변경사항 무시하기 Ignore Server Changes (다른 사람이 만든
변경사항을 무시하며 이 작업 후에는 사용자는 사용자의 로컬 변경사항을 서버에 적용시킬 수 있음) 중에서 선택할 수 있습니다.
추가적으로, 스크립트 같은 텍스트 에셋의 경우에는 서버의 버전과 로컬 버전을 합치는 Merge 를 선택할 수 있습니다.
만일 사용자가 로컬 변경을 commit 하는 동안 충돌이 발생하면, 유니티는 사용자의 변경사항을 적용하는 것을 거부하고 충돌 발생이
발생했다고 사용자에게 통지합니다. 이 충돌을 해결하려면 Update 를 선택합니다. 그러면 사용자의 로컬 변경사항은 자동으로 덮여
씌워지지 않을 것입니다. 이 시점에 Conflict Resolution 대화 창이 뜨고, 사용자는 위 문단에의 지시 사항을 따르면 됩니다.
수정 내역 찾아보기와 에셋 되돌리기 Browsing revision history and reverting assets
에셋 서버는 그것의 데이터베이스에 하나의 어떤 에셋에 대한 모든 업로드된 버전을 보관하므로, 사용자는 언제든 이전 버전으로
사용자의 로컬 버전을 되돌릴 수 있습니다. 전체 프로젝트 혹은 단독 파일을 선택하여 복귀할 수도 있습니다. 에셋이나 프로젝트의
이전 버전으로 되돌리려면, 오버뷰 Overview 탭을 선택한 후 에셋 서버 액션 Asset Server Actions 밑에 있는 Show History 를
클릭합니다. 그러면 사용자는 모든 적용 commit 리스트를 볼 수 있을 것이고 어떤 파일이나 혹은 전체 프로젝트를 선택하여 이전
버전으로 되돌릴 수 있게 됩니다.
History 대화창
여기서 사용자는 에셋이나 프로젝트 각 버젼의 추가 코멘트와 버전 넘버를 볼 수 있습니다. 이것이 바로 상황설명적인 코멘트가
중요한 한가지 이유입니다. 에셋을 선택하여 그 작업 내역을 보거나 전체 프로젝트 Entire Project 를 선택하여 해당 프로젝트의 모든
변경 사항을 볼 수 있습니다. 필요한 수정항목 revision 을 찾으면, 사용자는 해당 수정항목 전체를 선택하거나 그 수정항목에 속해
있는 특정 에셋을 선택할 수 있습니다. 그때 Download Selected File 을 선택하면 사용자의 로컬 에셋이 사용자가 선택한 수정항목을
대체합니다. Revert All Project 를 선택하면 전체 프로젝트가 선택된 수정항목으로 되돌려 집니다.
되돌리기 revert 전에, 사용자의 로컬 버전과 선택한 서버 버전이 다르다면, 그 변경사항들은 로컬 버전이 되돌려질 때 잃게 됩니다.
만약 사용자가 로컬 복사본에만 적용된 변경 사항을 버리고 싶다면 revert 할 필요가 없습니다. 사용자가 메인 에셋 서버 창에서
변경사항 버리기 Discard Changes 를 선택하면 그 로컬 변경사항은 버려지게 됩니다. 이 작업은 즉시 서버로부터 사용자의 로컬
프로젝트로 서버에 있는 현재 버전을 다운로드 받습니다.
에셋 버전 비교하기 Comparing asset versions
사용자가 두 특정한 버전 사이의 차이점을 보고 싶다면, 사용자는 둘을 명백히 비교할 수 있습니다. 이것을 하려면 내역 History 창을
열고, 비교하고 싶은 수정사항 revision 이나 에셋을 선택하여 로컬 버젼과 비교 Compare to Local Version 를 누르세요. 만일 한
에셋의 두가지 다른 수정사항을 비교하고 싶다면 – 그 위에서 마우스 우클릭을 하고 나타난 메뉴에서 다른 수정사항과 비교
Compare to Another Revision 를 선택하여 비교하고 싶은 변경버전을 찾아 선택하세요.
주의: 이 기능을 사용하려면 다음의 지원하는 파일 diff/merge 툴들 중 하나를 설치해야 합니다. 지원하는 툴은:
•
On Windows:
o
TortoiseMerge: TortoiseSVN의 일부 혹은 project site에서 별도 다운로드.
o
WinMerge.
o
SourceGear Diff/Merge.
o
Perforce Merge (p4merge): Perforce의 비쥬얼 클라언트 수트 (P4V)의 일부.
o
TkDiff.
•
On Mac OS X:
o
SourceGear Diff/Merge.
o
FileMerge: part of Apple's XCode 개발툴.
o
TkDiff.
o
Perforce Merge (p4merge): Perforce의 비쥬얼 클라언트 수트 (P4V).
삭제된 에셋의 복구 Recovering deleted assets
로컬 에셋을 삭제하고 삭제한 것을 서버에 적용해도 해당 에셋이 실제로 영구 삭제 되는 것은 아닙니다. 오버뷰 Overview 탭에 있는
내역 History 윈도우를 사용하면 에셋의 어떤 이전 버젼도 복구할 수 있습니다.
History 대화창
Deleted Assets 아이템을 확장하여, 리스트에서 에셋을 찾아 선택한 후 복원 Recover 을 실행하면, 선택한 에셋들이 다운로드 되어
로컬 프로젝트로 다시 더해지게 됩니다. 만약 삭제 이전에 에셋이 들어가 있었던 폴더가 아직 존재한다면 해당 에셋은 원래의 그
위치로 원상복귀되고, 그렇지 않은 경우라면 복원된 것은 로컬 프로젝트 에셋 폴더의 루트에서 복원됩니다.
에셋 서버 교육 완료 Asset Server training complete
사용자는 이제 에셋 서버를 효과적으로 사용하는데 필요한 지식을 갖추게 되었습니다. 다만 작업 흐름의 기초를 항상 잊지 마시고
작업을 시작하세요. 변경사항을 항상 적용 commit 시켜 버릇하면 어떤 것을 잃게 될까 걱정하지 않으셔도 됩니다.
Behind the Scenes
유니티는 사용자를 위하여 자동으로 에셋을 불러오며 모든 종류의 메타데이터 metadata 를 관리합니다. 어떻게 그런가요?
에셋 폴더에 텍스쳐 같은 어떤 에셋 Assets 을 위치 시키면 유니티는 자신이 알지 못하던 새로운 파일을 탐지하게 됩니다. 그러면
유니티는 새로운 유일 식별자 identifier 를 그 에셋에 부여한 후 그것을 불러오기 시작합니다. 그리고 유니티는 모든 불려온 에셋을
처리합니다. 사용자가 프로젝트 뷰 Project View 에서 텍스쳐를 보면 그것은 이미 처리를 거친 에셋인 것입니다.
이런 식으로 불려온 에셋에 사용자는 많은 메타 데이터를 추가할 수 있습니다. 예를 들면 텍스쳐 불러오기 import 설정에서
텍스처에게 밉맵 mip maps 을 사용하라고 말할 수 있습니다. 당연히 포토샾은 밉맵을 지원하지 않기 때문에 이에 대한 메타데이터가
필요합니다. 각 에셋의 모든 메타데이터는 라이브러리 Library 폴더에 저장되어 있습니다. 사용자는 그 라이브러리 Library 폴더를
수동으로 건드리지 말아야 합니다.
유니티에서는 프로젝트 뷰에서 사용자가 원하는데로 에셋을 이동하고 정리할 수 있습니다. 유니티는 모든 파일의 이동과 다른
에셋에 대한 참조 reference 들을 추적합니다. 사용자는 반드시 유니티 안에서만 파일을 옮겨야 합니다. 이것은 프로젝트 뷰에서
드래그앤드롭을 통해 간단히 할 수 있습니다. 그러나 객체를 익스플로러 explorer (윈도우)나 파인더 Finder (OS X) 에서 옮기면
유니티는 그 이동을 인지하지 못합니다. 이것을 유니티는 새로운 에셋이 생기고 기존의 에셋이 제거 되었다고 여길 것입니다.
그러므로 운영체제의 파일 관리자에서 파일을 옮기면 그 에셋에 대한 연결들이 사라지게 됩니다.
사용자의 프로젝트에서 라이브러리 폴더는 아주 중요합니다. 유니티는 라이브러리 폴더를 사용자를 위해 자동으로 관리합니다.
그러므로 사용자는 그 안에서 파일을 이동 시키거나 건드리면 안됩니다. 프로젝트에서 아주 중요한 부분을 차지하고 있으므로 만약
사용자가 그것을 지우면 에셋들에 대한 모든 연결들은 사라질 것입니다.
프로젝트를 백업할 때는 항상 에셋 Assets 과 라이브러리 Library 폴더를 둘 다 포함하는 프로젝트 폴더 단위로 백업을 하세요!
게임플레이 제작 Creating Gameplay
유니티는 게임 기회자 Game Designer 가 게임을 만들도록 도와줍니다. 유니티의 정말 특별한 점은 재미있는 게임을 만들기 위해서
수년간의 프로그래밍 경력이나 미술 학위가 필요없다는 점입니다. 유니티를 배우기 위해서는 필요한 몇몇의 기본적인 작업장식
workflow 개념들이 있습니다. 이것들을 한번 익히면 사용자는 많은 시간을 들이지 않고도 게임을 만드는 자신을 볼 수 있습니다.
게임을 만들고 실행시키는데 아껴진 시간들로 사용자의 게임을 완벽하게 만들기 위해 가다듬고 밸런스를 맞추고 고쳐나가는데
사용할 수 있습니다.
이 단원은 독특하고 놀라우며 재미있는 게임플레이를 만드는데 알아야할 핵심 개념들에 대해 설명하겠습니다. 이러한 개념의
대부분은 스크립트 scripts 를 통해 이루어 집니다. 스크립트 작성 및 작업에 대한 개요는 Scripting 페이지를 참고 하세요.
•
프리팹 인스턴스화하기
•
인풋
•
트랜스폼
•
피직스
•
애니메이션 뷰 가이드
•
애니메이션 스크립팅
•
사운드
•
게임 인터페이스 요소들
•
네트워크 연결된 멀티플레이어
런타임 tl 프리팹을 인스턴스화 하기 Instantiating Prefabs at runtime
이 시점에서 사용자는 프리팹 Prefabs 에 관한 기초적인 개념을 이해하고 있어야 합니다. 프리팹은 사용자의게임을 통털어 재사용이
가능한 미리 설정된 게임오브젝트 GameObjects 들과 컴포넌트 Components 들의 집합입니다. 프리팹이 무엇인지 모르실 경우,
기초 지식을 위해 Prefabs 페이지를 읽어보시길 권유합니다.
프리팹은 복잡한 게임오브젝트를 런타임때 인스턴스화(instantiate) 시키길 원하는 경우 매우 유용합니다. 프리팹을 인스턴스화 하는
것 외에 다른 방안은 코드를 사용해 처음부터 게임오브젝트를 만드는 것입니다. 프리팹 인스턴스화는 이런 대안에 비하여 더 많은
장점들을 가지고 있습니다:
•
사용자는 한 줄의 코드로 완전한 기능을 가진 프리팹의 인스턴스화를 할 수 있습니다. 똑같은 게임오브젝트를 코드로 처음부터
만드는 것은 평균 5 줄 혹은 더 이상이 필요하게 됩니다.
•
사용자는 씬 Scene 과 인스펙터 Inspector 에서 프리팹을 더 빠르고 쉽게 설정하고 테스트하고 수정할 수 있습니다.
•
사용자는 인스턴스 되어진 프리팹을 그것을 인스턴스화하는 코드를 변경하지 않고도 해당 프리팹을 변경할 수 있습니다. 가령 코드
변경없이도 일반 로켓탄을 슈퍼 충전된 로켓으로 변경할 수 있습니다.
일반적인 시나리오들 Common Scenarios
프리팹의 강점을 설명하기 위해서, 프리팹이 유용하게 쓰여지는 기본적인 상황들을 고려해 보겠습니다:
1.
벽돌 프리팹을 각각 다른 위치로 여러 차례 생성하여 벽을 만들수 있습니다.
2.
로켓발사기는 로켓을 쏘았을 때 날으는 로켓탄 프리팹을 인스턴스화 합니다. 그 프리팹은 메쉬, 강체 Rigidbody, 충돌체
Collider, 그리고, 자신의 흔적 trail 파티클 시스템 Particle System 을 가진 자식 child 게임오브젝트를 포함합니다.
3.
많은 조각들로 폭발하는 로봇. 완전하게 작동하던 로봇은 부서진후 파괴된_로봇_프리팹 으로 교체됩니다. 이 프리팹들은
각각의 강체 Rigidbodies 들과 파티클 시스템들이 설정된 여러 개의 파트들로 나눠진 로봇으로 구성될 것입니다. 이
테크닉은 로봇을 많은 조각으로 폭발시키며 한 개의 객체를 한 개의 프리팹으로 교체하는 것을 단 한 줄의 코드로 할 수
있게 해줍니다.
벽 짓기 Building a wall
아래의 설명은 프리팹을 사용하는 것과 코드로 객체를 생성하는 것의 비교를 통하여 프리팹 사용의 장점을 보여줄 것입니다.
우선, 코드로부터 벽돌을 만들어 봅니다:
function Start () {
for (var y = 0; y < 5; y++) {
for (var x = 0; x < 5; x++) {
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.AddComponent(Rigidbody);
cube.transform.position = Vector3 (x, y, 0);
}
}
}
•
위의 스크립트를 사용하기 위해서는, 사용자는 단순히 스크립트를 저장하고 비어있는 게임오브젝트로 스크립트를 드래그 합니다.
•
GameObject->Create Empty 로 빈 게임오브젝트를 생성합니다.
만약 위의 코드를 실행하면, 사용자가 플레이 모드 Play Mode 로 들어갈 때 벽돌 벽 전체를 보게 될 것입니다. 거기에는 각각의
벽돌의 기능에 관련된 두 개의 코드 줄이 있습니다. 이들은 CreatePrimitive()와 AddComponent()입니다. 지금 이것도 나쁘지는
않지만, 벽돌들은 텍스쳐를 가지고 있지 않습니다. 텍스쳐 texture, 마찰력 friction, 강체의 질량 Rigidbody mass 을 바꾸는 것처럼
벽돌에 행해지는 각각의 추가적인 행동들은 모두 추가적인 줄을 필요로 하게 됩니다.
만약 사용자가 프리팹을 생성하여, 모든 설정을 사전에 해놓는다면, 각 벽돌의 설정과 생성을 수행하기 위해서 한 줄의 코드만
사용하게 됩니다. 이것은 사용자가 무언가 수정을 해야한다고 느꼈을 때 많은 코드들을 관리하고 수정하는 수고를 덜어 줄 것 입니다.
프리팹을 사용하면 사용자는 단지 수정한 후 플레이하면 됩니다. 코드의 수정이 따로 필요 없습니다.
개개의 벽돌을 위해 프리팹을 사용할 것이라면, 다음이 사용자가 벽을 생성하기 위해 필요한 코드입니다.
var cube : Transform;
function Start () {
for (var y = 0; y < 5; y++) {
for (var x = 0; x < 5; x++) {
var cube = Instantiate(cube, Vector3 (x, y, 0), Quaternion.identity);
}
}
}
위의 코드는 아주 깔끔할 뿐만 아니라 재사용이 가능합니다. 여기에는 큐브를 인스턴스화한다 instantiating 라던지 큐브가 강체
rigidbody 를 포함 해야 한다 라는 말이 필요 없습니다. 이 모든 것은 프리팹에서 정의되고 에디터에서 빠르게 생성될 수 있습니다.
이제 사용자는 에디터 안에서 프리팹을 만들기만 하면 됩니다. 다음과 같은 방법으로 프리팹을 생성합니다:
1.
GameObject->Create Other->Cube 를 선택합니다.
2.
Component->Physics->Rigidbody 를 선택합니다.
3.
Assets->Create Prefab 를 선택합니다.
4.
프로젝트 뷰 Project View 에서, 새로운 프리팹의 이름을 "Brick"으로 바꿉니다.
5.
계층 Hierarchy 에서 생성한 큐브를 드래그하여 프로젝트 뷰의 “Brick” 프리팹에 놓습니다.
6.
생성된 프리팹으로 사용자는 계층에서 안전하게 큐브를 삭제할 수 있습니다 (윈도우에서는 Delete, 맥에서는 CommandBackspace)
이제 벽돌 프리팹이 생성되었습니다. 이제 사용자는 이것을 스크립트의 cube 변수에 붙여야 attach 합니다. 스크립트를 포함하는 빈
게임오브젝트를 선택하세요. 인스펙터에서 새로운 변수인 "cube"가 나타난 것을 보게 될 것입니다.
이 변수는 어떤 게임오브젝트나 프리팹도 받아들일 수 있습니다
이제 "Brick" 프리팹을 프로젝트 뷰에서 인스펙터의 cube 변수위로 드래그 합니다. 플레이 Play 를 누르면 프리팹을 사용하는 벽을
보게 될 것입니다.
이것은 유니티에서 굉장히 많이 사용되는 작업방식 패턴입니다. 사용자는 처음에 코드로부터 큐브를 생성하는 스크립트가 단 2 줄이
더 긴데 왜 이 방식이 훨씬 더 낫다는 건지 의아해 할 수도 있습니다.
그러나 지금은 프리팹 사용으로 인해 단 몇 초 내에 프리팹을 수정할 수 있습니다. 모든 인스턴스의 질량 수정이 필요합니까?
그렇다면 해당 프리팹 안의 강체를 수정하세요. 모든 인스턴스들에 각각 다른 재질 Material 을 사용하기 원합니까? 그렇다면 해당
프리팹으로 재질을 한번만 드래그 해놓으면 됩니다. 마찰의 수정을 원하십니까? 그렇다면 프리팹의 충돌체에 다른 피직 재질
Physic Material 을 사용하십시오. 여기 모든 박스에 파티클 시스템을 추가 하시겠습니까? 그렇다면 프리팹에 자식 child 을 한 번만
추가하시면 됩니다.
로켓과 폭발의 인스턴스화 Instantiating rockets & explosions
다음은 프리팹이 어떻게 이 시나리오에 들어맞는지에 대한 설명입니다:
1.
로켓 발사기는 사용자가 로켓을 발사할 때, 로켓 프리팹을 인스턴스화 instantiate 합니다. 이 프리팹은 메쉬, 강체, 충돌체,
그리고 흔적 파티클 시스템 trail particle system 을 포함하는 자식 게임오브젝트를 가지고 있습니다.
2.
로켓은 폭발 프리팹에 영향을 미치고 인스턴스화 시킵니다. 폭발 프리팹은 시간이 지나며 점점 희미해지는 빛의 파티클
시스템과 주위의 게임오브젝트들에 데미지를 가하는 스크립트를 지니고 있습니다.
로켓 게임오브젝트를 코드로 처음부터 작성하여 수동으로 컴포넌트 추가하고 속성 설정하는 것도 가능하지만 프리팹을 인스턴스화
하는 것이 훨씬 더 쉽습니다. 로켓의 프리팹이 얼마나 복잡하던지 간에 로켓을 한 줄의 코드로 로켓을 인스턴스화 할 수 있습니다.
프리팹을 인스턴스화 한 후에 사용자는 인스턴스화한 객체의 어떤 속성도 변경이 가능합니다 (예: 로켓 강체의 속도 설정).
사용이 쉬운 것 이외에도 프리팹은 나중에 업데이트가 가능하다는 장점이 있습니다. 가령 사용자가 로켓을 만든다면, 로켓에 당장
흔적 파티클을 추가할 필요가 없습니다. 나중에 업데이트 하는 것이 가능하기 때문입니다. 나중에 사용자가 자식 게임오브젝트로서
흔적 trail 을 프리팹에 추가하면, 사용자의 인스턴스 instance 화 된 모든 로켓들은 흔적 파티클들을 가지게 될 것입니다. 그리고
마지막으로 사용자는 인스펙터의 로켓 프리팹의 속성들을 빨리 수정해서 게임을 정교하게 가다듬는 것을 더 쉽게 만들어 줍니다.
이 스크립트는 Instantiate() 함수를 사용하여 어떻게 로켓을 발사하는지 보여줍니다.
// 로켓이 강체가 되어야 합니다.
// 그래야 사용자가 강체없이 프리팹 할당을 못합니다.
var rocket : Rigidbody;
var speed = 10.0;
function FireRocket () {
var rocketClone : Rigidbody = Instantiate(rocket, transform.position, transform.rotation);
rocketClone.velocity = transform.forward * speed;
// 사용자는 복제품의 컴포넌트나 스크립트에 접근할 수 있습니다.
rocketClone.GetComponent(MyRocketScript).DoSomething();
}
//CTRL 나 마우스를 누르고 있을때 발사 메쏘드를 호출합니다.
function Update () {
if (Input.GetButtonDown("Fire1")) {
FireRocket();
}
}
캐릭터를 랙돌 ragdoll 이나 망가진 것으로 교체하기 Replacing a character with a ragdoll or wreck
만약 사용자가 완전히 리깅된 적 캐릭터를 가지고 있는데 그가 죽었다고 가정해 보세요. 이 경우 사용자는 단순히 캐릭터에 죽음
애니메이션이 작동하게 하고 그 적 캐릭터의 로직을 다루는 모든 스크립트를 사용불가 disable 상태로 만들수도 있습니다. 이때
사용자는 몇몇 스크립트들을 제거하고, 다른 아무도 죽은 적을 더 이상 공격하지 않는 몇몇 커스텀 로직을 더해야 하는 등등의
여러가지 청소 작업에 신경 써야 할 것입니다.
하지만 이보다 더 좋은 접근법은 캐릭터를 통체로 즉시 삭제하고, 그 캐릭터를 인스턴스화된 망가진 프리팹 인스턴스로 교체하는
것입니다. 이는 사용자에게 더 많은 유연성을 제공해 줍니다. 죽은 캐릭터를 위해서 다른 재질 을 사용할 수도 있고, 완전히 다른
스크립트들을 붙일 수도 있을 것이며, 산산조각난 적을 연출하기 위해 여러 개로 쪼개진 그 객체를 포함하는 프리팹을 만들거나 혹은
단순히 그 캐릭터의 버전을 포함하는 프리팹을 인스턴스 시킬 수도 있을 것입니다.
이 어떤 선택사항들도 Instantiate()로 한번의 호출로 가능하며, 사용자는 간단히 그것을 맞는 프리팹으로 연결만하면 완료가 되는
것입니다!
이 중 꼭 기억해야 할 중요한 파트은 사용자가 Instantiate() 명령어를 사용해 만든 부서진 캐릭터를 원래와 완전히 다른 객체들로
구성할 수 있다는 점입니다. 예를 들어 사용자가 비행기가 있을시 사용자는 두 가지 버전으로 그것을 모델링 할 것입니다. 비행기가
메쉬 렌더러 Mesh Renderer 와 비행기 피직스 (물리) physics 를 위한 스크립트들을 가진 하나의 게임오브젝트로 구성된 모델의
경우를 봅니다. 이 모델을 하나의 게임오브젝트에 간직함으로 인하여, 사용자는 더 적은 수의 삼각형들로 구성된 모델로 만들 수
있으므로 사용자의 게임 속도는 더욱 더 향상될 것입니다. 그리고 더 적은 수의 객체들로 구성됨으로 인해, 여러개의 작은 파트들을
많이 사용하는 경우에 비해 렌더 속도도 더 빠를 것입니다. 또한 비행기에 문제없이 날고 있다면, 굳이 분리된 파트들로 구성된
모델을 가지고 있을 이유가 없습니다.
망가진 비행기 프리팹을 만들기 위한 일반적인 단계는 다음과 같습니다:
1.
사용자가 선호하는 3D 모델링 프로그램으로 많은 파트들로 구성된 비행기를 모델링합니다.
2.
비어있는 씬 empty Scene 을 생성합니다.
3.
모델을 빈 씬으로 드래그 합니다.
4.
모든 파트들을 선택하고 Component->Physics->Rigidbody 메뉴를 선택해서 강체 Rigidbodies 를 모든 파트들에 더합니다.
5.
모든 파트들을 선택하고 Component->Physics->Box Collider 를 선택해서 박스 충돌체를 모든 파트들에 더합니다.
6.
추가적인 특수 효과를 위해서 각 파트들에 연기와 같은 파티클 시스템을 자식 child 게임오브젝트로써 더합니다.
7.
이제 사용자는 복수개의 폭발된 파트들로 구성된 비행기를 가지고 있고 이것들은 피직스 physic 에 의해 땅으로 떨어지고
부착된 파티클 시스템으로 인하여 흔적 파티클들을 만들어 낼 것입니다. 재생 play 을 눌러 모델이 어떤 식으로 반응하는지
살펴본 후 필요한 변경을 가해 주세요.
8.
Assets->Create Prefab 를 선택합니다.
9.
비행기 파트들을 모두 포함한 루트 root 게임오브젝트를 프리팹 안으로 드래그 합니다.
var wreck : GameObject;
//한 예로 우리는 3 초 후에 자동적으로 게임오브젝트가 망가진 것으로 바뀌도록 해봅니다.
function Start () {
yield WaitForSeconds(3);
KillSelf();
}
// CTRL 이나 마우스를 누를때 발사 메쏘드를 호출합니다.
function KillSelf () {
// 우리가 있는 같은 위치로 부서진 게임오브젝트의 인스턴스를 생성합니다.
var wreckClone = Instantiate(wreck, transform.position, transform.rotation);
// 때로 우리는 이 객체로부터 몇몇 변수들을 가져올 필요가 있습니다.
// 부서진 게임오브젝트로 말입니다.
wreckClone.GetComponent(MyScript).someVariable = GetComponent(MyScript).someVariable;
// 우리를 파괴합니다.
Destroy(gameObject);
}
일인칭 슈팅 게임 튜토리얼(강좌)은 캐릭터를 랙돌 ragdoll 버젼으로 어떻게 바꾸고 애니메이션의 마지막 상태로 팔다리를
동기화하여 맞추는지 설명합니다. 이 강좌는 Tutorials 페이지에서 찾으실 수 있습니다.
여러 개의 객체들을 특정한 패턴으로 배치하기 Placing a bunch of objects in a specific pattern
사용자가 다양한 오브젝트들을 그리드나 원형의 패턴에 놓고 싶어한다고 합시다. 예전에는 이것들을 다음과 같은 방법들로
실현했습니다:
1.
완전히 코드만으로 객체를 만듭니다. 이는 굉장히 지루합니다. 한 스크립트에 값들을 넣는 것은 작업속도가 느려질 뿐만
아니라 직관적이지도 않아 힘만 들게 됩니다.
2.
완전히 리깅된 오브젝트를 만들고, 그것을 복제해서 씬 Scene 의 여러 곳에 배치하는 방법입니다. 이 또한 지루한 작업이며,
객체들을 그리드 (좌표) grid 에 정확하게 놓는 것은 어렵습니다.
그러므로, 프리팹과 Instantiate() 를 이용하세요! 이러한 시나리오들에서 왜 프리팹들이 유용한지 이제는 이해가 되실 것입니다.
이 시나리오들을 위해 필요한 코드는 다음과 같습니다:
// 원 안에서 프리팹 인스턴스들 만들기
var prefab : GameObject;
var numberOfObjects = 20;
var radius = 5;
function Start () {
for (var i = 0; i < numberOfObjects; i++) {
var angle = i * Mathf.PI * 2 / numberOfObjects;
var pos = Vector3 (Mathf.Cos(angle), 0, Mathf.Sin(angle)) * radius;
Instantiate(prefab, pos, Quaternion.identity);
}
}
//그리드 안에 프리팹 인스턴스들 만들기
var prefab : GameObject;
var gridX = 5;
var gridY = 5;
var spacing = 2.0;
function Start () {
for (var y = 0; y < gridY; y++) {
for (var x=0;x<gridX;x++) {
var pos = Vector3 (x, 0, y) * spacing;
Instantiate(prefab, pos, Quaternion.identity);
}
}
}
입력 Input
데스크톱 Desktop
주의: 키보드, 조이스틱, 게임패드 입력은 유니티의 데스크탑 버전에서만 작동합니다.
유니티는 키보드, 조이스틱과 게임패드 입력을 지원합니다.
가상 축과 버튼은 입력 매니져 Input Manager 에서 만들수 있고 사용자는 키보드 입력을 화면 설정 대화창 screen configuration
dialogue 에서 설정할 수 있습니다.
사용자는 조이스틱, 게임패드, 키보드 그리고 마우스를 설정하고 그것들 모두를 하나의 간단한 스크립팅 인터페이스를 통해 접근할
수 있습니다.
스크립트에서 모든 가상 축은 그들의 이름을 통해 접근하게 됩니다.
모든 프로젝트는 생성되었을 때 아래의 기본 입력 축 input axe 을 가집니다:
•
수평 Horizontal and 수직 Vertical 은 w, a, s, d 와 화살표 키로 연결 map 되어 있습니다.
•
발사 Fire1, 발사 Fire2, 발사 Fire3 는 각각 Ctrl, Option (Alt), Command 으로 연결되어 있습니다.
•
마우스 Mouse X 와 마우스 Mouse Y 는 마우스 이동의 델타 delta 와 연결되어 있습니다.
•
윈도우 셰이크 Window Shake X 와윈도우 셰이크 Window Shake Y 는 윈도우 이동과 연결되어 있습니다.
새로운 입력 축 추가하기 Adding new Input Axes
새로운 입력 축을 추가하고 싶으면 Edit->Project Settings->Input 메뉴로 갑니다. 여기서 각 축의 설정도 바꿀수 있습니다.
사용자는 각각의 축을 조이스틱, 마우스, 또는 키보드 키들의 두개의 버튼들에 연결합니다.
Property:
Function:
Name
스크립트에서 이 축을 확인하기 위한 문자열 string 의 이름.
Descriptive Name
스탠드얼론 빌드에서 설정 대화창의 입력 탭에 보여지는 양의 (+) positive 값을 지닌 이름.
Descriptive Negative
스탠드얼론 빌드에서 설정 대화창의 입력 탭에 보여지는 음의 (-) negative 값을 지닌 이름.
Name
Negative Button
음(-)의 방향으로 축을 미는데 사용되는 버튼.
Positive Button
양(+)의 방향으로 축을 미는데 사용되는 버튼.
Alt Negative Button
음(-)의 방향으로 축을 미는데 사용되는 또 다른 버튼.
Alt Positive Button
양(+)의 방향으로 축을 미는데 사용되는 또 다른 버튼.
Gravity
아무 버튼도 누르지 않았을 때 축이 중립 neutral 으로 떨어지는 초당 단위 units per second 속도.
아날로그 데드존 dead zone 의 크기. 이 범위에 속하는 모든 아날로그 장치 값은 맵이 중립이 되게
Dead
만듭니다.
Sensitivity
축이 목표 값으로 가는 초당 단위 속도. 이것은 디지털 장치들에만 해당 됩니다.
Snap
활성화되면 반대 방향의 버튼을 눌렀을 때 이 축의 값이 0 으로 리셋됩니다.
Invert
활성화되면 음 Negative 버튼들이 양 positive 값을 보내고 그 반대의 경우도 성립합니다.
Type
이 축을 제어할 입력 종류.
Axis
이 축을 제어할 연결 장치의 축.
Joy Num
이 축을 제어할 연결된 조이스틱.
입력의 더 나은 모양과 느낌을 위해서 위의 설정을 이용하세요. 이들은 모두 에디터에 풍선도움말 tooltips 로도 볼 수 있습니다.
스크립트에서 입력 축 이용하기 Using Input Axes from Scripts
사용자는 이런 스크립트를 통해 현재 상태를 아래와 같이 물을 query 수 있습니다:
value = Input.GetAxis ("Horizontal");
축은 -1 부터 1 까지의 값을 가집니다. 중립 위치는 0 입니다.이것은 조이스틱과 키보드 입력의 경우입니다.
그러나 마우스 델타 Mouse Delta 와 윈도우 셰이크 델타 Window Shake Delta 는 마지막 프레임동안 얼마나 마우스나 윈도우가
움직였는가 입니다. 즉 이것은 사용자가 마우스를 빨리 움직이면 그것이 1 보다 크거나 -1 보다 작을 수도 있다는 말입니다.
같은 이름으로 여러 개의 축을 만드는 것은 가능합니다. 입력 축 input axis 을 얻을 때는 가장 큰 절대값을 가진 축이 불려옵니다.
이것은 하나의 축 이름에 하나 이상의 입력 장치를 할당하는 것을 가능하게 합니다. 예를 들어, 키보드 입력을 위한 축 하나를 만들고
같은 이름으로 조이스틱 입력을 위한 축을 만듭니다. 만약 사용자가 조이스틱을 이용하면 입력은 조이스틱에서 올 것이고 그렇지
않으면 입력은 키보드에서 오게 될 것입니다. 이 방식을 통하여 사용자는 스크립트를 작성할 때 입력이 어디서 올 지 신경쓸 필요가
없게 됩니다.
버튼 이름 Button Names
하나의 키를 어떤 축과 연결시키기 위해서는 키의 이름을 인스펙터 Inspector 에 Positive Button 또는 Negative Button 속성에
넣어야 합니다.
키의 이름은 아래의 관례를 따릅니다:
•
보통 키: "a", "b", "c" ...
•
숫자 키: "1", "2", "3", ...
•
방향 키: "up", "down", "left", "right"
•
키패드 키: "[1]", "[2]", "[3]", "[+]", "[equals]"
•
수정 키: "right shift", "left shift", "right ctrl", "left ctrl", "right alt", "left alt", "right cmd", "left cmd"
•
마우스 버튼: "mouse 0", "mouse 1", "mouse 2", ...
•
조이스틱 버튼 (모든 조이스틱에서): "joystick button 0", "joystick button 1", "joystick button 2", ...
•
조이스틱 버튼(특정 조이스틱에서): "joystick button 0", "joystick button 1", "joystick 1 button 0", ...
•
특수 키: "backspace", "tab", "return", "escape", "space", "delete", "enter", "insert", "home", "end", "page up", "page down"
•
기능 키: "f1", "f2", "f3", ...
키들을 식별하기 위한 이름은 스크립팅 인터페이스에서나 인스펙터에서나 같습니다.
value = Input.GetKey ("a");
모바일 입력 Mobile Input
유니티 iOS/안드로이드는 Input과 iOS Input 스크립트 인터페이스를 통해 아이폰, 아이패드, 그리고 안드로이드 입력 시스템에
접근할 수 있게 해줍니다.
Input은 멀티터치 스크린, 가속도계 accelerator 그리고 기기의 화면방향 device orientation 에 접근하게 해줍니다.iOS Input 는
지리적 위치 정보에 접근하게 해줍니다.
모바일 장치에서 키보드로의 접근은 iOS keyboard 를 통해 제공됩니다.
멀티터치 스크린 Multi-Touch Screen
아이폰과 아이팟 터치 장치는 다섯 손가락의 동시 터치를 감지할 수 있습니다. 사용자는 Input.touches 속성 배열 property array 을
통해 마지막 프레임 동안 화면을 만진 각 손가락에 대한 상태를 가져올 수 있습니다.
안드로이드 장치들은 한번에 얼마나 많은 손가락 터치를 감지할 지에 대한 일관된 제한 기준이 없습니다. 조금 오래된 장치에서는 두
손가락 터치, 조금 더 최신 장치에서는 다섯 손가락까지 이것은 장치마다 다 틀립니다.
각 손가락 터치는 Input.Touch의 데이타 구조로 표현됩니다:
Property:
Function:
fingerId
하나의 터치에 대한 특별 인덱스.
position
그 터치의 화면에서의 위치.
deltaPosition 마지막 프레임 이후의 화면에서의 위치 변화.
deltaTime
마지막 상태 변화 이후로 지난 시간.
아이폰/아이패드 화면은 사용자의 빠른 손가락 탭을 구별할 수 있습니다. 이 카운터는 사용자가 손가락을 옆으로
tapCount
이동하지 않고도 몇번이나 탭 했는지를 알려줍니다. 안드로이드 기기들은 탭 수를 세지 않기 때문에 이 값은 항상
1 입니다.
터치상태, 일명 "페이즈 phase"를 설명합니다. 이것은 터치가 방금 시작되었나를, 사용자가 손가락을 움직였는가,
phase
혹은 손가락을 떼었는가 등을 파악하도록 도와줍니다.
터치상태인 페이즈 Phase 는 아래 중 하나의 상태에 있게 됩니다:
Began
손가락이 방금 화면을 터치함.
Moved
손가락이 화면에서 움직임.
Stationary 손가락이 화면을 터치하고 있지만 마지막 프레임동안 움직임이 없었음.
Ended
손가락이 화면에서 들어올려짐. 이것은 터치의 마지막 페이즈 phase 입니다.
사용자가 장치를 얼굴에 가져다 대거나 한번에 다섯개 초과의 터치가 일어났을 때 시스템이 터치의 추적을 취소합니다.
Canceled
이것도 터치의 마지막 페이즈 phase 입니다.
다음은 유저가 화면을 탭 할때마다 광선 ray 을 뿌리는 예제 스크립트입니다:
var particle : GameObject;
function Update () {
for (var touch : Touch in Input.touches) {
if (touch.phase == TouchPhase.Began) {
//현재 터치 좌표에서 광선을 만듭니다.
var ray = Camera.main.ScreenPointToRay (touch.position);
if (Physics.Raycast (ray)) {
//히트시 파티클을 생성합니다.
Instantiate (particle, transform.position, transform.rotation);
}
}
}
}
마우스 시뮬레이션 Mouse Simulation
본래의 터치 지원 이외에도 유니티 iOS/안드로이드는 마우스 시뮬레이션을 제공합니다. 사용자는 표준 Input 클래스에서 마우스
기능을 사용할 수 있습니다.
장치 방향 Device Orientation
유니티 iOS/안드로이드는 사용자가 3 차원 공간에서 기기의 실제 물리적 방향의 분리된 정보를 얻는 것을 가능하게 합니다.
사용자가 어떻게 장치를 들고 있는가에 따라 게임의 행동 behaviors 이 반응하게 만들고 싶다면 방향 변화의 감지는 유용히 쓰일 수
있습니다.
사용자는 Input.deviceOrientation 속성에서 장치 방향에 대한 정보를 얻을 수 있습니다. 방향은 아래 중에 하나의 값을 가집니다:
Unknown
장치 방향을 정할 수가 없습니다. 가령 장치가 대각선 방향으로 회전하고 있는 경우에 입니다.
Portrait
장치가 똑바로 서있고 홈버튼이 바닥에 있는 세로 portrait 모드입니다.
PortraitUpsideDown 장치가 세로 모드이지만 거꾸로 세워져 홈버튼이 꼭대기에 있습니다.
LandscapeLeft
장치가 가로 모드이고 세워져 있고 홈버튼이 오른쪽에 있습니다.
LandscapeRight
장치가 가로 모드이고 세워져 있고 홈버튼이 왼족에 있습니다.
FaceUp
장치의 화면이 위 (하늘) 쪽을 향한 채로 지면과 평행으로 놓여 있습니다.
FaceDown
장치의 화면이 아래 (땅) 쪽을 향한 채로 지면과 평행으로 놓여 있습니다.
가속도계 Accelerometer
모바일 장치가 움직이면서 내장된 가속도계 accelerometer 는 3D 공간에서 일차적인 세 개의 축에 대한 선형 가속 변화 llinear
acceleration changes 를 보고합니다. 각 축 방향으로의 가속은 G-force 값으로 하드웨어에 의해 직접 보고 되어집니다. 값 1.0 은
주어진 축에서 +1g 의 양을 나타내며 -1.0 은 -1g 를 나타냅니다. 만약 사용자가 장치를 정면으로 보고 똑바로 세워서 잡고 있으면
(홈버튼이 바닥에 위치) X 축은 오른쪽으로 양수값이며 Y 축은 위쪽으로 양수이며 Z 축은 사용자 쪽으로 양수값을 가집니다.
가속도계 값은 Input.acceleration 속성에서 얻을 수 있습니다.
아래는 가속도계를 이용해서 객체를 움직이는 예제 스크립트입니다:
var speed = 10.0;
function Update () {
var dir : Vector3 = Vector3.zero;
// 장치가 지면과 평행하게 놓여있다고 가정합니다
// 홈 버튼이 오른손 쪽에 위치해 있습니다
// 장치 가속도 축을 게임 좌표에 재적용합니다:
// 1) 장치의 XY 평면이 XZ 평면에 적용됩니다
// 2) Y 축을 따라 90 도 회전 되었습니다.
dir.x = -Input.acceleration.y;
dir.z = Input.acceleration.x;
// 가속 벡터를 단위 구 unit sphere 에 고정.
if (dir.sqrMagnitude > 1)
dir.Normalize();
//이것을 프레임당 10 미터 대신 초당 10 미터로 이동하게 만듭니다.
dir *= Time.deltaTime;
//객체를 이동합니다.
transform.Translate (dir * speed);
}
로우-패스 필터 Low-Pass Filter
가속도계를 읽는 것은 불규칙한 곳들과 노이즈가 많습니다. 로우-패스 필터 Low-pass filter 를 신호 signal 에 적용시키는 것은
사용자가 그것을 완화시키고 고주파 노이즈를 제거하게 해줍니다.
아래의 스크립트는 사용자가 어떻게 로우-패스 필터를 가속도계 읽기에 적용시키는지 보여줍니다:
var AccelerometerUpdateInterval : float = 1.0 / 60.0;
var LowPassKernelWidthInSeconds : float = 1.0;
private var LowPassFilterFactor : float = AccelerometerUpdateInterval / LowPassKernelWidthInSeconds; // tweakable
private var lowPassValue : Vector3 = Vector3.zero;
function Start () {
lowPassValue = Input.acceleration;
}
function LowPassFilterAccelerometer() : Vector3 {
lowPassValue = Mathf.Lerp(lowPassValue, Input.acceleration, LowPassFilterFactor);
return lowPassValue;
}
LowPassKernelWidthInSeconds 의 값이 클수록 필터된 값이 현재 입력 샘플 input sample 에 모이는 것이 느려지게 될 것입니다
(반대의 경우도 마찬가지). 사용자는 avgSamples() 대신 LowPassFilter() 함수를 사용할 수 있습니다.
가속도계를 읽을 때 가장 정밀한 값을 원합니다. 어떻게 해야 하나요?
Input.acceleration 변수를 읽는 것은 하드웨어를 샘플링하는 것과 같은 것이 아닙니다. 간단히 말하면 유니티는 하드웨어를 60Hz의
빈도로 샘플을 모으며 그 결과를 해당 변수에 저장합니다. 현실적으로는 이것은 조금 더 복잡합니다. 만약 CPU에 부담이 굉장히
많은 상황이 되면 가속도계의 샘플링은 일정한 시간 간격으로 일어나지 않습니다. 그 결과 시스템은 한 프레임에선 2 개의 샘플을
보고하기도 하고 다음 프레임에선 1 개의 샘플을 보고하기도 합니다.
프레임에서 가속도계가 그 프레임에서 실행한 모든 측정 정보에 접근할 수 있습니다. 아래의 코드는 마지막 프레임안에서 수집된
모든 가속도계 이벤트의 간단한 평균을 보여줄 것입니다:
var period : float = 0.0;
var acc : Vector3 = Vector3.zero;
for (var evnt : iPhoneAccelerationEvent in iPhoneInput.accelerationEvents) {
acc += evnt.acceleration * evnt.deltaTime;
period += evnt.deltaTime;
}
if (period > 0)
acc *= 1.0/period;
return acc;
추가 읽기 Further Reading
유니티 모바일 입력 API 는 원래 애플의 API 에 기반을 둡니다. 유니티의 입력 API 를 더 잘 이해하기 위해서는 원래 API 를 배우면
도움이 될 것입니다. 아래에서 애플 입력 API 문서를 찾을 수 있습니다:
•
Programming Guide: Event Handling (애플 아이폰 SDK 문서)
•
UITouch Class Reference (애플 iOS SDK 문서)
주의: 위 링크들은 사용자의 로컬 설치된 아이폰 SDK 참조 문서 iPhone SDK Reference Documentation 를 참조하고 본래
ObjectiveC 코드를 포함하고 있을 것입니다. 유니티를 모바일 장치에서 사용하기 위해 꼭 위의 문서들을 이해할 필요는 없으나
도움이 되는 분들이 있을 것입니다!
iOS
장치의 지리적 위치 Device geographical location
장치의 지리적 위치는 iPhoneInput.lastLocation 속성을 통해 얻을 수 있습니다. 사용자는 이 속성을 호출하기
전에 iPhoneSettings.StartLocationServiceUpdates()를 이용해서 위치 서비스 업데이트를
시작하고 iPhoneSettings.locationServiceStatus를 통해 서비스 상태를 확인해야 할 것입니다. 자세한 사항은 scripting reference를
보세요.
트랜스폼 Transforms
트랜스폼 Transforms 은 모든 게임오브젝트 GameObject 의 핵심 컴포넌트 Component 입니다. 이것으로 게임오브젝트가 어떻게
배치되었고 어떻게 회전되었고 얼마나 큰 지를 말합니다. 트랜스폼이 없는 게임오브젝트는 가질 수가 없습니다. 사용자는 씬 뷰
Scene View, 인스펙터 Inspector, 혹은 스크립팅을 통해 어느 게임오브젝트의 트랜스폼이던지 변경이 가능합니다.
이 페이지의 나머지는 Transform Component Reference 에서 가져온 것입니다.
트랜스폼 Transform
트랜스폼 컴포넌트 Transform Component 는 씬 scene 에서의 모든 객체들의 실질적인 위치 Position, 회전 Rotation, 그리고
스케일 Scale 을 결정합니다. 모든 객체는 트랜스폼을 가지고 있습니다.
트랜스폼 컴포넌트는 인스펙터에서 보거나 편집이 가능합니다
속성들 Properties
Property:
Function:
Position
X, Y, Z 좌표에서의 트랜스폼의 위치.
Rotation
도 degree 단위로 측정된 X, Y, Z 축들로의 트랜스폼의 회전.
Scale
X, Y, Z 축에서의 트랜스폼의 스케일. 값 “1”이 원래 스케일 (객체가 불려올 때의 스케일).
트랜스폼의 모든 속성들은 트랜스폼의 부모 parent 에게 상대적인 값으로 측정됩니다. 만약 트랜스폼이 부모를 가지지 않으면,
속성들은 세계 공간 World Space 에 비교해 측정됩니다.
트랜스폼들 사용하기 Using Transforms
트랜스폼들은 항상 3D 공간에서 X, Y, Z 축을 사용하여 조정됩니다. 유니티 안에서는 이 축들은 각각 빨강 x, 녹색 y, 파랑 z 의 색깔로
표현됩니다. (XYZ=RGB 임을 명심하세요.)
3 개의 축들과 트랜스폼 속성들 사이의 색상 코드로 표현된 관계
트랜스폼 컴포넌트들은 씬 뷰나 인스펙터를 사용하여 직접 조정할 수 있습니다. 인스펙터는 쉬운 편집을 위해서 언급된 속성들을
열거합니다. 사용자는 씬에서 이동, 회전, 스케일 도구들을 사용한 상호작용을 통해서 씬에서 트랜스폼들을 수정할 수 있습니다.
이러한 도구들은 유니티 에디터의 좌측 상단 구석에 위치해 있습니다.
보기 View, 이동 Translate, 회전 Rotate, 스케일 Scale 도구들
도구들은 사용자의 씬의 어떠한 객체에도 사용 가능합니다. 객체를 클릭하세요. 그러면 객체 주위에 도구기즈모 tool gizmo 가
나타나는 것을 보게 될 것입니다. 현재 선택된 도구에 따라서, 기즈모 gizmo 는 약간씩 다르게 보이실 것입니다. 객체를 클릭하시는
것은 트랜스폼 컴포넌트가 인스펙터에서 보여지게도 합니다. 만약 인스펙터가 트랜스폼 컴포넌트나 속성들을 표시하지 않는다면,
씬 뷰에서 하이라이트된 객체도 없을 것입니다.
세 개의 기즈모 모두 씬 뷰에서 직접 편집이 가능합니다.
트랜스폼을 다루기 위해서는, 세 개의 기즈모 중 하나를 클릭하여 드래그합니다. 그러면 선택된 것의 색상이 변화하는 것이 보이실
것입니다. 마우스를 드래그하면 객체가 축을 따라 이동하거나, 회전, 스케일 하는 것을 보실 수 있을 것입니다. 마우스 버튼을 놓으면
release, 축이 여전히 선택된 상태로 남아 있는 것을 보게 될 것입니다. 사용자는 선택된 축을 따라 트랜스폼을 조정하기 위해서
마우스 중간 버튼을 클릭해서 드래그하세요. 세 개의 축을 한번에 선택하기 위해서는 세 개의 기즈모의 중심점을 클릭해서 드래그
하시면 됩니다.
각각의 축은 클릭시 선택됩니다
부모자식관계설정 (패어런팅) Parenting
부모자식관계설정 (패어런팅) Parenting 은 유니티를 사용할 때 이해해야 할 가장 중요한 개념 중의 하나입니다. 하나의
게임오브젝트가 또 다른 게임오브젝트의 부모 Parent 일 때, 자식 게임오브젝트는 부모게임오브젝트가 하는 것을 그대로 따라서
움직이고, 회전하며, 스케일이 변화할 것입니다. 이것은 우리 몸에 부착되어 있는 팔들처럼 우리가 몸을 틀 때 팔들은 몸통에 붙어
있기 때문에 팔들도 같이 움직이게 됩니다. 어떤 객체도 다수의 자식 child 들을 가질 수는 있지만, 부모는 단 하나만 가지게 됩니다.
사용자는 계층뷰 Hierarchy View 에서 하나의 게임오브젝트를 다른 게임오브젝트 위로 드래그해서 부모를 설정할 수 있습니다.
이것은 두 게임오브젝트들 사이에 부모-자식관계를 생성하게 될 것입니다.
부모-자식 구조의 실제 예. 화살표가 왼쪽에 붙은 모든 게임오브젝트들은 부모 게임오브젝트들입니다.
위의 예에서, 우리는 팔들이 몸에게 자식으로 관계설정되고 (A is parented to B = A 가 B 의 자식이 됨) , 손들은 팔들에
자식관계설정이 되었다고 말할 수 있습니다. 사용자가 유니티 안에서 만들 씬들은 이러한 트랜스폼 계층구조 Transform
hierarchies 의 집합을 포함하고 있을 것입니다. 최상위 부모 객체는 루트 객체 Root object 라고 일컫습니다. 사용자가 부모 객체를
움직이거나 크기 변화 또는 회전을 시키면, 부모에게 적용된 모든 트랜스폼 변화들은 자식 객체들에게도 적용이 됩니다.
주목할 것은 어떤 자식 게임오브젝트의 인스펙터 내의 트랜스폼 값들이 부모의 트랜스폼 값들에 상대적으로 표시된다는 사항입니다.
이 트랜스폼 값들은 로컬(지역) 좌표 Local Coordinates 들로 불려집니다. 스크립트를 통해서 로컬 좌표뿐만 아니라 전체 좌표
Global Coordinates 에도 접근할 수 있습니다.
사용자는 복수의 개별 객체들을 서로 부모자식관계를 설정하여 인간 랙돌 ragdoll 같은 뼈대구조의 합성객체 compound object 를
생성할 수 있습니다. 사용자는 또한 하나의 부모설정으로 작지만 효과있는 객체들을 만들 수 있습니다. 예를 들면 사용자가 한밤중에
일어나는 공포게임을 만든다면, 회중전등 flashlight 로 효과적인 분위기를 만들려 할 것입니다. 이 전등 객체를 생성하기 위해서,
사용자는 스팟라이트 spotlight 트랜스폼을 회중전등 트랜스폼에 자식설정을 할 것입니다. 그러면 회중전등 트랜스폼의 변화는
스팟라이트에 영향을 줘서 그럴 듯한 회중 전등 효과를 만들게 됩니다.
스케일 Scale 의 중요성
트랜스폼의 스케일 scale 은 사용자 3D 모델링 프로그램에서의 메쉬 mesh 사이즈와 유니티 안에서의 메쉬 사이즈 사이의 차이를
말합니다. 유니티 안에서의 메쉬의 크기(즉 트랜스폼의 스케일)는 굉장히 중요합니다. 그중에서도 특히 물리 physics 시뮬레이션
중에는 말입니다. 객체의 스케일을 결정하는 것에는 세 가지 요소가 있습니다:
•
사용자의 3D 모델링 프로그램에서의 메쉬의 크기.
•
객체의 불러오기 세팅 Import Settings 에 있는 메쉬 스케일 요소 Mesh Scale Factor 설정.
•
트랜스폼 컴포넌트의 스케일 (Scale) 값들.
사용자는 트랜스폼 컴포넌트 Transform Component 에서 객체들의 스케일 Scale 을 조정하지 않는 것이 좋습니다. 가장 이상적인
것은 실제 세계에서의 스케일로 모델들을 제작하는 것입니다. 이는 트랜스폼의 스케일을 추후에 바꿀 필요가 없게 합니다. 두 번째로
차선책은 각각의 메쉬를 위하여 불러오기 설정 Import Settings 에서 메쉬를 불러올 스케일을 조정하는 것입니다. 불러오는 파일의
크기에 기반해 어떤 최적화 작업이 일어나게 되고, 조정된 스케일 값을 가진 객체의 인스턴스화는 성능의 저하를 일으킬 수 있습니다.
더 많은 정보를 위해서는 Rigidbody 컴포넌트의 스케일 최적화 부분 optimizing scale 을 읽으시길 바랍니다.
힌트 Hints
•
트랜스폼을 자식관계 설정할 때, 자식을 만들기 전에 부모의 위치를 0, 0, 0 에 두세요. 이는 나중에 일어날 골치거리들을 줄이게
해줍니다.
•
파티클 시스템 Particle Systems 은 트랜스폼 스케일에 영향을 받지 않습니다. 파티클 시스템의 스케일을 변화시키기 위해서는,
시스템의 파티클 이미터 particle emitter, 에니메이터 animator, 그리고 렌더러 renderer 안의 속성들을 변화시켜야 합니다.
•
물리 physics 시뮬레이션을 위한 강체 Rigidbodies 를 사용한다면, class-Rigidbody 페이지에 스케일 속성에 관한 중요한 정보들을
보시는 것이 좋습니다.
•
Unity Menu->Preferences->Colors & keys 에서 트랜스폼 축들 (그리고 다른 사용자 인터페이스 UI 요소들)의 색상들을 변경할 수
있습니다.
•
스케일 바꾸는 것을 피할 수 있다면, 그렇게 하는 것이 낫습니다. 3D 모델링 프로그램 또는 메쉬의 불러오기 설정에서 모델들의
스케일을 완전히 결정짓도록 해보세요.
물리 (피직스) Physics
리지드바디
Rigidbodies 는 사용자의 GameObjects 가 물리력의 제어 하에서 동작 할 수 있게 하여 줍니다. 리지드바디는 사용자의 오브젝트가
현실 세상처럼 움직이게 만들어 힘과 회전력을 적용할 수 있게 하여 줍니다. GameObject 는 중력의 영향을 받고 스크립트를 통해
추가된 힘의 영향력 하에 있거나, NVIDIA PhysX 물리력 엔진을 통하여 다른 오브젝트와 상호작용을 하려면, 반드시 Rigidbody 을
포함하여야 합니다.
리지드바디는 GameObjects 가 물리적 영향력 하에 동작하게 하여 줍니다
속성
Property:
Function:
킬로그램으로 표시된 오브젝트의 무게. 다른 리지드바디에 비교하여 100 배 이하 혹은 이상 이내에서 무게를 정할
Mass
것을 권유합니다.
힘을 받아 동작할 때 오브젝트에 가해지는 공기 저항력의 정도. 0 은 저항력이 없는 상태를 말하고, 무한대면
Drag
오브젝트는 즉시 멈춰서 버립니다.
회전력에 의해 회전 시 오브젝트에 가해지는 공기 저항력의 정도. 0 은 저항력이 없는 상태를 말하고, 무한대면
Angular Drag
Use Gravity
오브젝트는 즉시 멈춰서 버립니다.
이 속성이 켜지면, 오브젝트는 중력의 영향을 받습니다.
이 속성이 켜지면, 오브젝트는 물리 엔진에 의해 작동하지 않고, 그의 Transform 에 의해서만 조종될 수 있습니다.
Is Kinematic 이 속성은 움직이는 플랫폼에서 유용하며 또한 사용자가 HingeJoint 가 있는 리지드바디를 동영상화 하고 싶을
때도 유용합니다.
Interpolate
만일 사용자의 리지드바디 움직임에 경련이 보이면 이 중 한 옵션을 사용하여 보십시오.
None
보간법(Interpolation)이 적용되지 않습니다.
Interpolate
이전 프레임의 Transform 을 기반으로 Transform 을 부드럽게 수행합니다.
Extrapolate
다음 프레임의 Transform 을 예상하여 Transform 을 부드럽게 수행합니다.
Freeze
이 속성이 켜지면, GameObject 는 스크립트를 통한 충돌이나 힘에 의해서는 절대 회전하지 않을 것 입니다. 오직
Rotation
transform.Rotate()을 사용하여 회전할 것 입니다.
Collision
오브젝트가 충돌을 감지하지 못하고 다른 오브젝트를 관통하는 것을 방지하기 위하여 사용됩니다.
Detection
장면(scene) 내에서 다른 모든 콜라이더에 대한 신중한(Discreet) 충돌 감지를 사용합니다. 다른 콜라이더는 이것에
Discrete
대한 충돌을 시험할 때 Discrete 충돌 감지를 사용할 것 입니다. 일반 충돌에 사용 됩니다.(이것은 디폴트 값입니다).
동적 콜라이더에 (리지드바디를 가지고 있는) 대해서는 신중한(Discrete) 충돌 감지를 사용하고, 정적
메쉬콜라이더(static MeshColliders) (리지드바디가 없음)에 대해서는 지속적인 충돌감지를 사용합니다. 지속적인
동적(Continuous Dynamic)으로 설정된 리지드바디는 이 리지드바디에 대한 충돌을 테스트 할 때 지속적 충돌
Continuous
감지를 사용할 것 입니다. 다른 리지드바디는 신중한 충돌(Discreet Collision) 감지를 사용할 것 입니다. 지속적인
동적(Continuous Dynamic) 리즈드바디가 충돌할 필요가 있는 오브젝트에 사용됩니다. (이것은 물리적 수행에 있어
커다란 임팩트가 있으므로, 빠른 오브젝트의 충돌에 별 문제가 없다면 Discrete 로 남겨두기 바랍니다).
속성이 Continuous 로 설정된 오브젝트나 지속적 동적 충돌(Continuous Dynamic Collision)에는 지속적 충돌 감지를
Continuous
사용합니다. 이것 또한 (리지드바디가 없는)정적 메쉬콜라이더(static MeshColliders)에 대하여 지속적 충돌 감지를
Dynamic
사용할 것 입니다. 다른 콜라이더에 대해서는 신중한(discrete) 충돌 감지를 사용합니다. 빠르게 움직이는
오브젝트에 사용됩니다.
Constraints
Freeze
리지드바디의 움직임에 대한 제약 :-
월드에서 움직이는 리지드바디를 . X, Y, Z 축에서 선택적으로 멈추게 합니다.
Position
Freeze
월드에서 회전하는 리지드바디를 . X, Y, Z 축에서 선택적으로 멈추게 합니다.
Rotation
상세사항
리지드바디는 사용자의 GameObjects 가 물리엔진의 제어 내에서 동작할 수 있게 합니다. 이것은 실감나는 충돌, 여러 종류의
조인트들, 그리고 여타의 아주 멋진 동작을 가능하게 합니다. 사용자의 GameObjects 에 리지드바디에 힘을 가하여 조종하게 되면
단순한 Transform Component 보다는 아주 다른 느낌과 시각의 효과를 줄 수 있습니다. 일반적으로 사용자는 같은
GameObject 에서 리지드바디를 조종하는 것과 변형(Transform)을 동시에 같이 할 수는 없고 하나를 선택해야 합니다.
변형(Transform)과 리지드바디를 조종하는 것 사이의 가장 큰 차이는 힘의 사용입니다. 리지드바디는 힘과 회전력을 받을 수 있지만,
변형(Transform)은 없습니다. 변형(Transform)도 해석하고 회전할 수 있지만 물리력을 사용하는 것과 같은 것은 아닙니다. 사용자가
직접 사용해보면 극명한 차이를 느낄 것 입니다. 리지드바디에 힘과 회전력을 가하면 실제로 오브젝트의 Transform 컴포넌트의
위치와 회전을 변경합니다. 이렇기 때문에 사용자는 둘 중 하나만을 사용해야 합니다. 물리력을 사용하면서도 Transform 을
변경하는 것은 충돌과 여타 다른 계산에서 문제를 일으킬 수 있습니다.
리지드바디가 물리엔진에 의해 영향을 받으려면 명시적으로 사용자의 GameObject 에 추가하여야만 합니다. 사용자는 메뉴바에서
Components->Physics->Rigidbody 에서 선택한 오브젝트에 리지드바디를 추가할 수 있습니다. 이제 사용자의 오브젝트는
물리적으로 완벽합니다. 해당 오브젝트는 중력하에서 추락하고 스크립트를 통해 힘을 받을 수 있으나, 만일 사용자가 원하는 대로
정확하게 행동하게 하려면 Collider 난 조인트(Joint)를 추가해야 할 수도 있습니다.
Parenting
어느 오브젝트가 물리력 제어 하에 있을 때, 이의 변형부모(transform parents )가 움직이는 것과 반쯤 독립적으로 움직입니다.
사용자가 어느 한 부모를 이동시키면, 부모는 리지드바디 자식을 같이 끌고 다닙니다. 하지만 해당 리지드바디는 여전히 중력에
추락하고 충돌 이벤트에 반응합니다.
Scripting
사용자의 리지드바디를 제어하기 위하여, 사용자는 주로 스크립트를 사용하여 힘이나 회전력을 가할 것 입니다. 이것을 하려면
오브젝트의 리지드바디에 AddForce()와 AddTorque()를 호출합니다.사용자가 물리력을 사용할 경우 오브젝트의 Transform을
변경할 수 없다는 것을 기억하십시오.
Animation
어떤 상황에서는, 주로 랙돌(ragdoll) 효과 생성에, 애니메이션과 물리력 사이에 오브젝트의 제어를 맞교환 할 필요가 있습니다.
이러한 목적을 위하여 리지드바디는 isKinematic으로 표시될 수 있습니다. 리지드바디가 isKinematic으로 표시되어 있는 한 충돌,
힘 혹은 여타 다른 부분의 physX에 대한 영향은 미치지 못합니다. 이 경우 사용자는 Transform 콤포넌트를 바로 조종하여 해당
오브젝트를 제어해야 한다는 것을 의미합니다. 운동학적 리지드바디(Kinematic Rigidbodies)는 다른 오브젝트에 영향을 주겠지만 그
들 자신은 물리력에 영향을 받지 않습니다. 예를 들어, Kinematic 오브젝트에 부착된 조인트는 다른 리지드바디가 부착되는 것을
제한하고, 운동학적 리지드바디는 충돌을 통해 다른 리지드바디에 영향을 줄 것 입니다.
Colliders
콜라이더는 리지드바디와 함께 충돌이 발생을 가능케 하려면 추가되어야 하는 다른 종류의 콤포넌트입니다. 만일 2 개의
리지드바디가 서로 충돌하면, 물리엔진은 두 오브젝트에 콜라이더가 부착되어 있지 않는 한 계산을 하지 않을 것 입니다. 콜라이더가
없는 리지드바디는 물리력 시뮬레이션에서 서로를 관통하고 지나갈 뿐입니다.
콜라이더는 리지드바디의 물리적 경계를 정의합니다
메뉴의 Component->Physics 에서 콜라더를 추가합니다. 각 콜라이의 콤포넌트 조회 페이지에서 더 많은 메뉴를 확인할 수 있습니다:
•
Box Collider - 정육면체의 프리미티브 모양
•
Sphere Collider - 구의 프리미티브 모양
•
Capsule Collider - 캡슐의 프리미티브 모양
•
Mesh Collider - Collider 오브젝트의 메쉬에서 콜라이더를 생성, 다른 메쉬 콜라이더와 충돌 할 수 없습니다
•
Wheel Collider - 자동차와 여타 움직이는 교통수단을 위한 콜라이더
복합 콜라이더
지속적인 충돌 감지
지속적 충돌감지(Continuous collision detection is)는 빨리 움직이는 콜라이더가 서로를 관통하는 것을 방지할 수 있습니다.
노멀(Discrete) 충돌 감지를 사용하거나, 한 오브젝트가 한 프레임 내에서 콜라이더의 한쪽 면에 있고 다음 프레임에서 이미 해당
콜라이더를 지나쳤을 때 이 현상이 발생할 수 있습니다. 이것을 해결하기 위하여, 사용자는 빨리 움직이는 오브젝트의 리지드바디
상에 지속적 충돌감지(continuous collision detection) 옵션을 켤 수 있습니다. 리지드바디가 충돌감지 모드가 Continuous 혹은
Continuous Dynamic 으로 설정된 여타의 다른 리지드바디를 서로 관통하는 것을 방지하려면 충돌 감지 모드를 Continuous 로
설정하여야 합니다.
정확한 크기의 사용
사용자의 GameObject 의 메쉬의 크기는 리지드바디의 질량보다 훨씬 더 중요합니다. 만일 사용자의 리지드바디가 예상한 대로
움직여주지 않으면 – 느리거나 떠다니거나 혹은 정확하게 충돌하지 않으면 – 사용자 에셋의 질량을 조정해 보십시오. 유니티의
디폴트 단위 크기는 1 단위 = 1 미터로 하여 사용자가 들여온 메쉬의 크기가 유지되고 물리력계산에도 적용됩니다. 예를 들어,
무너지는 고층빌딩은 장난감 블록으로 만든 타워와는 아무 다르게 동작하므로, 규모가 다른 오브젝트는 정확한 규모로 모델링이
되어야 합니다.
사용자가 만일 인간을 모델링 한다면, 유니티에서 2 미터 가량 되도록 해야 합니다. 사용자 오브젝트가 정확한 크기를 가지고 있는지
확인하려면, 디폴트 규브와 비교하여 보십시오. 사용자가 큐브를 생성하려면 GameObject->Create Other->Cube 를 사용하면
됩니다. 해당 큐브의 높이는 정확하게 1 미터가 될 것이므로, 사용자은 인간 오브젝트는 2 배쯤이 되어야 합니다.
사용자가 메쉬 그 자체를 조절할 수 없다면, 사용자는 Project View 에서 Assets->Import Settings...을 선택하여 특정 메쉬 에셋의
동일 스케일을 변경 할 수 있습니다. 여기서, 사용자는 스케일을 변경하고 사용자 메쉬를 다시 불러들이기 할 수 있습니다.
사용자의 게임이 사용자 오브젝트를 다른 규모로 발생하게 할 필요가 있다면, 사용자 Transform 의 스케일 축의 값을 조절하는 것은
허용됩니다. 단점은 물리 시뮬레이션에서 해당 오브젝트가 발생할 때 더 많은 작업을 해야 한다는 것이며 이것이 사용자 게임의 성능
저하를 가져올 수 있습니다. 이것이 비로 엄청난 손실은 아니지만 다른 두 옵션으로 사용자의 스케일을 최종 설정하는 것보다는 덜
효율적입니다. 또한 일정하지 않은 스케일을 사용하면 육아(Parenting)이 사용되었을 때 원치 않는 행동이 생길 수도 있다는 것을
기억하십시오. 이러한 이유들로 사용자의 모델링 어플리케이션에서 정확한 스케일을 사용하여 오브젝트를 생성하는 것이 항상
최고의 선택이라는 것 입니다.
Hints
•
두 리지드바디의 상대적 Mass 가 그들이 서로 충돌했을 때 어떻게 반응하는 지를 결정합니다.
•
한 리지드바디를 다른 것보다 Mass 를 크게 한다고 해서 다른 것보다 빨리 자유 낙하하는 것은 아닙니다. Drag 를 사용하십시오.
•
낮은 Drag 값을 설정하면 해당 오브젝트가 무거워 보이게 합니다. 높은 값은 가벼워 보이게 합니다. Drag 의 전형적인
값은 .001(단단한 강철 블록)과 10(새털)의 사이에서 결정합니다.
•
사용자가 사용자 오브젝트를 Transform 콤포넌트에서 직접 조정하면서 물리력을 원한다면, 리지드바디를 하나 추가하고 그것을
Kinematic 으로 설정하십시오.
•
사용자가 Transform 콤포넌트를 사용하여 GameObject 를 움직이고 있으나 Collision/Trigger 메시지를 수신하고 싶다면, 사용자는
움직이는 오브젝트에 리지드바디를 부착하여야 합니다.
Constant Force
Constant Force 은 Rigidbody 에 일정한 힘을 추가하기 위한 간편한 유틸입니다. 이것은 사용자가 커다란 속도를 가지고 시작하는
것이 아닌 가속하도록 하는 것을 원할 때 로켓과 같은 오브젝트에 잘 작동합니다.
Constant Force 에 의해 앞으로 나가는 로켓 프로펠러
Properties
Property:
Force
Function:
공간에서 적용되는 힘의 벡터.
Relative Force 오브젝트의 로컬 공간에서 적용되는 힘의 벡터.
공간에 적용되는 회전력의 벡터. 오브젝트는 그 벡터 주변을 돌기 시작할 것입니다. 벡터가 길수록 회전을
Torque
빨라집니다.
Relative
로컬 공간에 적용되는 회전력의 벡터. 오브젝트는 그 벡터 주변을 돌기 시작할 것입니다. 벡터가 길수록 회전을
Torque
빨라집니다.
Details
로켓을 앞으로 가속하기 위해서는 z 축의 양수쪽을 따라서 Relative Force 를 세팅해 주십시요. 그 다음 최고 속도를 넘지 않기
위해서 Rigidbody 의 Drag 속성을 사용합니다(더 높이 드래그 할 수록 최고 속도는 더 낮아질 것입니다). Rigidbody 에서 로켓이
그것의 경로를 따라서 머물수 있도록 중력을 끄는 것을 잊지 마십시요.
Hints
•
오브젝트가 위로 흘러가기 위해서 양수의 Y 값을 가지는 Force 속성과 함께 Constant Force 를 추가합니다.
•
오브젝트가 앞로 흘러가기 위해서 양수의 Z 값을 가지는 Relative Force 속성과 함께 Constant Force 를 추가합니다.
구 콜라이더
Sphere Collider 는 구 모양의 기본 충돌 프리미티브(primitive) 입니다.
구 콜라이더 더미
속성
Property:
Function:
Radius
콜라이더의 크기.
Center
오브젝트의 지역 공간에서 콜라이더의 위치.
Details
구 콜라이더는 일정한 스케일로 크기를 변경할 수 있으나, 특정 축을 따라서 변경은 불가합니다. 이는 낙하하는 바위, 탁구공, 구슬
등에 매우 유용합니다.
표준 구콜라이더
Compound Colliders
Hints
•
폭발을 생성하려면, 수많은 드레그를 포함한 리지드바디 하나와 구 콜라이더를 여기에 추가하여, 이것이 부딪히는 벽에서 약간
밀려나오도록 하게 하면 매우 효과적입니다.
Physic Material
Physic Material 는 마찰과 충돌하는 물체의 튕기는 효과를 조정하기 위해 사용됩니다.
물리적인 재료를 생성하기 위해서 메뉴바로부터 Assets->Create->Physic Material 를 선택하세요. 씬에서 Collider 위에서 프로젝트
뷰로부터 물리적인 재료를 드래그 합니다.
물리적인 재료 Inspector
Properties
Property:
Function:
움직일 때 사용되는 마찰. 보통 0 부터 1 사이. 0 의 값은 얼음과 같고 1 의 값은 많은 힘 또는 중력이 물체를
Dynamic Friction
누르지 않는다면 그것을 매우 빠르게 휴식을 취할 것입니다.
물체가 여전히 표면위에 놓여 있을 때 사용되는 마찰. 보통 0 부터 1 사이의 값. 0 의 값은 얼음과 같고 1 의 값은
Static Friction
물체가 움직이게 하기 어려울 것입니다.
표면이 얼마나 탄력적입니까? 0 의 값은 탄력적이지 않을 것입니다. 1 의 값은 에너지의 어떠한 손실도 없이
Bouncyness
Friction Combine
탄력적일 것입니다.
두 개의 충돌하는 물체의 마찰이 어떻게 결합되는지.
Mode
Average
두 개의 마찰 값이 평균화 됩니다.
Min
두 값중 가장 작은 값이 사용됩니다.
Max
두 값은 가장 큰 값이 사용됩니다.
Multiply
마찰 값이 서로가 곱해집니다.
Bounce Combine
두 개의 충돌하는 물체의 탄력이 어떻게 결합되는지. Friction Combine Mode 와 같은 모드를 가집니다.
Friction
이방성의 방향성. 방향이 0 가 아니라면 이방성의 마찰이 활성화 됩니다. 동적인 Friction 2 와 정적인 Friction
Direction 2
2 는 Friction Direction 2 을 따라서 적용될 것입니다.
Dynamic Friction
이방성인 마찰이 활성화되면 DynamicFriction2 이 Friction Direction 2 을 따라서 적용될 것입니다.
2
Static Friction
이방성인 마찰이 활성화되면 StaticFriction2 이 Friction Direction 2 을 따라서 적용될 것입니다.
2
Details
마찰은 표면이 미끄러워지는 것을 막는 양입니다. 이 값은 물체를 쌓으려고 할 때 중요합니다. 마찰이 두 개의 형태, 동적인 그리고
정적인 형태로 나타납니다. 물체가 여전히 놓여있을 때 Static friction 이 사용됩니다. 그것은 물체가 움직이기 시작하는 것을
막습니다. 충분히 큰 힘이 물체에 적용되면 그것은 움직이기 시작할 것입니다. 이 포인트에서 Dynamic Friction 이 재생할
것입니다. Dynamic Friction 은 서로가 연락하는 동안 물체를 늦추게 하려는 시도를 할 것입니다.
Hints
•
주요 캐릭터를 위해 기본적인 물리적인 재료를 사용하지 않도록 해야 합니다. 그것을 사용자 정의하고 완벽하게 합니다.
Hi 경첩 조인트
Hinge Joint 는 개의 리지드바디(Rigidbodies)를 한 그룹으로 묶어 놓아 마치 그들이 경첩으로 연결 되어 있는 것처럼 동작하게
만듭니다. 이것은 문(doors )을 표현하기에 완벽하며, 또한 사슬, 추 등에서 사용될 수 있습니다.
경첩조인드 Inspector
속성
Property:
Function:
해당 조인트가 의존하는 리지드바이의 선택적 조회. 이 속성이 설정되지 않으면, 해당 조인트는 월드로
Connected Body
연결됩니다.
Anchor
해당 물체가 중심으로 흔드는 축의 위치, 이 위치는 로컬 공간에서 설정됩니다.
Axis
해당 물체가 중심으로 흔드는 축의 방향, 이 위치는 로컬 공간에서 설정됩니다.
Use Spring
스프링(Spring)을 사용하면 리지드바디가 자신와 연결된 문제와 대비하여 특정 각도가 될 수 있도록 하여 줍니다.
Spring
스프링의 속성으로 Spring 이 켜지면 사용됩니다.
Spring
해당 위치로 이동하기 위해 오브젝트가 사용하는 힘.
Damper
이 값이 클수록, 더 많은 오브젝트가 느려집니다.
Target
스프링의 목표 각도. 스프링은 각도의 단위로 측정된 이 각도를 향해서 당깁니다.
Position
Use Motor
모터는 오브젝트를 빙빙 돌게 합니다.
Motor
모터의 속성으로 Use Motor 가 켜지면 사용됩니다.
Target
오브젝트가 도달하려고 하는 속도.
Velocity
Force
해당 속도에 도달하기 위해 적용되어야 하는 힘.
Free Spin
이 속성이 켜지면, 해당 모터는 가속에만 사용이 되고 회전을 멈추는 데는 결코 사용되지 않습니다.
Use Limits
속성이 켜지면, 경첩의 각도가 Min & Max 값 내로 한정됩니다.
Limits
Use Limits 속성이 켜질 경우 Limits 의 속성.
Min
해당 회전이 할 수 있는 최저 각도.
Max
해당 회전이 할 수 있는 최고 각도.
Min Bounce
최소 스톱에 다다랐을 때 오브젝트가 튀어 나오는 정도.
Max Bounce
최고 스톱에 다다랐을 때 오브젝트가 튀어 나오는 정도.
Break Force
해당 조인트가 부서지기 위해 적용되어야 할 힘.
Break Torque
해당 조인트가 부서지기 위해 적용되어야 할 회전력.
상세사항
하나의 GameObject 에는 단 하나의 경첩조인트만 적용해야 합니다. 해당 경첩은 Axis 속성에서 명시한 대로 돌아다니며 Anchor
속성에서 명시된 지점에서 회전합니다. 사용자가 해당 조인트의 Connected Body 속성에 GameObject 을 할당 할 필요는 없습니다.
만일 사용자가 해당 조인트의 Transform 이 첨부된 오브젝트의 Transform 에 의존하기를 원하는 경우에만, Connected Body 속성에
GameObject 을 할당해야 합니다.
문짝의 경첩이 어떻게 동작하는지 생각하여 보십시오. 이 경우 Axis 는 Y 축을 따라 상위, 양수입니다. Anchor 는 문과 벽이 교차하는
어느 지점에 배치됩니다. 해당 조인트는 디폴트로 월드와 연결되어 있으므로, 사용자가 Connected Body 에 벽을 할당할 필요는
없습니다.
이제 애견용 문의 경첩을 생각하여 보십시오. 애견용 문의 Axis 은 가로로 되어 있고, X 축을 따라 양수입니다. 이 경우, 주 문짝이
Connected Body 로 할당 되어야 애견용 문의 경첩이 주 문짝의 리지드바디에 의거하게 됩니다.
Chains
여러 개의 경첩 조인트를 함께 연결하면 사슬을 생성할 수 있습니다. 사슬 안에서 각 연결부위에 조인트를 추가하고, 다음 연결점을
Connected Body 로 부착합니다.
Hints
•
동작을 위해 사용자의 조인트에 Connected Body 을 할당할 필요는 없습니다.
•
동적 피해 시스템을 만들려면 Break Force 을 사용하면 됩니다. 이것을 사용하면 플레이어가 로켓 발사기로 날리거나 차로
달려들어가 문짝을 경첩에서 떼어낼 수 있게 하여주는 멋진 효과를 낼 수 있게 합니다.
•
Spring, Motor, 그리고 Limits 속성을 사용하면, 사용자는 자신의 조인트의 동작을 미세 조정할 수 있습니다.
Spring Joint
Spring Joint 는 두 개의 Rigidbodies 를 그들이 하나의 스프링에 의해 연결된 것처럼 움직이게 제한하면서 함께 그룹 짓습니다.
Spring Joint Inspector
Properties
Property:
Function:
Connected Body
조인트가 의존적인 Rigidbody 로의 선택적인 레퍼런스.
Anchor
조인트의 중심을 정의하는 물체의 로컬 공간에서의 위치. 이것은 물체가 그려질 포인트는 아닙니다.
X
X 축을 따라 조이트의 로컬 센터의 위치.
Y
Y 축을 따라 조이트의 로컬 센터의 위치.
Z
Z 축을 따라 조이트의 로컬 센터의 위치.
Spring
스프링의 세기.
Damper
활성화될 때 스프링이 줄여지는 양.
Min Distance
이것보다 더 큰 거리는 스프링을 활성화되게 할 것입니다.
Max Distance
이것보다 더 적은 거리는 스프링을 활성화되게 하지 않을 것입니다.
Break Force
이 조인트가 부서지게 하기 위해 적용될 필요가 있는 힘.
Break Torque
이 조인트가 부서지게 하기 위해 적용될 필요가 있는 회전력.
Details
스프링 조인트는 하나의 Rigidbodied GameObject 가 특별한 "target" 위치를 향해 당겨지도록 합니다. 이 위치는 또다른 Rigidbodied
GameObject 또는 세계중 하나가 될 것입니다. GameObject 가 이 "target" 위치로 부터 멀리 감에 따라 Spring Joint 는 그것의 본래의
"target" 위치로 그것을 되돌릴 힘을 적용합니다. 이것은 고무총이나 고무 밴드와 매우 유사한 효과를 냅니다.
Spring 의 "target"위치는 Spring Joint 가 생성될 때 또는 플레이 모드로 들어갈 때 Connected Body (또는 세계)에 Anchor 로부터
상대적인 위치에 의해 결정됩니다. 이것은 편집기에서 조인트된 캐럭터들이나 물체들을 세팅하는 데에서 Spring Joint 를 매우
효과적으로 만들 수 있습니다. 그러나 이것은 스크립팅을 통해서 실시간으로 스프링의 행동을 밀어넣고/당기는 것을 생성하는 것은
더 어렵습니다. 사용자가 Spring Joint 를 사용해서 GameObject 의 위치를 주로 컨트롤 하려고 한다면 Rigidbody 를 가진
빈 GameObject 를 생성하고 조인트 물체의 Connected Rigidbody 가 되도록 그것을 세팅하는 것이 최고입니다. 그 후에
스크립팅에서 사용자는 Connected Rigidbody 의 위치를 바꿀 수 있고 사용자의 스프링이 사용자가 예상하는 방향으로 움직이는
것을 볼 수 있습니다.
Connected Rigidbody
사용자는 사용자의 조인트가 작동하기 위해서 Connected Rigidbody 를 사용할 필요가 없습니다. 사용자의 물체의 위치
그리고/또는 회전이 의존적이라면 사용자는 오직 한 개를 사용해야 합니다. Connected Rigidbody 가 없다면 사용자의 스프링은
세계와 연결될 것입니다.
Spring & Damper
Spring 물체를 그것의 "target" 위치를 향해 끌어오는 힘의 세기 입니다. 이것이 0 이면 물체를 당기는 힘이 없다고 스프링 조인트가
부착되지 않은 것처럼 행동할 것입니다.
Damper 는 Spring 힘에 의해 만나지는 저항력 입니다. 이것이 낮은수록 물체를 더 당길 것입니다. Damper 가 증가됨에 따라 조인트에
의한 탄력의 양은 감소될 것입니다.
Min & Max Distance
사용자의 물체릐 위치가 Min & Max Distances 사이에 떨어진다면 조인트는 사용자의 물체에 적용될 것입니다. 그 위치는 조인트가
활성화되기 위해서 이러한 값들의 밖으로 움직여야만 합니다.
Hints
•
사용자는 Connected Body 가 작동하기 위해서 사용자의 조인트에 그것을 지정할 필요는 없습니다.
•
플레이 모드로 들어가기 전에 편집기에서 사용자의 조인트된 물체의 이상적인 위치를 세팅합니다.
•
스프링 조인트는 사용자의 물체가 부착된 하나의 Rigidbody 를 가지도록 해야 합니다
Animation View Guide
Unity 의 Animation View 는 사용자가 Unity 안에서 Animation Clips 들을 직접 생성하고 변경하는 것을 가능하게 합니다. 그것은
외부의 3D 애니메이션 프로그램을 보충하거나 또는 심지어 대신 사용될 수 있게 해주는 강력하고 손쉬운 툴이 될 수 있습니다.
그것은 간단한 Animation Clip 들을 생성하기에 좋습니다. 그리고 그것은 재료 또는 구성요소의 변수들을 생기있게 할 수 있는 것의
추가된 혜택들을 가지고 있고 적기에 특정 지점에서 스크립트 함수들을 부를 수 있는 Animation Events 를 추가합니다.
외부의 프로그램으로부터 애니메이션들을 불러오는 것에 정보는 Animation import 에 관련된 페이지에서 확인할 수 있습니다.
스크립팅을 통해 캐릭터들을 움직이는 것에 대한 정보는 Animation Scripting 페이지에서 확인할 수 있습니다.
이 Animation View Guide 는 Animation View 의다른 부분들에 초점을 맞춘 다른 페이지들로 나뉘어져 있습니다. Animation View 를
사용하는 것에 대한 전반적인 지식을 확립하기 위해서 다음의 페이지들을 참고하시기 바랍니다.
Using the Animation View
이 섹션은 Animation View 을 사용하는 것에 대한 기본적인 정보를 다루고 있습니다. Animation Clips 생성과 그것들을 Animation
Mode 를 사용하여 어떻게 편집하는 지에 대한 내용을 포함하고 있습니다.
Using Animation Curves
이 섹션은 Animation View 에서 Animation Curves 를 어떻게 추가하는지를 다루고 있습니다. Animation Curves 생성,
keyframes 생성과 이동, setting WrapModes 세팅, 그리고 Animation Curves 로 할 수 있는 모든 것들에 대한 팁들을 포함하고
있습니다.
Editing Curves
이 섹션은 Animation View 에서 Animation Curves 를 직접적으로 편집하는 방법을 다루고 있습니다. 효율적인 네비게이션, keys
생성과 이동 , 그리고 tangents 와 tangent 타입들의 편집을 포함하고 있습니다.
Objects with Multiple Moving Parts
이 섹션은 다양한 움직이는 부분들을 가진 Game Objects 들을 어떻게 움직이게 하는지와 그 선택된 Game Object 를 통제할 수
있는 Animation Component 가 한 개 이상인 곳에서 어떻게 처리할 수 있는지를 다루고 있습니다.
Using Animation Events
이 섹션은 Animation Clip 으로 Animation Events 들을 어떻게 추가할 수 있는지를 다루고 있습니다. Animation Event 들은
애니메이션을 재생하는 것의 일환으로 SendMessage 와 비슷한 스크립트 함수를 부를 수 있게 합니다.
애니메이션 스크립팅 Animation Scripting
유니티의 애니메이션 시스템은 멋지게 애니메이션이 적용된 스키닝이 된 캐릭터를 만드는 것을 가능하게 해줍니다. 애니메이션
시스템은 애니메이션 블렌딩 blending, 믹싱 mixing, 가산 additive 애니메이션, 걷기사이클 시간동기화 walk cycle time
synchronization, 애니메이션 레이어, 애니메이션 재생에 관한 모든 면에서의 제어 (시간, 속도, 블렌드 웨이트 blend-weights), 버텍스
당 1, 2, 혹은 4 개 본 bone 들의 메쉬 스키닝뿐만 아니라 물리 기반의 랙돌 ragdoll 과 절차적 애니메이션 procedural animation 도
지원합니다. 가장 만족스런 결과를 얻기 위해서는 Modeling Optimized Characters 페이지의 유니티에서 최적의 성능을 내는 리깅된
캐릭터 생성을 위한 가장 좋은 방법들과 기법들에 대해 읽어 보시는 것을 추천해 드립니다.
애니메이션 캐릭터를 만드는 것은 두 가지와 관련이 있습니다: 세상에서 그들이 움직이게 만들고 그에 따라 캐릭터가 애니메이션을
하게 만드는 것 입니다. 캐릭터를 움직이는 것에 대해 더 알고 싶으시다면 다음 Character Controller page 를 참조하세요. 이
페이지는 애니메이션에 촛점을 맞추고 있습니다. 실제 캐릭터들의 애니메이션 적용은 유니티의 스크립팅 인터페이스를 통해 이루어
집니다.
이 페이지에서 기본을 익히면 animation script interface도 보시기 바랍니다.
원하신다면 이 페이지에서 다루는 아래의 주제들을 탐구해 보세요:
•
애니메이션 블렌딩 Animation Blending
•
애니메이션 레이어 Animation Layers
•
애니메이션 믹싱 Animation Mixing
•
가산 애니메이션 Additive Animation
•
절차적 애니메이션 Procedural Animation
•
애니메이션 재생과 샘플링 Animation Playback and Sampling
애니메이션 블렌딩 Animation Blending
오늘날의 게임에서 애니메이션 블렌딩 blending 은 캐릭터의 부드러운 애니메이션을 위해서 필수적인 요소입니다. 애니메이션을
만드는 사람은 각각의 애니메이션을 만듭니다. 예를 들어, 걷고, 뛰고, 쉴 때 idle 동작, 또는 사격하는 애니메이션이 있습니다. 게임
중에서는 어떤 때라도 가만히 있는 idle 애니메이션에서 걷는 애니메이션 또는 반대로 바꿀 수가 있어야 합니다. 물론 사용자는
움직임이 갑작스레 튀지 않고 부드럽게 전환되는 애니메이션을 원할 것입니다.
이때 필요한 것이 바로 애니메이션 블렌딩입니다. 유니티에서는 하나의 같은 캐릭터에 어떤 수의 애니메이션도 넣을 수가 있습니다.
모든 애니메이션들은 최종 애니메이션을 만들기 위해 서로 섞여지거나 더해집니다.
사용자가 할 첫 스텝은 캐릭터를 가만히 쉬는 애니메이션에서 걷는 애니메이션으로 부드럽게 전환하는 것입니다. 스크립트 작성시
작업을 쉽게 하기위해 애니메이션의 랩 모드 Wrap Mode 를 `반복 `Loop 으로 설정합니다. 그리고 사용자가 만드는 스크립트가
애니메이션이 재생되는 유일한 것이 되게 자동으로 재생되게 Play Automatically`` 를 꺼놓습니다.
캐릭터를 동작시키기 위한 첫 스크립트는 꽤 간단한 편입니다. 사용자가 알아야 할 것은 단지 캐릭터가 얼마나 빨리 움직이는지
감지할 방법과 걷는 애니메이션과 쉬는 애니메이션 사이에 녹아들어 사라지게 합니다. 이 간단한 테스트를 위해서 미리 설정된 입력
축들 input axes 을 사용합니다.
function Update () {
if (Input.GetAxis("Vertical") > 0.2)
animation.CrossFade ("walk");
else
animation.CrossFade ("idle");
}
이 스크립트를 실행하기 위해서는:
1.
Assets->Create Other->Javascript 를 이용해 자바 스크립트 Javascript 를 만듭니다.
2.
그 안에 코드를 복사 & 붙여넣기를 합니다
3.
스크립트를 캐릭터로 드래그하세요 (그것은 애니메이션과 같은 게임 오브젝트여야 합니다)
사용자가 재생 Play 버튼을 누르고, 위방향키를 누르고 있으면 캐릭터가 걷기 시작하고 손가락을 떼면 쉬는 포즈로 돌아갈 것입니다.
애니메이션 레이어 Animation Layer
레이어는 사용자가 애니메이션을 그룹화하고 가중치 weighting 에 우선 순위를 매기는 것을 가능하게 해주는 굉장히 중요한
개념입니다.
유니티 애니메이션 시스템에서 사용자는 원하는 만큼 애니메이션 클립들을 서로 블렌드 할수 있습니다. 사용자는 수동으로
가중치를 주거나 간단히 자동으로 가중치를 주는 animation.CrossFade()를 이용할 수 있습니다.
블렌드 가중치는 적용되기 전에 항상 정규화됩니다 Blend weights are always normalized before being applied.
걷는 것과 뛰는 애니메이션이 있고 둘 모두 1 (100%) 의 가중치를 가진다고 가정해 보세요. 유니티가 최종 애니메이션을 생성할 때
가중치를 정규화 합니다. 즉 걷는 것과 뛰는 애니메이션이 50%씩의 가중치를 각각 부여하게 되는 것입니다.
하지만 대부분의 경우 사용자는 두 개의 애니메이션이 있을 때 어떤 애니메이션이 더 가중치를 적용받을지 우선 순위를 정하길
원합니다. 물론 이때 모든 가중치의 합이 수동으로 100%가 되도록 할 수도 있겠지만 레이어들을 사용하는 것이 훨씬 쉬운 방법이
됩니다.
레이어만들기 예제 Layering Example
한 예로써 사용자가 사격하고, 쉬고, 그리고 걷는 애니메이션이 있다고 가정합니다. 걷는 애니메이션과 쉬는 애니메이션은
플레이어의 속도에 따라 블렌드되어 섞이겠지만, 사격 버튼이 눌러졌을때는 사격하는 애니메이션만이 나와야 합니다. 그러므로
사격 애니메이션은 이들 중 더 높은 우선 순위를 가지게 됩니다.
이것을 위한 가장 쉬운 방법은 사격 중에도 걷고 쉬는 애니메이션을 재생하게 하는 것입니다. 그러기 위해서는 사격 애니메이션을
쉬거나 걷기 보다 높은 레이어로 위치시켜야 하고 이것은 사격 애니메이션이 블렌드 가중치 blend weights 를 가장 우선 순위로 받게
된다는 뜻입니다. 걷기와 쉬기 애니메이션은 사격 애니메이션이 100% 블렌드 가중치를 다 사용하지 않을 때에만 가중치를 받게
됩니다. 그래서 크로스페이딩 CrossFading 으로 사격 애니메이션을 걷기나 쉬기 애니메이션 안에 들여보낼 때 사격 애니메이션의
가중치는 0 에서 시작해 짧은 순간에 100%로 가중치가 변할 것입니다. 처음에 걷기와 정지레이어는 블렌드 가중치를 받지만 사격
애니메이션이 완전히 들어오면 (fade in) 가중치를 전혀 받을 수 없게 될 것입니다. 이것은 정확히 우리가 원하던 바입니다!
function Start () {
// 모든 애니메이션을 룹으로 설정
animation.wrapMode = WrapMode.Loop;
// 사격은 제외
animation["shoot"].wrapMode = WrapMode.Once;
// 쉬기와 걷기를 아래 레이어로 놓습니다. (디폴트 레이어는 항상 0)
// 이것은 두 가지를 할 것입니다.
// - 사격과 쉬기/걷기는 다른 레이어에 있으므로,
//
크로스페이드 CrossFade 를 호출할 때 그들은 서로의 재생에 영향을 끼치지 않을 것입니다
// - 사격은 더 높은 레이어에 있으므로,
// 페이드-인 (fade-in) 할때 그 애니메이션은 쉬기/걷기 애니메이션을 대체할 것입니다.
animation["shoot"].layer = 1;
// 이미 재생되는 애니메이션을 정지시킵니다.Stop animations that are already playing
//(사용자가 자동재생을 비활성화 시켰을 경우)
animation.Stop();
}
function Update () {
// 눌려진 키에 따라서,
// 걷기나 쉬기 애니메이션을 재생합니다.
if (Mathf.Abs(Input.GetAxis("Vertical")) > 0.1)
animation.CrossFade("walk");
else
animation.CrossFade("idle");
// Shoot
if (Input.GetButtonDown ("Fire1"))
animation.CrossFade("shoot");
}
기본 설정으로 animation.Play()나 animation.CrossFade() 는 같은 레이어에 있는 애니메이션을 정지시키거나 사라지게 fadeout 합니다. 이것이 대부분의 경우 이것은 사용자가 원하는 바입니다. 위의 우리의 예제에서는 쉬기/걷기는 사격 애니매이션에
영향을 주지 않으며 그 반대의 경우도 마찬가지 입니다 (원한다면 animation.CrossFade 의 옵션 파라미터에서 이 것을 바꿀 수
있습니다).
애니메이션 믹싱 Animation Mixing
애니메이션 믹싱은 애니메이션을 몸의 어떤 일 부분에만 적용시켜 게임에서 생성해야 하는 애니메이션의 수를 줄여줍니다. 이것은
그런 애니메이션들이 다른 애니메이션들과 여러 조합으로 이루어져 사용될 수 있다는 뜻입니다.
사용자는 주어진 애니메이션상태 AnimatioState 에 AddMixingTransform()을 호출하여 애니메이션 믹싱 트랜스폼 animation
mixing transform 을 다른 애니메이션에 더합니다.
믹싱 예 Mixing Example
믹싱의 한 예로는 손을 흔드는 애니메이션이 있습니다. 사용자는 캐릭터가 쉬거나 걸을 때 이 손 흔드는 애니메이션을 사용하길
원합니다. 애니메이션 믹싱이 없다면 사용자는 걸으며 손 흔드는 것 쉬면서 손흔드는 두개의 애니메이션을 만들어야 할 것입니다.
그러나 만약 사용자가 손 흔드는 애니메이션에 어깨 트랜스폼을 믹싱 트랜스폼으로써 추가하면, 손 흔드는 애니메이션은 어깨
조인트에서 손까지는 완전히 제어할 수 있게 될 것입니다. 나머지 몸은 그것에 의해 영향을 받지 않기 때문에 캐릭터는 쉬거나 걷는
애니메이션을 계속할 것입니다. 그러므로 몸의 나머지 부분이 쉬거나 걷는 동안에 손이 흔들리게 하려면 위와 같은 단 하나의
애니메이션 만이 필요하게 됩니다.
/// 트랜스폼 변수를 사용하여 믹싱 트랜스폼을 더합니다.
var shoulder : Transform;
animation["wave_hand"].AddMixingTransform(shoulder);
경로 path 를 이용한 또 다른 예.
function Start () {
// 경로를 이용하여 믹싱 트랜스폼을 더합니다.
var mixTransform : Transform = transform.Find("root/upper_body/left_shoulder");
animation["wave_hand"].AddMixingTransform(mixTransform);
}
부가 애니메이션 Additive Animations
부가 애니메이션 Additive animation 과 애니메이션 믹싱은 게임을 위해 생성해야 하는 애니메이션 수를 줄이는 것을 줄이고,
얼굴표정 facial 애니메이션을 만드는데 중요한 역할을 합니다.
사용자가 걷거나 뛰면서 방향을 돌때 옆으로 기우는 캐릭터를 만든다고 가정해 봅시다. 이 경우 각각 애니메이션이 필요한 다음과
같은 네가지 조합이 필요하게 됩니다: 왼쪽으로 기울며 걷기 walk-lean-left, 오른쪽으로 기울며 걷기 walk-lean-right, 왼쪽으로 기울며
뛰기 run-lean-left, 오른쪽으로 기울며 뛰기 run-lean-right. 각 조합을 위해 각각 별개의 애니메이션을 만드는 것은 이와 같은 간단한
경우에도 훨씬 더 많은 추가 작업을 시키게 되고, 다른 액션들이 추가될 때마다 조합의 수는 기하급수적으로 늘어날 것입니다.
다행히도 가산 애니메이션 additive animation 과 믹싱은 단순 움직임들의 조합을 위해 각각 따로 애니메이션을 만들어야 하는
번잡함을 줄여 줍니다.
가산 애니메이션의 예 Additive Animation Example
가산 애니메이션은 한 애니메이션의 효과를 재생중인 다른 애니메이션들 위에 겹치게 overlay 합니다. 가산 애니메이션을 만들때
유니티는 애니메이션 클립의 첫번째 프레임과 현재 프레임의 차이를 계산할 것입니다. 그리고 이 차이를 다른 모든 재생 중인
애니메이션 위에 적용합니다.
다시 아까의 예로 돌아가서 이제 사용자는 왼쪽이나 오른쪽으로 기운 애니메이션을 만들면 유니티는 이것을 걷거나 쉬거나 뛰는
동작의 애니메이션 위에 상위 레이어로 놓을 수 있습니다.
이것을 만들기 위한 코드입니다:
private var leanLeft : AnimationState;
private var leanRight : AnimationState;
function Start () {
leanLeft = animation["leanLeft"];
leanRight = animation["leanRight"];
//기우는 애니메이션 lean animation 을 별개의 레이어에 놓아서,
//CrossFade 를 호출하는 다른 것들이 그것에 영향을 주지 않도록 합니다.
leanLeft.layer = 10;
leanRight.layer = 10;
//기우는 애니메이션을 가산 additive 으로 설정합니다.
leanLeft.blendMode = AnimationBlendMode.Additive;
leanRight.blendMode = AnimationBlendMode.Additive;
//기우는 애니메이션을 ClampForever 로 설정합니다.
//ClampForever 가 설정되면 애니메이션은 클립의 끝에 도달해도
//자동적으로 정지되지 않습니다.
leanLeft.wrapMode = WrapMode.ClampForever;
leanRight.wrapMode = WrapMode.ClampForever;
//애니메이션을 활성화 Enable 하고 그것을 완전히 들어오게 fade in 합니다.
//여기서 사용자는 animation.Play 를 사용하지 않습니다. 왜냐하면
//그것은 업데이트 함수에서 시간을 수동적으로 조절할 수 있기 때문입니다.
//대신에 사용자는 그냥 애니메이션을 활성화시키고, 그것을 최대 가중치 weight 로 설정합니다.
leanRight.enabled = true;
leanLeft.enabled = true;
leanRight.weight = 1.0;
leanLeft.weight = 1.0;
//테스트를 위해서 걷기 애니메이션을 재생한 후 반복 Loop 을 시킵니다.
animation["walk"].wrapMode = WrapMode.Loop;
animation.Play("walk");
}
//모든 프레임을 정규화된 normalized 시간으로 설정합니다.
//사용자가 적용시키기 원하는 정도에 따라서 말입니다.
function Update () {
var lean = Input.GetAxis("Horizontal");
// normalizedTime 은 첫 프레임때는 0 이고 클립의 마지막 프레임에는 1 이 됩니다.
leanLeft.normalizedTime = -lean;
leanRight.normalizedTime = lean;
}
팁:가산 애니메이션을 사용할 때 사용자가 가산 애니메이션과 함께 사용된 모든 트랜스폼 위에 가산이 아닌 다른 일반
애니메이션들도 같이 재생하는 것은 굉장히 중요합니다. 그렇지 않으면 그 애니메이션들은 마지막 프레임의 결과 위에 추가되
얹혀질 것입니다. 이것은 확실히 사용자가 원하는 바가 아닐 것입니다.
순차적으로 캐릭터 애니메이션화 하기 Animating Characters Procedurally
사용자는 가끔 캐릭터의 본 bone 을 순차적으로 애니메이션 만들기를 원합니다. 예를 들어, 사용자는 3D 공간에서 캐릭터의 머리가
목표점을 추적하는 스크립트에 의해 조정되어 어느 한 점을 바라보기를 원합니다. 다행히도 유니티에서 본 bone 들은 그 스킨된
메쉬를 움직이는 트랜스폼일 뿐이기에 유니티는 이것을 매우 쉽게 할 수 있습니다. 사용자는 스크립트를 써서 어떤 게임오브젝트의
트랜스폼을 다루듯 캐릭터의 본들도 제어할 수 있는 것입니다.
한가지 중요하게 알아야 할 것은 애니메이션 시스템은 Update() 함수 후에 그리고 LateUpdate() 함수 전에 트랜스폼들을 업데이트
한다는 것입니다. 그러므로 만약 사용자가 LookAt() 함수를 사용하고 싶다면 사용자는 사용자가 정말로 애니메이션을 오버라이딩
override 하는 것을 확실히 하기 위해 그 함수를 LateUpdate() 안에서 해야만 합니다.
랙돌 Ragdoll 들도 같은 방법으로 생성됩니다. 사용자는 단지 강체 Rigidbodies, 캐릭터 조인트 Character Joints 그리고 캡슐 충돌체
Capsule Colliders 들을 다른 본들에 붙여주기만 하면 됩니다. 그럼 이것은 사용자의 스킨된 캐릭터를 물리적으로 애니메이션화 하게
됩니다.
애니메이션 플레이백과 샘플링 Animation Playback and Sampling
이 섹션은 유니티에서 애니메이션들이 엔진에 의해 재생될 때 어떻게 샘플링이 되는지 설명해 줍니다.
애니메이션 클립 AnimationClips 들은 보통 고정된 프레임 비율로 만들어 집니다. 예를 들어, 사용자는 3D 맥스나 마야에서 프레임
속도 60fps (frames per second) 의 애니메이션을 만들수 있습니다. 유니티에서 그 애니메이션을 불러올 때 이 프레임 속도는 임포터
importer 에 의해 읽히게 되어 불려온 애니메이션의 데이타도 60 fps 로 샘플링 됩니다.
하지만 게임은 일반적으로 다양한 프레임 속도로 실행됩니다. 프레임 속도는 어떤 컴퓨터에서는 다른 컴퓨터에서보다 더 높을 수
있고, 특정 순간에 카메라가 보고 있는 뷰의 복잡도에 따라 1 초부터 수 초까지 또 다양한 결과를 냅니다. 기본적으로 이것은 게임이
실행되고 있는 프레임의 정확한 속도에 관해 우리는 어떤 가정도 만들수 없다는 것을 의미합니다. 즉 애니메이션이 60 fps 로 만들어
졌어도 이것은 56.72 fps 나 83.14 fps 혹은 어떤 다른 fps 속도로도 재생될지 모르는 것입니다.
그래서 그 결과로, 유니티는 애니메이션을 원래 지정되어진 프레임 속도가 아닌 이런 다양한 속도로 샘플링을 하게 됩니다. 다행히도
3D 컴퓨터 그래픽 애니메이션은 개별적으로 분리된 프레임이 아닌 연속적인 커브 curve 로 이루어져 있습니다. 이런 커브들은
원래의 애니메이션의 프레임들의 시간들에 딱딱 들어맞는 것이 아니라 어떤 시간에나 샘플링 될 수 있게 되어 있습니다. 그래서
실제적으로는 만약 게임이 만들어진 것보다 더 높은 프레임 속도로 실행이 될 경우 애니메이션은 애니메이션이 제작된
소프트웨어에서보다 더 부드럽고 유연하게 보일 것입니다.
가장 실제적인 상황에서는 사용자는 유니티가 애니메이션을 다양한 프레임 속도 variable fps 로 샘플을 한다는 것은 무시해도
좋습니다. 하지만 만약 사용자가 트랜스폼이나 속성을 어떤 아주 특정한 설정으로 애니메이트하는 애니메이션들에 의지하는
게임플레이 로직을 가지고 있다면, 사용자는 재샘플링 resampling 이 보이지 않는 곳에서 일어난다는 것을 알고 있어야 합니다. 예를
들어, 만약 사용자가 30 프레임에 걸쳐 객체가 0 에서 180 도로 회전하는 애니메이션을 가지고 있고 그리고 그것이 언제 중간까지
도달했는지 코드에서 알고 싶다면, 사용자는 현재 회전 각도가 90 도인지 체크하는 조건문을 만들어서 확인하면 안됩니다. 유니티는
애니메이션을 게임속의 다양한 프레임 속도로 샘플링을 하므로, 회전이 90 도가 조금 안될때 샘플링을 하고 나중에는 90 도 바로
이후에 할지도 모릅니다. 만약 사용자가 애니메이션에서 어떤 특정 점에 다다랐을 때 알림 받기를 원한다면 AnimationEvent 를
이용해야 합니다.
또한 다양한 프레임 속도의 샘플링의 결과로 WrapMode.Once 를 사용한 애니메이션이 재생될 때 정확히 마지막 프레임에서
샘플링되지 않을 수도 있다는 것에 주의하세요. 게임의 한 프레임에서는 애니메이션의 마지막 바로 전에 샘플되고, 다음
프레임에서는 시간이 애니메이션의 길이를 초과해 버려 비활성화되고 더 이상 샘플링이 되지 않을지도 모릅니다. 만약 마지막
프레임이 반드시 샘플링이 되게 해야한다면 WrapMode.ClampForever 를 사용해야 합니다. 이 경우 사용자가 애니메이션을 직접
멈출때까지 마지막 프레임 샘플링을 계속 할 것입니다.
Audio Listener
Audio Listener 는 마이크로폰같은 장치처럼 작동합니다. 그것은 씬에서 어떠한 주어진 Audio Source 로부터 입력을 받아 컴퓨터
스피커를 통해서 소리를 재생합니다. 대부분의 응용 프로그램을 위해서 Main Camera 에 리스터를 부착하기 하는 것이 가장
적합합니다. 오디오 리스너가 Reverb Zone 의 범위에 있다면 반향은 그 씬의 모든 들리는 소리에 적용됩니다(오직 PRO 만). 게다가,
Audio Effects 는 리스너에 적용될 수 있고 그 씬의 모든 들리는 소리에 적용될 것입니다.
Main Camera 에 부착된 Audio Listener
Properties
Audio Listener 는 속성을 가지지 않습니다. 그것은 단순히 작업에 추가되어야 하고 기본적으로 Main Camera 에 추가되어야 합니다.
Details
Audio Listener 는사용자가 그의 게임을 위한 청각 경험을 만드는 것을 허용하면서 Audio Sources 와 함께 작동합니다. Audio
Listener 가 사용자의 씬에서 GameObject 에 부착되면 그 Listener 충분히 가까이에 있는 어떠한 소스라도 선택될 것이고 컴퓨터
스피커로 결과를 만들어 보낼 수 있을 것입니다. 각 씬은 제대로 작동하기 위해서 오직 1 개의 Audio Listener 만을 가질 수 있습니다.
소스들이 3D (Audio Clip 의 import settings 를 참고하십시요)라면, 그 리스너는 위치와 속도 그리고 3D 세계에서 소리의 방향을
에뮬에이션할 것입니다(사용자는 Audio Source 에서 자세히 3D/2D 의 행동과 감쇠를 조정할 수 있습니다.). 2D 는 어떠한 3D 처리도
무시할 수 있습니다. 예를 들어, 사용자의 캐릭터가 나이트 클럽안으로의 길을 산책한다면, 그 나이트 클럽의 음악은 아마도 2D 일
것이며 반면 클럽안의 캐릭터들의 개별적인 소리들은 Unity 에 의해 처리되고 있는 그들의 현실적인 위치에 따라 단선율일 것입니다
사용자는 Audio Listener 를 Main Camera 나 혹은 플에이어를 나타내는 Game Object 에 부착해야 합니다. 어떠한 것이 사용자의
게임을 위해서 최상인지 찾도록 노력해야 합니다.
Hints
•
각 씬은 오직 한 개의 Audio Listener 를 가질 수 있습니다.
•
사용자는 Audio Manager 를 사용해서 Edit->Project Settings->Audio 에 있는 project-wide audio 세팅에 접근할 수 있습니다.
•
Mono vs Stereo 소리에 대한 자세한 정보는 Audio Clip 페이지를 참고하시기 바랍니다.
음향 소스
Audio Source 는 장면(scene)에서 Audio Clip 을 재생합니다. 만일 해당 음향 클립이 3D 클립이라면, 해당 소스는 주어진 위치에서
거리 감쇄를 적용하며 재생될 것 입니다. 음향은 여러 개의 스피커 사이에 분배 할 수 있고 (스테레오에서 7.1 까지) (Spread) 3D 와
2D 사이를 자연스럽게 변환합니다 (PanLevel). 이것은 감쇠 궤도(falloff curves)로 원 거리에서 제어 가능합니다. 또한 청취자
(listener) 1 개 혹은 다수의 에코존 Reverb Zones 에 있다면 소스에 그 반향이 적용됩니다. (Pro 만 지원) 더욱 풍부한 음향 효과를
위하여 각 필터는 각각의 음향 소스에 적용할 수 있습니다. 추가 정보를 보려면 Audio Effects 를 참조하십시요
inspector 내 Scene View 와 그 설정에서의 음향소스 기즈모''
속성
Property:
Audio Clip
Mute
Bypass Effects
Function:
재생되는 음향 클립파일의 참조.
이 속성이 켜지면, 음향이 음소거 상태에서 재생됩니다.
음향 소스에 적용된 필터 효과를 “우회” 하기 위한 속성. 모든 효과를 켜고 끄는 손쉬운 방법입니다.
이 속성이 켜지면, 장면(scene)이 시작하는 순간 음향이 재생됩니다. 이 속성이 꺼지면, 사용자가 스크립트에서
Play On Awake
Loop
Play() 명령을 통해서 시작하여야 합니다.
속성을 켜면 Audio Clip 이 끝나면 룹을 계속합니다.
장면(scene)에 공존하는 모든 음향 소스의 속성을 결정합니다. (Priority: 0 = 가장 중요. 256 = 가장 중요하지 않음.
Priority
초기값 = 128)
Volume
Audio Listener 로터 1 세상 단위(1 미터)가 떨어질 때마다 얼마나 음량이 큰가를 정합니다.
Pitch
Audio Clip 의 속도 저하/향상으로 인한 피치의 변화 량. 값 1 은 일반적인 재생 스피드를 나타냅니다.
3D Sound
음향이 3D 음향일 경우 적용되는 오디오 소스의 설정.
Settings
Pan Level
Spread
Doppler Level
3D 엔진이 음향 소스에 가지는 효과 량을 정합니다.
스피커 공간에서 3D 스테레오나 다중 채널로 확산 각도를 정합니다.
음향 소스에 도플러 효과를 얼마나 많이 적용할 것인가를 정합니다. (0 이라면, 효과 적용 없음).
MinDistance 내에서, 음향은 가능한 최고 음량을 유지합니다. MinDistance 밖에서는, 감쇄하기 시작합니다. 3D
Min Distance
세계에서는 더 소리를 크게 하기 위하여 MinDistance 을 증가하고, 더 조용하기 하기 위해서는 MinDistance 을
감소합니다.
소리의 감쇄가 멈추는 거리. 이 지점 너머에서는 음량이 청취자로부터 MaxDistance 단위의 음량으로 유지되며 더
Max Distance
이상 감쇄되지 않습니다.
음향이 얼마나 빨리 사라지는지를 표시. 이 값이 클수록 소리를 듣기 전에 청취자는 가까운 거리에
Rolloff Mode
Logarithmic
있습니다.(그래프에 의해 결정)
음향 소스에 가까우면 소리는 커지고, 오브젝트에서 멀어지면 아주 빠른 속도로 사라집니다.
Rolloff
Linear Rolloff
음향 소스에서 멀어질수록, 사용자는 덜 듣게 됩니다.
음향 소스로부터의 소리는 롤오프(roll off) 그래프 설정에 따라 동작합니다.
Custom Rolloff
2D Sound
3D 음향일 경우 음향 소스에 적용되는 설정.
Settings
Pan 2D
엔진이 음향 소스에 미치는 효과를 설정.
롤오프(Rolloff) 타입
롤오프(Rolloff)에는 다음 세 가지 모드가 있습니다: 대수적(Logarithmic), 직선적(Linear) 그리고 맞춤 롤오프(Custom Rolloff)가
있습니다. 맞춤 롤오프는 음량 거리 궤도(volume distance curve)를 수정하여 변경할 수 있습니다. 대수적(Logarithmic) 혹은
직선적(Linear) 모드에서 사용자가 음량 거리 함수를 수정하려고 하면, 해당 당입은 자동으로 맞춤 롤오프 타입으로 전환됩니다.
음향 소스가 가질 수 있는 롤오프 모드
거리 함수
음향이 가질 수 있는 속성 중 오디오소스와 오디오 청취자 사이의 거리함수로 변경될 수 있는 것이 몇 가지 있습니다.
Volume: 거리에 따라 Amplitude(0.0 - 1.0).
Pan: 거리에 따라 Left(-1.0) to Right(1.0).
Spread: 거리에 따라 Angle (degrees 0.0 - 360.0).
Low-Pass (LowPassFilter 가 AudioSource 에 부착된 경우에만 적용): 거리에 따라 Cutoff Frequency (22000.0-10.0).
음량, Pan, Spread 와 Low-Pass 음향 필터를 위한 거리 함수. 오디오 청취자까지의 현재 거리는 그래프에 표시되어 있습니다.
거리함수를 수정하려면, 궤도를 바로 편집하여야 합니다. 추가 정보를 보려면 Editing Curves 가이드를 참조하세요.
음향 소스 생성
음향 소스는 할당된 Audio Clip 이 없이는 아무 작동도 하지 않습니다. 클립은 재생을 위한 실제 음향 파일입니다. 소스란 그 클립을
정지하고 재생하고 시작하고 오디오 속성을 변경하기 위한 제어기 같은 것 입니다.
새로운 음향 소스를 생성하려면:
1.
사용자의 유니티 프로젝트에 음향 파일을 들여옵니다.
2.
메뉴바에서 GameObject->Create Empty 를 선택합니다.
3.
새로운 GameObject 를 선책하고 Component->Audio->Audio Source 를 선택합니다.
4.
청취자(listener)의 해당 음향 소스 컴포넌트에 Audio Clip 속성을 할당합니다.
주의: 사용자의 에셋 폴더에 있는 Audio Clip 에 대한 음향 소스만 생성하고 싶다면, 사용자는 그 Audio Clip 을 장면뷰(scene
view)로 단지 드래그 하면, 그 소스에 해당하는 Audio Source 게임 오브젝트가 자동 생성 됩니다.
플랫폼 특정 사항
iOS
모바일 플랫폼에서는 음향 압축은 빠른 압축 해제를 위하여 MP3 로 인코딩 됩니다. 이 압축은 클릭의 마지막에 샘플링을 하므로
"perfect-looping"의 클립을 훼손 할 가능성이 있습니다. 해당 클립이 MP3 특정 샘플링의 경계점에 있음을 확인하여야 합니다
(이것을 위한 도구는 손쉽게 구할 수 있습니다). 성능향상을 위하여, 음향 클립은 애플의 하드웨어 코덱을 사용하여 재생할 수
있습니다. 이 기능을 사용하려면, 들여오기 설정에서 "Use Hardware" 체크박스를 체크하여야 합니다. 더 자세한 내용을 보려면
Audio Clip 문서를 참조하시기 바랍니다.
Android
모바일 플랫폼에서는 더 빠른 압축해제를 위하여 압축음향은 MP3 으로 인코딩 되어 있습니다. 이 압축은 클릭의 마지막에 샘플링을
하므로 "perfect-looping"의 클립을 훼손 할 가능성이 있습니다. 해당 클립이 MP3 특정 샘플링의 경계점에 있음을 확인하여야 합니다
(이것을 위한 도구는 손쉽게 구할 수 있습니다).
오디오 클립 Audio Clip
오디오 클립 Audio Clips 은 오디오 소스에 의해 사용되는 오디오 데이터 입니다. 유니티는 모노, 스테레오 그리고 멀티 (최대 8)
채널 오디오 에셋들을 지원합니다. 유니티는 다음의 오디오 파일 포맷들을 불러오기 importing 지원합니다 : .aif, .wav, .mp3,
와 .ogg, 그리고 다음의 tracker module file formats: .xm, .mod, .it, and .s3m. 트래커 모듈 에셋들의 경우 파형 미리보기 (waveform
preview)가 에셋 불러오기 인스펙터(asset import inspector)에서 렌더링 되지 않는다는 것 외에는 유니티에 있는 모든 다른 오디오
에셋들과 같은 방식으로 작동합니다.
오디오 클립인스펙터
속성 Properties
Property:
Function:
Audio Format
실행시 소리를 위해 사용될 특정 포맷.
Native
파일 용량이 클수록 더 높은 퀄리티. 매우 짧은 음향 효과에 최적.
Compressed
파일이 작을 수록 더 낮고 변동(variable)이 많은 퀄리티. 중간 길이의 사운드 이펙트나 음악에 최적.
3D Sound
활성화되면, 소리가 3D 공간에서 재생됩니다. 모노와 스테레오 사운드 둘 다 3D 로 재생될 수 있습니다.
Force to mono 활성화되면, 오디오 클릭은 하나의 채널 사운드로 다운믹스 down-mix (여러 개가 더 적은 수로 믹스) 될 것입니다.
Load Type
유니티가 실행시 오디오 에셋을 로드하는 방법.
로드할 때 사운드 압축을 풉니다(decompress). 즉석 비압축 decompressiong 으로 인한 성능의 오버헤드를 피하기
Decompress on 위해서 더 작은 압축 사운드들에 이것을 사용합니다. 로딩시 사운드 압축풀기는 그것을 메모리에 압축된 채로
load
놔두는 것보다 10x 정도 더 많은 메모리를 사용한다는 것을 주의하셔야 합니다. 그러므로 커다란 파일들에는
이것을 사용하지 마시길 바랍니다
Compressed in 사운드를 메모리에 압축된 채로 두었다가 재생시 압축을 풉니다. 이것은 약간의 성능에 오버헤드가 (특히
memory
Ogg/Vorbis 압축파일들에) 가해집니다. 그러므로 이것은 오직 더 큰 파일들에만 사용하세요.
오디오 데이터를 디스크로 부터 직접 스트림 stream. 이것은 메모리의 본래 사운드 사이즈의 약간을 사용합니다.
Stream from
disc
사용자의 음악 또는 매우 긴 트랙을 위해서 사용하세요. 하드웨어에 따라서 일반적으로 이것을 1 개에서 2 개의
동시간 simultaneous 스트림 정도로 적은 수로 유지하는 것이 낫습니다.
압축 compress 된 클립에 적용되는 압축의 양. 파일 사이즈에 대한 통계는 슬라이더 아래에 나타납니다.
Compression
슬라이더는 사용자의 파일 크기/배포의 요구사항에 적합한 작은 사이즈면서도 재생이 충분히 ‘’괜찮은’’ 곳에 그
슬라이더를 가져다 놓는 것이 좋습니다.
(오직 iOS 에서만) iOS 장치 위에서 압축된 오디오에 사용가능. CPU 소모적 비압축 (intensive decompression)을
Hardware
Decoding
완화시키기 위해서 애플의 하드웨어 디코더를 사용합니다. 더 많은 정보를 위해서 특정 플랫폼 관련 내용을
살펴보세요.
(오직 Android 와 iOS 에서만) 룹 Loop (반복재생) 을 지속시키기 위해 완벽히 룹핑 looping 이 되는 (압축되지 않은
Gapless
looping
PCM 포맷에서의) 오디오 소스 파일을 압축할 때 이것을 사용합니다. 스탠다드 MPEG 인코더는 룹 포인트 주변에 작은
“클릭” 이나 “팝”으로 재생되는 조용한 무음이 있는데 유니티는 사용자를 위해 이것을 매끄럽게 처리합니다.
오디오 에셋들을 불러오기 Importing Audio Assets
유니티는 압축 compressed 또는 네이티브 native 오디오를 둘다 지원합니다. MP3/Ogg Vorbis 를 제외하고는 어떤 파일 타입이던
처음에는 네이티브로 불려오게 됩니다. 압축된 오디오 파일은 게임이 실행되고 있는 동안 CPU 에 의해 압축이 풀려야 하기는 하나
파일 사이즈에서는 더 작습니다. 스트림 stream 이 체크되면 오디오는 즉시 압축이 풀리게 되나 (decompressed) 그렇지 않을 경우
로딩할때만 완전히 압축이 풀리게 됩니다. 네이티브 PCM 포맷 (WAV, AIFF)은 CPU 에 부담을 증가시키는 것 없이 더 높은 완성도를
가지는 장점이 있으나 훨씬 더 큰 파일을 생성한다는 단점이 있습니다. 모듈 파일들 (.mod,.it,.s3m..xm)은 굉장히 적은 사용공간을
사용하면서도 매우 높은 퀄리티를 제공합니다.
일반적인 규칙에 따라서 압축된 오디오(또는 모듈)은 배경 음악이나 대화같은 긴 파일들에 가장 좋고 무압축 uncompressed 된
것들은 짧은 사운드 이펙트에 더 좋습니다. 압축 Compression 슬라이더로 압축의 양(amount)을 사운드 퀄리티의 차이가 눈에 띄기
바로 전 정도로 조절합니다.
3D 오디오 사용하기 Using 3D Audio
오디오 클립이 3D 사운드로 표시 mark 되면 그것은 게임 환경 3D 공간에서의 위치를 시뮬레이션 하기 위해 재생될 것입니다. 3D
사운드는 스피커를 따라서 볼륨 volume 과 패닝 panning (왼쪽과 오른쪽 스피커의 음량 조절)을 약하거나 강하게 조절하는 것에
의해 소리의 거리와 위치를 모방 emulation 하게 됩니다. 모노와 멀티 채널 사운드 둘 다 3D 에 위치시킬 수 있습니다. 멀티 채널
오디오를 위해서 스피커 공간에서 분리된 개별 채널을 펼치고 나누기 위해서 오디오 소스 Audio Source 의 ’스프레드’ 옵션을
사용하세요. 유니티는 3D 공간에서 오디오 행동을 제어하고 미세조정하기 위한 다양한 옵션들을 제공합니다. 오디오 소스를
살펴보시기 바랍니다.
플랫폼별 상세정보 Platform specific details
iOS
모바일 플랫폼에서 압축된 오디오는 더 적은 CPU 소모적 압축풀기 (intensive decompression)을 위해서 MP3 로 인코드 됩니다.
성능상의 이유로 오디오 클립은 애플 하드웨어 코덱을 사용해서 재생될 수 있습니다. 이것을 활성화하기 위해서는 오디오 불러오기
Audio Importer 에서 "하드웨어 디코딩 Hardware Decoding" 체크박스를 클릭해 주세요. 배경에서 실행중인 iPod 오디오를 포함해 한
번에 오직 한 개의 하드웨어 오디오 스트림만이 비압축 decompression 가능합니다.
하드웨어 디코더를 사용 가능하지 않다면 압축풀기는 소프트웨어 디코더에게로 돌아갈 것입니다 (iPhone 3GS 나더 새로운 애플의
소프트웨어에서 디코더가 유니티의 (FMOD) 디코더보다 더 우선적으로 사용됩니다).
Android
모바일 플랫폼에서 압축된 오디오는 보다 적은 CPU 소모적 압축풀기를 위해서 MP3 로 인코드 됩니다.
게임 인터페이스 요소들 Game Interface Elements
유니티는 사용자가 제작하는 게임의 그래픽 사용자 인터페이스 Graphic User Interface (GUI) 를 생성하기 위한 여러가지 다양한
옵션을 제공합니다. 사용자는 씬 Scene 에서 GUI Text 와 GUI Texture 객체들을 사용할 수도 있고 또는 유니티 GUI UnityGUI 를
사용하여 스크립트로부터 인터페이스를 생성할 수도 있습니다.
이 페이지 나머지 부분에는 UnityGUI 를 시작하고 실행하는 것에 대한 자세한 가이드 내용을 담고 있습니다.
GUI Scripting Guide
Overview
GUI 는 그래픽적인 사용자 인터페이스 입니다. Unity 의 GUI 시스템은 UnityGUI 라고 불려집니다. UnityGUI 는 사용자가 매우
빠르게 그리고 쉽게 기능성과 함께 완전한 엄청나게 다양한 GUIs 를 생성하는 것을 할 수 있게 합니다. GUI 오브젝트를 생성하고
수동적으로 그것을 위치하고 그 후에 그것의 기능을 다루는 하나의 스크립트를 쓰는 것보다 사용자는 작은 양의 코드로 이 모든 것을
한꺼번에 합니다. 이것은 GUI Controls 을 생성하는 것에 의해 작동하고 그것은 착수되고 위치되고 한 번 모두가 정의됩니다.
예를 들어, 다음의 코드는 스크래치로 부터 완전히 기능적인 버튼을 생성할 것입니다:
function OnGUI () {
if (GUI.Button (Rect (10,10,150,100), "I am a button")) {
print ("You clicked the button!");
}
}
위의 코드에 의해 생성되는 버튼입니다
이 예제가 매우 간단함에도 불구하고 UnityGUI 에서 사용을 위해 가능한 매우 강력하고 복잡한 테크닉들이 있습니다. 그것은 넓은
주제이고 다음의 섹션은 사용자가 가능한한 빠르게 속도를 낼 수 있게 할 것입니다. 이 가이드는 레퍼런스 자료를 통해 직접 읽어질
수 있거나 사용될 수 있습니다.
UnityGUI Basics
이 섹션은 사용자에게 사용자의 프로젝트로 붙일 수 있는 한 뭉치의 작동하는 예제 뿐만 아니라 개요도 제공하면서 UnityGUI 의
중요한 컨셉을 다룹니다. UnityGUI 는 다루기에 매우 친절해서 시작하기에 좋은 곳입니다.
Controls
이 섹션은 UnityGUI 에서 모든 가능한 컨트롤을 리스트 합니다. 그것은 코드 예제와 이미지와 함께 완벽합니다.
Customization
기능적인 GUI 컨트롤을 생성하는 것은 그들의 외관이 사용자 정의될 수 없다면 유용하지 않을 것입니다. 고맙게도 우리는 이것에
대해 생각을 했습니다. UnityGUI 의 모든 컨트롤은 GUIStyles 과 GUISkins 와 함께 사용자 정의될 수 있습니다. 이 섹션은 그들을
사용하는 법을 설명합니다.
Layout Modes
UnityGUI 는 사용자의 GUIs 를 정렬하는 두 가지 방법을 가집니다. 사용자는 수동적으로 스크린위에 각 컨트롤을 놓을 수 있거나
또는 사용자는 HTML 테이블같이 많이 작동하는 자동 레이아웃 시스템을 사용할 수 있습니다. 하나의 시스템 또는 다른 것을
사용하는 것은 다른 클래스를 사용하는 것만큼 간단하고 사용자는 두 가지를 함께 믹스할 수 있습니다. 이 섹션은 예제를 포함해서
두 개의 시스템 사이에 기능적인 차이를 설명합니다.
Extending UnityGUI
UnityGUI 는 새로운 컨트롤 타입과 함께 확장하는 것이 매우 평이합니다. 이 챕터는 사용자가 간단한 compound 컨트롤을 어떻게
만드는지를 보여줍니다 – Unity 의 이벤트 시스템으로 통합과 함께 완성합니다.
Extending Unity Editor
주요 Unity 편집기는 UnityGUI 를 사용해서 쓰여집니다. 사용자가 게임안의 GUI 를 위해 사용하는 것처럼 같은 코드를 사용하는 것은
완전히 확장됩니다. 게다가 사용자 정의 편집기 GUI 를 생성할 때 사용자를 도와주기 위해 편집기의 특정한 GUI widgets 의 묶음이
있습니다.
네트워크 멀티플레이어 Networked Multiplayer
실시간 네트워킹은 복잡한 영역이지만 유니티에서는 이것을 엄청나게 쉽게 달성할 수 있게 만들었습니다. 하지만 여전히 여러
다양한 종류의 네트워크 게임 생성과 관련된 범위와 깊이를 이해하는 것이 가장 좋습니다. 이 섹션은 기본 네트워크 개념의 기본과
사용자가 사용할 수 있게 이 컨셉들의 유니티 만의 특정 실행방법들을 설명할 것입니다. 만약 사용자가 네트워크 게임을 만든 경험이
없다면 그러한 게임을 만들기 전에 이 가이드를 자세히 읽기를 적극적으로 추천합니다.
상급 레벨의 개요 High Level Overview
이 섹션은 네트워킹에 관련된 모든 개념의 아웃라인을 다룹니다. 이것은 더 깊은 주제로 이끄는 소개가 될 것입니다.
유니티의 네트워킹 요소들 Networking Elements in Unity
이 섹션에서는 위에서 다룬 내용들에 대한 유니티의 실행에 대한 설명을 할 것입니다.
RPC 세부사항 RPC Details
RPC 는 원격 절차 호출 Remote Procedure Call 을 의미합니다. 이것은 원격 컴퓨터에서 함수를 호출하는 방법입니다. 이것은
클라이언트가 서버에 있는 함수를 부르는 것일 수도 있고 혹은 서버가 모든 혹은 특정 클라이언트들의 함수를 호출하는 것일 수도
있습니다. 이 페이지에서는 RPC 개념을 자세히 다룹니다.
상태 동기화 State Synchronization
상태 동기화 State Synchronization 는 네트워크상에서 실행 중인 두개 혹은 그 이상의 게임 인스턴스들의 특정 데이터 세트를
정기적으로 업데이트 하는 방법입니다.
대역폭 최소화 Minimizing Bandwidth
어디에서 어떻게 데이터를 공유할지에 관해 사용자가 정하는 모든 결정은 사용자의 게임이 사용하는 대역폭에 영향을 줄 것입니다.
이 페이지는 대역폭 사용에 대한 상세내용과 어떻게 그것을 최소화로 유지하는지에 대한 자세한 내용을 다룰 것입니다.
네트워크 뷰 Network View
네트워크 뷰는 네트워크 상에서 데이터를 공유할 때 쓰이는 컴포넌트입니다. 이것을 이해하는 것은 굉장히 중요합니다. 이 페이지는
그것에 대한 자세한 내용을 다룹니다.
네트워크 인스턴스화 Network Instantiate
네트위크에서 어려운 주제 중 하나가 바로 객체의 소유권 ownership 에 관한 것입니다. 누가 무엇을 제어하는가? 네트워크
인스턴스화 instantiation 는 사용자를 위해 이 로직을 결정해 줄 것입니다. 이 페이지는 이것을 어떻게 할지 설명할 것입니다. 이
페이지는 또한 사용자가 더 많은 제어를 필요로 할때를 위한 복잡한 대안도 설명할 것입니다.
마스터 서버 Master Server
마스터 서버는 서버가 자신의 존재를 클라이어트에게 광고할 수 있는 게임 로비와 같은 것입니다. 이것은 또한 방화벽이나
홈네트워크 뒤로부터 통신 communication 을 가능하게 하기 위한 해결 방법이기도 합니다. 필요하다면 이것은 사용자의
플레이어들이 서로 항상 연결되 있게 하기 위해서 (촉진제 facilitator 의 도움으로) Nat punchthrough 라 불리는 테크닉을 사용
가능하게 합니다. 이 페이지는 마스터 서버를 어떻게 사용할 수 있는지에 대해 설명할 것입니다.
iOS 개발 시작하기 Getting Started with iOS Development
iOS 를 위한 개발 Developing for the iOS
iPhone/iPad 같은 기기를 위한 게임을 빌드하는 것은 데스크톱 PC 게임들의 경우와 다른 방식을 취하게 됩니다. PC 마켓과는 달리
사용자의 목표 하드웨어는 표준화 되어졌고 전용 비디오 카드가 있는 컴퓨터만큼 빠르거나 강력하지 않습니다. 그렇기 때문에
사용자는 이러한 플랫폼들을 위해서는 약간 다른 게임 개발 방식이 필요할 것입니다. 또한 유니티에서 iOS 를 위한 기능들은
데스크탑 PC 들을 위한 유니티의 기능들과 약간 다릅니다.
사용자의 애플 개발자 계정 설정하기 Setting Up Your Apple Developer Account
사용자가 유니티 iOS 게임을 실제 디바이스에서 사용하기 전에 사용자는 사용자의 애플 개발자 계정이 승인받고설정될 필요가
있습니다. 이것은 사용자의 팀을 정하는 것, 사용자의 기기를 추가하는 것 그리고 사용자의 표준 프로필을 확정짓는 것을 포함합니다.
이 모든 셋업은 애플의 개발자 웹사이트를 통해서 실행됩니다. 이것은 복잡한 과정이기 때문에 우리는 사용자가 사용자의 iOS
기기에서 코드를 실행할 수 있기 전에 완료되어야만 하는 일들에 대한 기본 아웃라인을 제공합니다. 그러나 가장 좋은 것은 Apple's
iPhone Developer portal로부터 지시사항을 하나하나씩 차례대로 따르는 것입니다.
참고: 애플 개발자 계정이 iOS 개발시 유니티의 모든 기능을 최대한 사용하기 위해 필요되기 때문에 우리는 진행 전에 사용자가
사용자의 애플 개발자 계정을 먼저 설정을 마치는 것을 권장합니다.
iOS 기능 사용하기 Access iOS Functionality
유니티는 멀티-터치 스크린, 가속도계, 기기의 지리적 위치 등 더 많은 것들에 접근하기 위해 많은 수의 스크립팅 API 들을
제공합니다. 사용자는 iOS scripting page 에서 새로운 스크립트 클래스들에 대해 더 많은 것을 찾을 수 있습니다.
스크립트에 네이티브 C, C++ 또는 Objective-C 노출하기 Exposing Native C, C++ or Objective-C Code to
Scripts
유니티는 사용자가 C# 스크립트로 부터 C, C++ 또는 Objective-C 로 쓰여진 사용자 정의 네이티브 함수를 호출하도록 허용합니다.
함수들을 어떻게 연결 bind 하는지에 대해 알고 싶다면 plugins page 를 방문해 보시기 바랍니다.
앱 내 구매기능을 위한 사용자 앱 준비 Prepare Your Application for In-App Purchases
유니티 iOS 런타임은 사용자가 새로운 컨텐츠를 다운로드하게 해주며 사용자가 앱 내에서의 구매기능을 구현하기 원할때 이 특성을
사용할 수 있습니다. 더 많은 정보를 원한다면 downloadable content page 를 방문해 주세요.
오클루젼 컬링 Occlusion Culling
유니티는 많은 오브젝트들이 포함된 복잡한 씬에서 가장 높은 성능을 쥐어짜낼때 편리한 오클루젼 컬링 occlusion culling 을
지원합니다. 더 많은 정보를 알고 싶다면 occlusion culling page 를 방문해 주세요.
스플래쉬 스크린 커스터마이제이션 Splash Screen Customization
사용자가 기기에서 사용자의 게임을 시작할 때 나타나는 이미지를 바꾸는 법을 알고 싶다면 splash screen customization page 를
방문해 주세요.
문제해결과 충돌 보고 Troubleshooting and Reporting Crashes
사용자의 기기에서 자꾸 충돌이 일어난다면 how to troubleshoot on iOS 페이지에서 자주 일어나는 문제점과 해결책에 대한
내용들을 참고해 주세요. 하지만 만약 여기서 해결방법을 찾을 수 없다면 그 충돌에 관한 버그 보고서를 보내주세요. (유니티 에디터
안에서 메뉴: Help > Report A Bug)
iOS 에서읭 충돌 버그 보고하기 Reporting Crash Bugs on iOS
우리는 유효한 버그 리포트를 환영합니다. 그러나 troubleshooting on iOS page 를 먼저 살펴보시기를 바랍니다.
어떻게 유니티의 iOS 와 데스크톱 타겟이 달라지는가 How Unity’s iOS and Desktop Targets Differ
Statically Typed JavaScript
자바 스크립트에서 동적 타이핑 Dynamic typing 은 iOS 를 타켓으로 할때 유니티에서 항상 꺼둡니다 (이것은 #pragma strict 가
사용자의 모든 스크립트들에 자동적으로 더해지는 것과 같습니다). 정적 타이핑 Static typing 은 성능을 매우 향상시키고 이것은
iPhone/iPad 디바이스에서 특별히 매우 중요합니다. 사용자가 기존의 유니티 프로젝트를 그 iOS 타겟으로 바꿀때, 사용자가 동적
타이핑을 사용한다면 사용자는 컴파일 에러를 받게 될 것입니다. 사용자는 이것둘을 에러를 일으키는 변수들을 위한 명시적 선언
타입들을 사용하거나 타입 유추 type inference 를 이용함으로써 쉽게 고칠수 있습니다.
Ogg Vorbis 오디오 압축 대신 MP3 MP3 Instead of Ogg Vorbis Audio Compression
성능적인 이유로 인해 iPhone/iPad 기기들에서 MP3 압축이 선호됩니다. 사용자의 프로젝트가 Ogg Vorbis 압축된 오디오 파일을
포함한다면 그들은 빌드하는 동안 MP3 로 재압축될 것입니다. iPhone 에서 압축된 오디오의 사용에 대한 더 많은 정보를 위해서는
audio clip 문서를 참고하세요.
DXT 텍스쳐 압축 대신에 PVRTC PVRTC Instead of DXT Texture Compression
유니티 iOS 는 DXT 텍스쳐를 지원하지 않습니다. 대신 PVRTC 텍스쳐 압축이 iPhone/iPad 에서 네이티브 지원됩니다. iOS 텍스쳐
포맷에 대한 더 많은 정보를 원하면 texture import settings 문서를 참고하세요.
무비 재생 Movie Playback
MovieTextures 는 iOS 에서 지원되지 않습니다. 대신 전체 화면 스트리밍 재생이 스크립팅 함수를 통해서 제공됩니다. 지원되는 파일
포맷과 스크립팅 API 에 대해서 배우려면 movie page 를 참고하시기 바랍니다.
더 읽을거리 Further Reading
•
아이폰 기초
•
유니티 리모트
•
아이폰 API
o
아이폰 인풋
o
iOS 키보드
o
iOS 고급
o
iOS .Net
•
아이폰 하드웨어
•
아이폰 성능
o
아이폰 그래픽 성능 최적화

아이폰 드로우콜 배치(Batch)

아이폰 최적화된 캐릭터 모델링

아이폰 렌더링 통계
o
아이폰 피직스 최적화
o
아이폰 스크립트 최적화
o
아이폰 내부 프로파일러
o
아이폰 메인룹 최적화
o
아이폰 플레이어 크기 최적화
•
아이폰 계정 셋업
•
아이폰 미지원 기능
•
아이폰 플러그인
•
아이폰 다운로드 가능 콘텐츠
•
모바일 스플래쉬 스크린 최적화
•
아이폰 문제 해결
•
아이폰 버그 보고
유니티 iOS 기초 Unity iOS Basics
이 섹션은 iOS 로 작업할 때 생길 수 있는 가장 빈번히 일어나면서도 중요한 질문들을 다루고 있습니다.
필요사항 Prerequisites
저는 애플로 부터 iPhone 개발자 승인을 받았습니다. 그러나 나는 이전에 iOS 로 개발해 본 적이 없습니다. 먼저 무엇을 해야 합니까?
A: SDK 를 다운로드하고 애플 개발자 사이트를 활용하며 사용자의 팀, 기기, 그리고 규정, 조항들을 준비를 끝냅니다.
유니티로 만들어진 게임이 iPhone 시뮬레이터에서 실행됩니까?
A: 안됩니다. 하지만 사용자가 만약 가장 최신의 SDK 를 사용하고 있다면 Unity iOS 를 iPad 시뮬레이터에 빌드할 수 있습니다.
그러나 시뮬레이터 그 자체로는 그것이 iOS 로부터의 모든 입력값 input 을 시뮬레이션하지 않고 사용자가 iPhone/iPad 에서 내는
만틈의 성능을 제대로 에뮬레이트 emulate 하지를 못하기 때문에 유니티에는 큰 도움이 되지 않습니다. 사용자는 그것이 아이폰이나
아이패드가 유니티 리모트 Unity Remote 어플리케이션을 실행시키는 동안에 아이폰/아이패드를 리모트 컨트롤로 사용해서 유니티
내부에서 직접적으로 게임 플레이를 테스트 해봐야 합니다. 그 후에 사용자가 성능을 테스트하고 게임을 최적화했을 때 사용자는
iOS 기기로 퍼블리쉬합니다.
유니티 기능들 Unity Features
터치스크린과 가속도계 accelerometer 와는 어떻게 작업합니까?
A: 사용자는 사용자의 앱을 빌드하기 위해 필요한 기기의 기능들로 연결해주는 클래스들을 사용자의 유니티 iOS 설치 부분의
스크립팅 레퍼런스에서 찾을 것입니다. 더 많은 정보를 위해서는 Input System page 를 참고하시기 바랍니다.
제 현재 파티클 시스템은 iOS 에서 매우 느리게 실행하는 것처럼 보입니다. 어떻게 해야 합니까?
A: iOS 는 상대적으로 낮은 필레이트 fillrate 를 가집니다. 만약 사용자의 파티클이 복수의 레이어와 함께 씬의 많은 부분을
차지한다면 가장 단순한 셰이더를 사용한다해도 iOS 성능을 확 떨어뜨릴 것입니다. 우리는 사용자가 오프라인으로 일련의 텍스쳐들
안에 파티클 이펙트를 굽는 것을 추천합니다. 그리고 실행시에 1-2 개의 파티클 정도만 사용하여 움직이는 텍스쳐 animated texture
들을 통해 보여줄 수 있습니다. 사용자는 이 방법을 이용하여 최소한의 오버드로우 overdraw 로 충분히 괜찮은 효과를 낼 수
있습니다.
물리 physics 를 많이 사용하는 게임도 만들 수 있을까요?
A: 물리는 많은 양의 부동 소수점 수치처리 floating point number crunching 를 필요로 하기 때문에 iOS 에서 비용이 많이 듭니다.
사용자는 가능한한 MeshColliders 를 최대한 피하는 것이 좋지만 그들이 정말로 필요하면 사용할 수도 있습니다. 성능을 향상하기
위해서 Edit->Time->Fixed Delta Time 을 사용해서 낮은 고정 프레임 속도 fixed frame rate 를 사용하세요. 10-30 의 프레임 속도를
권장합니다. 낮은 물리적인 프레임 속도를 사용하는 동안에는 매끄러운 움직임을 만들기 위해서 강체 보간 rigidbody interpolation 을
활성화 하세요. 진동 없이 완전히 유연한 프레임 속도를 얻으려면 사용자의 게임이 iOS 에서 얻는 평균적인 프레임 속도에 기반해서,
고정된 deltaTime 값을 설정하는 것이 가장 좋습니다. 1:1 또는 프레임 속도의 절반이 권장됩니다. 예를 들어 사용자가 30 fps 의
속도를 얻고 있다면 사용자는 고정 프레임 속도를 15 또는 30 fps (0.033 또는 0.066)를 사용하는 것이 좋습니다.
제가 유니티 iOS 에서 갤러리, 음악 라이브러리 또는 네이티브 iPod 플레이어에 접근할 수 있나요?
A: 예 – 사용자가 그것을 구현한다면 가능합니다. 유니티 iPhone 은 갤러리, 음악 라이브러리, iPod 플레이어 등등 iOS SDK 에서
보여지는 모든 기능들로의 접근을 포함해서 사용자가 필요해 하는 모든 특성을 추가할 수 있는 네이티브 플러그인 시스템을
지원합니다. 유니티 iOS 는 유니티 스크립트를 통해서 언급된 기능들에 접근하기 위한 API 를 제공하지는 않습니다.
유니티 GUI 에서 고려할 점 UnityGUI Considerations
유니티 GUI 는 저의 게임에 어느 만큼의 성능적인 효과를 줄 수 있습니까?
A: 유니티 GUI 는 많은 컨트롤을 사용할수록 꽤 비용이 들게 됩니다. 사용자의 게임이 실행되는 동안에는 유니티 GUI 의 사용을 게임
메뉴나 아주 최소의 GUI 컨트롤로 제한하는 것이 가장 이상적입니다. OnGUI()() 호출을 내포하는 스크립트를 가진 모든 오브젝트는
추가적인 프로세서 시간을 필요로 한다는 것을 알고 있어야 합니다 – 설사 그것이 빈 OnGUI() 블록이라도 말입니다. 만약 GUI
컨트롤이 사용되지 않고 있다면 OnGUI() 호출을 가지는 모든 스크립트들을 비활성화 시키는 것이 최상입니다. 이것은 스크립트에서
enabled = false 로 표시함으로써 할 수 있습니다
유니티 GUI 을 사용하는 것에 대한 다른 팁은? Any other tips for using UnityGUI?
A: 가능하면 GUILayout 을 적게 사용하도록 하십시오. 사용자가 하나의 OnGUI() 콜에서 GUILayout 을 하나도 사용하고 있지 않다면,
사용자는 MonoBehaviour.useGUILayout = false;을 사용해서 모든 GUILayout 렌더링을 비할성화 시킬 수 있습니다. 이것은 GUI
렌더링 성능을 두배로 올려줍니다. 마지막으로 3D 씬을 렌더링하는 동안에는 가능한 적은 수의 GUI 요소들을 사용하세요.
유니티 리모트 Unity Remote
유니티 리모트(Unity Remote)는 사용자의 iPhone/iPad 가 유니티에서 사용자의 프로젝트를 위하여 원격 조종기 remote control
역할을 할 수 있도록 하여 주는 애플리케이션입니다. 이것은 사용자가 각 변경이 생길 때마다 기기에 있는 사용자 프로젝트를
빌드하고 배포하는 것보다 리모트 컨트롤을 이용해서 에디터 안의 사용자 프로젝트를 테스트하는 것이 더 빠르기 때문에 개발하는
동안에 더 편리합니다.
유니티 리모트는 어디에 있나요? Where can I find Unity Remote?
유니티 리모트는 앱스토어에서 무료로 다운로드 받을 수 있습니다.
유니티 리모트를 어떻게 구축하나요? How do I build Unity Remote?
먼저 여기에서 프로젝트 소스코드를 다운 받고 원하는 곳에 압축을 풉니다. 이 zip 파일에는 유니티 리모트를 빌드하고 그것을
사용자의 기기에 설치하기 위한 XCode 프로젝트를 담고 있습니다.
사용자가 이미 권한 설정 프로파일 provisioning profile 을 생성하고 사용자 기기에 iOS 응용 프로그램들을 설치했다는 가정하에,
사용자는 단지 Xcode 프로젝트 파일인 UnityRemote.xcodeproj 파일을 열기만 하면 됩니다. XCode 가 시작되면, 사용자는 사용자의
iOS 기기에 앱을 설치하기 위해 "Build and Go"를 클릭하세요. 만약 사용자가 이전에 한번도 앱을 빌드하고 실행해 본적이 없다면,
우선 애플의 샘플들 몇개를 빌드해서 XCode 와 iOS 에 익숙해지기를 추천하는 바입니다.
일단 유니티 리모트 설치가 완료되면, 사용자의 기기가 사용자의 개발 머쉰 machine 과 같은 네트워크에 Wi-Fi 를 통해서 연결되어
있는지 확인하여야 합니다. 유니티가 사용자 컴퓨터에서 실행되는 동안 사용자의 iPhone/iPad 에서 유니티 리모트를 시작하고,
거기에 나타나는 리스트에서 사용자의 컴퓨터를 선택하세요. 이제 사용자가 에디터에서 Play 모드에 들어갈 때 마다, 사용자의
기기는 사용자 게임을 개발하고 테스트하는데 사용할 수 있는 리모트 컨트롤 역할을 할 것 입니다. 이제 사용자는 iPhone 으로
무선으로 앱을 컨트롤 할 수 있으며 또한 사용자는 기기의 화면에서 해당 앱의 낮은 해상도 버전을 볼 수 있을 것 입니다.
주의:유니티 iOS 에디터는 기기의 하드웨어를 완벽하게 재현할 수 없으므로, 사용자는 실제 디바이스에서와 정확히 같은 작동
(그래픽 성능, 터치 반응도, 음악 재생 등) 을 하지 않을 수도 있습니다.
유니티 리모트를 제 기기에 배포하는 동안 XCode 에 이상한 에러가 발생합니다. 어떻게 하면 될까요? Xcode
shows strange errors while deploying Unity Remote to my device. What should I do?
이것은 유니티 리모트 프로젝트에서 기본 식별자인 default Identifier 가 사용자의 권한설정 프로파일 provisioning profile 과 호환이
되지 않는다는 것을 뜻합니다. 사용자는 이 식별자를 수동으로 사용자의 XCode 프로젝트에서 변경하여야 합니다. 이 식별자는
사용자의 권한설정 프로파일과 동일해야 합니다.
사용자는 이미 하지 않았다면 * 별표가 뒤따라오는 AppID를 만들어야 합니다. 이것은 애플의 iPhone Developer Program의 Program
Portal 에서 할 수 있습니다. 먼저, 프로그램 포탈로 가서 AppID 탭을 고르세요. 그리고서는 우측 상단의 Add ID 버튼을 클릭하고 App
ID Bundle Seed ID와 Bundle Identifier 입력란에 점과 별표가 따라 붙는 (예: com.mycompany.*) 당신의 일반 번들 식별자 bundle
identifier를 입력하세요 (Bundle Seed ID + Bundle Identifier)). 새로 생성된 AppID를 사용자의 권한설정 프로파일에 추가하고,
다운로드 후 재설치합니다. 이후 XCode를 재시작하는 것을 잊지 마세요. 만일 AppID를 만드는데 문제가 있다면, 애플
웹사이트의Provisioning How-to section을 참조하세요.
사용자 기기에 유니티 리모트를 설치하기 전에 identifier 를 변경하는 것을 잊지 마세요.
XCode 로 유니티 리모트를 여세요. 메뉴에서 Project->Edit Active Target "Unity Remote" 메뉴를 선택하면 Target "Unity
Remote" Info 라고 제목이 붙은 새로운 창이 열리게 됩니다. 속성 Properties 탭을 선택합니다. 사용자의 Identifier property field 를
com.unity3d.UnityRemote 에서 bundle identifier 로 변경하고 뒤에 "." (점)을 넣고 다시 "UnityRemote"를 넣습니다. 예를 들면
만일 사용자 권한설정 프로파일이 ######.com.mycompany.* AppID 을 가지고 있다면, 그 ID
필드를 com.mycompany.UnityRemote 로 변경하면 됩니다.
그 다음, 메뉴에서 Build->Clean all targets 을 선택 한 유니티 리모트를 다시 후 컴파일 하고 설치 합니다. 아마 사용자는 Active
SDK 을 Simulator 에서 Device - 2.0 | Release 로 변경해야 할 수도 있습니다. 사용자 기기가 더 새로운 OS 버전을 사용하고
있더라도, SDK 2.0 을 선택해도 괜찮습니다.
유니티 리모트에서 게임을 실행 할 때 그래픽의 질이 아주 좋지 않습니다. 이를 개선하려면 어떻게 해야 하나요?
유니티 리모트를 사용하여 게임을 개발 할 때, 실제 게임은 사용자의 Mac 에서 실행하고 그 시각적 콘텐츠만 심하게 압축되어 기기로
스트리밍을 통해 보내어 집니다. 그 결과는 사용자는 iOS 에서 낮은 해상도 버전의 응용프로그램을 보게 됩니다. 해당 게임이
기기에서 실제 어떻게 실행 되는지를 테스트해 보려면, 편집기 메뉴에서 Build & Run 을 실행하여 볼 수 있습니다 (File->Build
Settings->Build & Run).
유니티 리모트가 한발 늦게 반응합니다(laggy). 개선할 수 있을 까요?
유니티 리모트의 성능은 사용자 네트워크 하드웨어의 성능, 혹은 다른 요소 등 대부분 Wi-Fi 속도에 의해 결정됩니다. 가장 최상의
결과를 얻으려면 사용자의 Mac 과 사용자의 iPhone/iPad 사이에 Ad-Hoc 네트워크를 하나 만드시길 권합니다. 사용자 Mac 에서
공항(Airport) 아이콘을 클릭하고, "Create Network"을 선택하고, 이름/비밀번호를 입력하고, 그 다음 OK 를 클릭합니다. 사용자의
iPhone/iPad 상에서, Settings->Wi-Fi 을 선택하고 그리고 사용자가 방금 생성한 새 Wi-Fi 네트워크를 선택합니다. ad-hoc 네트워크는
실제로 무선 연결이면 무선 연결 지점(wireless access point)이 없다는 것을 기억하십시오. 그러므로 사용자는 이 ad-hoc 네트워킹을
사용하는 동안은 인터넷에 연결 할 수 없습니다.사용자의 iPhone/iPad 과 Mac 에서 블루투스(Bluetooth)을 차단하면 연결 성능을
개선 할 수 있습니다.사용자가 iDevice 에서 게임 뷰를 볼 필요가 없다면, 원격 기기 리스트에서 이미지 동기화(synchronization)을 꺼
버릴 수 있습니다. 이렇게 하면 Remote 에서 작동하는 네트워크 트래픽을 감소시킬 수 있습니다.
유니티 리모트 연결이 좋지 않습니다.
만일 사용자가 이런 상황이라면, 그것은 설치상의 문제점이거나 혹은 다른 유니티 리모트의 정상 동작을 저해하는 요인일 수도
있습니다. 더 나아가기 전에 다음 단계를 거쳐서 성능이 향상 되는지 확인하십시오:
1.
우선, Bluetooth 가 꺼져 있는지 확인하십시오. 사용자의 Mac 과 iPhone/iPad 둘 다 꺼져 있어야 합니다.
다음에~/Library/Preferences/com.unity3d.UnityEditoriPhone.plist 에 있는 설정 파일을 지워야 합니다.
2.
사용자 iPhone/iPad 에 유니티 iOS 를 재설치 하십시오.
3.
사용자 Mac 에 유니티 iOS 를 재설치 하십시오.
4.
마지막 단계로, iPhone/iPad 의 전원을 껐다 다시 켜 보시는 것도 좋은 생각입니다.
만일 아직도 여전히 같은 문제가 발생한다면, 유니티 리모트를 다른 iDevice (가능 하면 다른 위치에 있는)에 설치하여 거기에서 더
나은 결과를 보여주는 확인해 보십시오. RF 간섭에 의한 문제이거나 사용자의 Mac 이나 iDevice 의 무선 어댑터 성능에 영향을
미치는 다른 소프트웨어 때문 일 수도 있습니다.
저희 주변에 Wi-Fi 네트워크가 아주 많고 유니티 리모트를 사용할 수가 없습니다. 어떻게 하면 될까요?
사용자는 iOS 상의 응용프로그램의 모양을 희생하고 유니티 리모트의 입력 스피트 향상을 시도해 볼 수 있습니다. 그렇게 하려면,
사용자 응용프로그램 폴더에 위치한 소스 프로젝트로 가서, setup.h 파일을 찾아 (UnityRemote/Classes 안에 위치), 그 안에
enums 의 일부를 변경하여 보시기 바랍니다.
유니티 리모트에서 나의 Mac 이 보이지 않습니다. 어떻게 하면 될까요?
•
유니티 리모트와 사용자의 Mac 이 같은 무선 네트워크에서 연결되어 있는지를 확인해 보십시오.
•
사용자의 방화벽 설정과 라우터의 보안 설정 그리고 여타 다른 하드웨어/소프트웨어가 사용자 네트워크의 패킷을 걸러내는 등을
확인 하시기 바랍니다.
•
유니티 리모트를 실행하게 두고, 사용자 Mac 의 Airport 는 1,2 분 끈 후 다시 켜 보십시오.
•
유니티와 유니티 리모트를 둘 다 재실행 하여 보십시오. 가끔은 사용자 iPhone/iPad 를 전원을 껐다 켤 필요도 있습니다(hold 메뉴와
파워 버튼).
•
유니티 리모트는 Apple Bonjour 서비스를 사용합니다. 그러므로 사용자의 Mac 이 켜져 있는지 확인하여 보십시오.
•
가장 최신 유니티 iOS 패키지로 유니티 리모트를 설치하여 보십시오.
안드로이드 리모트 Android Remote
Android Remote 에 관해서도 읽어 보시길 권합니다.
iOS 스크립팅
유니티 iOS 는 독특한 장치의 기능의 접급을 위해 몇가지 새로운 스크립트 API 를 제공합니다. 크로스 플랫폼 프로젝트를 위해서
iOS 를 위한 C#코드를 조건적으로 컴파일하는 UNITY_IPHONE 가 정의되어 있습니다. 아래의 새로운 스크립트 클래스가 소개되어
있습니다:
iPhoneInput
멀티 터치 화며, 가속기, 장치 방향과 지리적 위치에 대한 접근.
iPhoneSettings
화면 방향, 어두어짐과 장치 하드웨어에 대한 정보같은 iOS 만의 설정 .
iPhoneKeyboard
화면 키보드 지원.
iPhoneUtils
동영상 재생, 불법 복제 방지 보호, 진동에 관한 유용한 기능들.
추가 읽기
•
아이폰 인풋
•
iOS 키보드
•
iOS 고급
•
iOS .Net
iOS
장치의 지리적 위치 Device geographical location
장치의 지리적 위치는 iPhoneInput.lastLocation 속성을 통해 얻을 수 있습니다. 사용자는 이 속성을 호출하기
전에 iPhoneSettings.StartLocationServiceUpdates()를 이용해서 위치 서비스 업데이트를
시작하고 iPhoneSettings.locationServiceStatus를 통해 서비스 상태를 확인해야 할 것입니다. 자세한 사항은 scripting reference를
보세요.
모바일 키보드
가끔 게임을 개발할때 사용자는 목표 플랫폼이 제공하는 키보드 인풋에 접근할 필요가 있는데 이것은 유니티에서 스크립트의 어떤
속성을 불러줌으로써 바로 할 수 있습니다.
iOS
키보드 사용하기
GUI 요소
사용자가 에디팅이 가능한 GUI요소를 누르면 키보드가 자동으로 나타납니다. 현재, GUI.TextField, GUI.TextArea
와 GUI.PasswordField 가 키보드의 자동 핸들이 가능합니다. 이것을 어떻게 사용하는 가는 GUI 를 읽으세요.
수동 키보드 다루기
키보드를 열기위해서는 iPhoneKeyboard.Open 함수를 사용하세요. 이 함수가 사용하는 파라미터는 iPhoneKeyboard scripting
스크립트 참조에서 볼 수 있습니다.
키보드 타입 개요
키보드는 아래의 타입을 지원합니다:
Property:
Function:
iPhoneKeyboardType.Default
글자. 숫자와 기호 키보드로 전환될 수 있음.
iPhoneKeyboardType.ASCIICapable
글자. 숫자와 기호 키보드로 전환될 수 있음.
iPhoneKeyboardType.NumbersAndPunctuation
숫자와 기호. 글자 키보드로 전환될 수 있음.
iPhoneKeyboardType.URL
글자, 슬래시, .com 버튼. 숫자와 기호 키보드로 전환될 수 있음.
iPhoneKeyboardType.NumberPad
0 부터 9 까지의 오직 숫자.
iPhoneKeyboardType.PhonePad
전화 번호를 입력하기 위한 키보드.
iPhoneKeyboardType.NamePhonePad
글자. 전화 번호 입력을 위한 키보드로 전환가능.
iPhoneKeyboardType.EmailAddress
글자의 @기호. 숫자와 기호 키보드로 전환 가능.
Text Preview
기본으로 키보드가 나타나면 에디터 박스가 생성되며 키보드 위에 놓이게 됩니다. 이것은 마치 유저가 타이핑하는 것의 미리보기
처럼 작동하므로 그 텍스트는 항상 유저에게 보여야합니다. 그러나 iPhoneKeyboard.hideInput 를 true 로 세팅하여 텍스트
미리보기를 비활성화 할수 있습니다. 이것은 특정 키보드 타입과 인풋 모드에서 동작한다는 것에 주의하십시오. 예를들어, 이것은
전화번호 키패드와 멀티라인 텍스트 인풋에서는 동작하지 않습니다. 그런 경우 에디터 박스가 항상 나타납니다.
iPhoneKeyboard.hideInput 는 글로벌 변수이며 모든 키보드에 영향을 줍니다.
키보드 방향
기본으로 키보드는 자동으로 장치의 방향을 따릅니다. 특정 방향으로의 회전을 비활성화 또는 활성화 하기
위해서는 iPhoneKeyboard에 있는 다음 속성을 이용하세요:
Property:
Function:
autorotateToPortrait
세로 방향 자동회전 활성화 또는 비활성화 (아래 버튼).
autorotateToPortraitUpsideDown
세로 방향 자동회전 활성화 또는 비활성화 (위 버튼).
autorotateToLandscapeLeft
가로 좌측 방향 자동회전 활성화 또는 비활성화 (오른쪽 버튼).
autorotateToLandscapeRight
가로 우측 방향 자동회전 활성화 또는 비활성화 (왼족 버튼).
보임과 키보드 크기
There are three keyboard properties in iPhoneKeyboard 에 세가지 키보드 속성이 있는데 키보드의 화면에서의 보임 상태와 크기를
결정 합니다.
Property:
Function:
visible
키보드가 화면에 보이며 문자를 넣을수 있으면 true 를 리턴합니다.
area
키보드의 위치와 치수를 리턴합니다.
키보드가 활성화 되있으면 true 를 리턴합니다. 이 속성은 정적인 속성이 아닙니다. 이 속성을 상요하가 위해서는 키보드
active
인스턴스가 있어야 합니다.
iPhoneKeyboard.area 는 키보드가 완전히 화면에 보일 때까지 위치와 크기를 0 으로 rect 를 리턴함에 주의하십시오.
사용자는 iPhoneKeyboard.Open 를 부르자마자 바로 이 값을 요청해서는 안됩니다. 키보드 이벤트 순서는 다음과 같습니다:
•
iPhoneKeyboard.Open 가 불립니다. iPhoneKeyboard.active 는 true 를 리턴합니다. iPhoneKeyboard.visible 는 false 를
리턴합니다. iPhoneKeyboard.area 는 (0, 0, 0, 0)를 리턴합니다.
•
키보드가 화면에 나타납니다. 모든 속성은 같게 유지됩니다.
•
키보드 슬라이딩을 멈춥니다. iPhoneKeyboard.active 가 true 를 리턴합니다. iPhoneKeyboard.visible 이 true 를 리턴합니다.
iPhoneKeyboard.area 이 키보드의 실제 위치와 크기를 리턴합니다.
안전한 텍스트 입력
키보드에 입력시 심볼을 보이지 않게 설정하는 것이 가능합니다. 이것은 유저가 민감한 정보(암호 같은) 를 넣을 때 유용합니다.
수동으로 안전한 텍스트 입력이 활성화된 키보드를 열기 위해서는 아래의 코드를 사용하세요:
iPhoneKeyboard.Open("", iPhoneKeyboardType.Default, false, false, true);
타이핑하는 동안 텍스트 숨기기
알람 키보드
키보드에 보통의 불투명 대신에 반투명의 검은 배경화면을 보여주려면 iPhoneKeyboard.Open 을 다음과 같이 부르세요:
iPhoneKeyboard.Open("", iPhoneKeyboardType.Default, false, false, true, true);
보통 키보드
알람 키보드
고급 유니티 모바일 스크립팅
iOS
고급 iOS 스크립팅
장치 세대 정하기
장치의 다른 세대는 다른 기능을 지원하고 다양한 성능차이를 보입니다. 사용자는 느린 장치의 성능 보완을 위해 어떤 기능을
비활성화 해야하는지 결정하기 위해 장치의 세대를 물어보아야 합니다.
장치의 세대는 iPhoneSettings.generation 속성에 접근하여 얻을 수 있습니다. 세대는 아래 중 하나일 수 있습니다:
•
iPhone
•
iPhone3G
•
iPhone3GS
•
iPhone4
•
iPodTouch1Gen
•
iPodTouch2Gen
•
iPodTouch3Gen
•
iPodTouch4Gen
•
iPad1Gen
iPhone Hardware Guide 에서 다른 장치의 세대, 성능과 지원되는 기능에 대한 정보들을 볼 수 있습니다.
장치 속성
사용자가 접근할 수 있는 몇가지 장치에 따른 속성이 있습니다:
Property:
Function:
iPhoneSettings.uniqueIdentifier
유일한 장치 식별자.
iPhoneSettings.name
유저가 지정한 장치 이름.
iPhoneSettings.model
iPhone 인지 iPod Touch 인지 알려줌
iPhoneSettings.systemName
운영체제.
SystemInfo.operatingSystem
운영체제버전.
불법 복제 방지 체크
해커가 앱스토어의 응용 프로그램에서 애플 DRM 방지를 제거하고 무료로 재배포하는 일은 흔한 일입니다. 유니티 iOS 는 앱스토에
프로그램 제출후 프로그램에 변화가 있는지 확인하는 불법 복제 방지 기능이 있습니다.
사용자는 iPhoneUtils.isApplicationGenuine 속성에 접근함으로써 프로그램이 해킹되었는지 확힌할 수 있습니다. 만약 이 속성이
false 를 리턴하면 유저에게 해킹당한 프로그램을 사용 중이라 알릴수 있고 또는 프로그램의 어떤 기능을 비활성화 시킬 수있습니다.
주의: accessing iPhoneUtils.isApplicationGenuine 속성에 접근하는 것은 성능에 많은 영향을 주는 작업이며 절대 프레임 단위로
접근해서는 안됩니다.
진동 지원
사용자는 iPhoneUtils.Vibrate.을 부름으로써 iOS 진동을 일으킬 수 있습니다. 그러나 iPod Touch 장치는 진동 하드웨어가 없으며 그
부름은 무시될 것입니다.
기준 에셋
"기준 에셋(Standard Assets)" 은 특별한 의미 ("Plugins" 와 "Editor 와 같음)를 지닌 폴더이고 그것의 내용은 다른 모든 스크립트 보다
먼저 컴파일 됩니다. 스크립트는 특별한 이름을 가지지 않은 폴더에 저장하여야 합니다.
.NET API 2.0 호환 레벨 사용하기
iOS
유니티 iOS 는 두가지 .NET API 호환 레벨을 지원합니다: .NET 2.0 그리고 부분적인 .NET 2.0 subset. 사용자는 PlayerSettings 에서
알맞은 레벨을 선택할 수 있습니다 class-PlayerSettings 에서 알맞은 레벨을 선택할 수 있습니다.
.NET API 2.0
iPhone/iPad 을 목표로한 유니티는 .NET 2.0 API 프로파일을 지원합니다. 이것은 전체 .NET 2.0 API 와 흡사하며 기존의 .NET
코드와 최상의 호환성을 제공합니다.
장점:
1.
더 낳은 데스크탑 유니티와 타사 라이브러리의 코드 호환성
2.
기준 API 의 더 많은 기능들
단점:
1.
응용 프로그램 빌드 크기가 커짐
2.
약간 나빠지는 응용 프로그램 시작 타임
주의: 유니티 iOS 는 스크립트에 네임스페이스(namespace)를 지원하지 않습니다. 만약 타사의 라이브러리가 코드와 함께
존재한다면 그 라이브러리를 유니티 iOS 에디터 외부에서 컴파일하고 .dll 라이브러리를 에셋 폴더에 넣는 것이 최선입니다.
.NET 2.0 Subset
유니티 iOS 타겟은.NET 2.0 Subset API 프로파일 또한 지원합니다. 이것은 Mono “monotouch”프로파일에 가장 가까우므로
“monotouch”프로파일에 적용되는 많은 제한들 또한 이 .NET 프로파일의 유니티 iOS 구현에 적용됩니다. “monotouch”프로파일의
제한들에 대한 더 많은 정보는 here에서 볼수 있습니다.
장점:
1.
특히 스트립핑이 쓰이지 않았을 때 작은 응용 프로그램 배포 사이즈
단점:
1.
기준 그리고 타사 라이브러리와의 나쁜 호환성
iOS Hardware Guide
Hardware models
다음의 테이블은 다양한 제너레이션의 디바이스에서 가능한 iOS 하드웨어를 요약합니다:
모든 iOS 디바이스에 공통적인 것
•
Screen: 320x480 pixels, LCD at 163ppi (unless stated otherwise)
•
Built-in accelerometer
•
Wi-Fi
본래의 iPhone
•
ARM11, 412 Mhz CPU
•
PowerVR MBX Lite 3D graphics processor
•
128MB 메모리
•
2 megapixel camera
•
Speaker 와 microphone
•
Vibration 지원
•
Silent switch
iPhone 3G
•
ARM11, 412 Mhz CPU
•
PowerVR MBX Lite 3D graphics processor
•
128MB 메모리
•
2 megapixel camera
•
Speaker 와 microphone
•
Vibration 지원
•
Silent switch
•
GPS 지원
iPhone 3GS
•
ARM Cortex A8, 600 MHz CPU
•
PowerVR SGX graphics processor
•
256MB 메모리
•
3 megapixel camera with video capture capability
•
Speaker 와 microphone
•
Vibration 지원
•
Silent switch
•
GPS 지원
•
Compass 지원
iPhone 4
•
ARM Cortex-A8 Apple A4 CPU
•
ARM Cortex-A8 Apple A4 graphics processor
•
512MB 메모리
•
Cameras
o
30 fps 에서 720p HD video 와 LED flash 를 가지는 Rear 5.0 MP backside illuminated CMOS image sensor
o
Front 0.3 MP (VGA) with geotagging, tap to focus 와 480p SD video at 30 fps
•
Screen: 960x640 pixels, LCD at 326 ppi, 800:1 contrast ratio.
•
Speaker 와 microphone
•
Vibration 지원
•
Silent switch
•
GPS 지원
•
Compass 지원
iPod Touch 1st generation
•
ARM11, 412 Mhz CPU
•
PowerVR MBX Lite 3D graphics processor
•
128MB 메모리
iPod Touch 2nd generation
•
ARM11, 533 Mhz CPU
•
PowerVR MBX Lite 3D graphics processor
•
128MB 메모리
•
Speaker 와 microphone
iPad
•
1 GHz Apple A4 CPU
•
Wifi + Blueooth + (3G Cellular HSDPA, 2G cellular EDGE on the 3G version)
•
Accelerometer, ambient light sensor, magnetometer (for digital compass)
•
Mechanical keys: Home, sleep, screen rotation lock, volume.
•
Screen: 1024x768 pixels, LCD at 132 ppi, LED-backlit.
Graphics Processing Unit 와 Hidden Surface Removal
iPhone/iPad 그래픽스 프로세싱 유닛 (GPU)는 타일에 기반을 둔 지연 렌더러 입니다. 데스크탑 컴퓨터의 대부분의 GPUs 와
반대로 iPhone/iPad GPU 는 실제로 보여질 픽셀들만이 프로세싱 리소스를 소비하기 위해서 씬을 프로세스하는 초기에 이미지를
렌더하기 위해 필요되는 프로세싱을 최소화하는 것에 초점을 맞춥니다.
GPU 의 프레임 버퍼는 타일들로 나뉘어지고 렌더링은 타일에 따라 일어납니다. 첫째로 전체 프레임을 위한 삼각형은 모아지고
타일에 정렬됩니다. 다음으로 각 삼각형의 보여지는 부분은 선택됩니다. 마지막으로 선택된 삼각형 조각은 rasterizer 로 전달됩니다
(카메라로부터 막아지는 삼각형 조각들은 이 단계에서 거절됩니다).
다시 말해서 iPhone/iPad GPU 는 감소된 비용으로 Hidden Surface Removal 오퍼레이션을 구현합니다. 그러한 설계는 더 적은
메모리 대역폭을 소비하게 하고 더 적은 파워 소비를 가지고 텍스쳐 캐쉬를 더 잘 사용하게 합니다. 타일에 기반을 둔 지연 렌더링은
디바이스가 과장을 낮게 유지하기에 효과적인 실제 rasterization 전에 막아진 조각들을 거절하도록 허용합니다.
더 많은 정보를 위해서 다음을 살펴보세요:
•
POWERVR MBX Technology Overview
•
Apple Notes on iPhone/iPad GPU 와 OpenGL ES
•
Apple Performance Advices for OpenGL ES in General
•
Apple Performance Advices for OpenGL ES Shaders
SGX series
iPhone 3GS 와 더욱 새로운 디바이스로부터 시작하는 것은 GPUs 의 SGX 시리즈와 함께 갖춰져 있습니다. SGX 시리즈 특성은
OpenGL ES2.0 을 위해서 렌더링 API, 꼭지점 그리고 픽셀 쉐이더를 지원합니다. 고정된 함수 파이프라인은 그러한 GPUs 위에서
지원되지 않습니다. 대신 그것은 즉석에서 유사한 기능을 가지는 꼭지점 그리고 픽셀 쉐이더를 생성하는 것에 의해 필적되어 집니다.
SGX 는 멀티 샘플 앤티 앨리어싱을 완전히 지원합니다.
MBX series
iPhone, iPhone 3G, iPod Touch 1st 그리고 2nd Generation 과 같은 더 오래된 디바이스는 GPUs 의 MBX 시리즈와 함께 갖춰집니다.
MBX 시리즈는 오직 OpenGL ES1.1 고정된 함수 Transform&Lighting 파이프라인 그리고 프래그먼트당 2 개의 텍스쳐만을
지원합니다.
Texture Compression
iOS 에 의해 지원되는 유일한 텍스쳐 압축 포맷은 PVRTC 입니다. PVRTC 는 RGB 과 RGBA (색상 정보 + 알파 채널) 텍스쳐 포맷을
위한 지원을 제공하고 4 또는 2 비트로 하나의 픽셀을 압축할 수 있습니다.
PVRTC 포맷은 메모리 대역폭 (어떤 데이터가 메모리로부터 읽어질 수 있는 속도, 보통 모바일 디바이스에서 매우 제한적인)의
소비를 줄이고 메모리 청사진을 저장하기 위해 필수적입니다.
Vertex Processing Unit
iPhone/iPad 는 꼭지점 프로세싱을 위한 책임이 있는 전용 장치를 가집니다. 그것은 rasterization 과 함께 병렬적으로 계산을
실행합니다. 더 좋은 병렬체계를 얻기 위해 iPhone/iPad 는 rasterizer 앞에서 하나의 프레임에서 꼭지점을 프로세스 합니다.
Unified Memory Architecture
iPhone/iPad 위에서 CPU 와 GPU 둘 다 같은 메모리를 공유합니다. 이점은 사용자의 텍스쳐를 위해서 비디오 메모리를 다 써버리는
것에 대해 걱정할 필요가 없다는 것입니다 (물론 사용자가 메인 메모리를 다 쓰지 않는다면). 단점은 사용자가 게임 플레이와
그래픽스를 위해서 같은 메모리 대역폭을 공유한다는 것입니다. 사용자가 그래픽스에 사용하는 메모리 대역폭이 많을 수록
사용자는 게임 플레이와 물리를 위해서 더 적은 것을 가질 것입니다.
Multimedia CoProcessing Unit
iPhone/iPad 주요 CPU 는 VFP 또는 NEON 구조를 지원하는 강력한 SIMD (Single Instruction, Multiple Data) coprocessor 와 함께
갖춰집니다. Unity iOS 런타임은 스킨 메쉬 변환, geometry batching, 오디오 프로세싱 그리고 다른 집중 계산 오퍼레이션들을
계산하는 것과 같이 다수의 태스크를 위해서 이러한 유닛들을 이용합니다.
iOS 에서의 성능 최적화.
iPhone/iPad 에서 게임을 만드는 것은 재미있습니다. 하지만 성공적인 게임을 만들기 위해서는 자연스럽게 실행되도록
만들어야합니다. 그러므로 iPhone 의 그래픽 성능이나 처리 능력을 이해하는 것은 중요합니다.
iPhone/iPad 성능이 닌텐도 DS 와 휴대용 플레이스테이션 사이임을 알아야 합니다. 이에 맞게 계획을 세우싶이오!
다행이도 유니티가 도와드립니다. 저희는 유니티 iOS 프로젝트가 빠르게 동작하도록 많은 시간과 노력을 사용하였습니다. 다음은
iOS 에서 더 나은 성능을 갖도록 도와줄 수 있는 가이드라인의 모음입니다:
•
아이폰 그래픽 성능 최적화
o
아이폰 드로우콜 배치(Batch)
o
아이폰 최적화된 캐릭터 모델링
o
아이폰 렌더링 통계
•
아이폰 피직스 최적화
•
아이폰 스크립트 최적화
•
아이폰 내부 프로파일러
•
아이폰 메인룹 최적화
•
아이폰 플레이어 크기 최적화
iOS
iOS 를 위해서 컨텐트의 최적화를 원한다면 learn more about iOS hardware devices 페이지를 참조 하십시오.
알파 테스팅
데스크톱과는 반대로, 알파테스팅 (또는 픽셀 쉐이더에서 discard$ / clip$$ 연산)은 iOS 에서 성능상 비용이 많이 듭니다. 알파
테스트 쉐이더를 알파 블렌드로 교체를 원하시면, 그렇게 하십시오. 알파 테스트가 정말 필요하시면, 보이는 알파 테스트 픽셀
지역을 최소로 유지 시키십시오.
정점 성능
일반적으로 iPhone 3GS 나 새로운 디바이스들을 타겟으로 할때, 프레임당 40K 나 더 적은 정점을 목표로 합니다. MBX GPU 가
장착된 iPhone, iPhone 3G, 1 세대 2 세대 iPod Touch 경우 프레임당 10K 나 더 적은 정점을 목표로 합니다.
라이팅 성능
픽셀당 동적 라이팅(lighting)은 모든 영향 받는 픽셀에 중요한 비용이 추가 되고, 다중 패스들에 렌더링 오브젝트들을 이끌 수
있습니다. 하나의 오브젝트에 영향을 주는 하나의 Pixel Light 보다 픽셀 라이트를 더 가지는 것을 피하시고, 방향성 빛을 선호하시길
바랍니다. Pixel Light 는 Render Mode 설정이 Important 로 설정되어 있음을 명심하시기 바랍니다.
정점당 동적 라이팅은 정점 변환에 많은 비용이 더 추가 됩니다. 하나의 오브젝트에 영향을 줄때는 다중 불빛을 피하시기 바랍니다.
정적 오브젝트들을 위해서는 베이크 라이팅 (bake lighting)을 사용하십시오.
모델 기하 최적화
모델 기하를 최적화 할 때, 두 가지 기초 룰이 있습니다:
•
필요하지 않다면, 더 많은 추가 면을 사용하지 마세요.
•
UV 매핑솔기(seam)의 수를 유지하고, 하드 모서리(hard edge)를 가능한 적게 하십시오.
그래픽 하드웨어가 프로세싱하는 실질적인 정점의 개수는 3D 어플리케이션에 표시되는 것과는 같지 않습니다. 모델링
어플리케이션들은 모델을 이루는 포인트들, 즉 기하 정점 카운트를 표시합니다.
그래픽 카드들은, 몇몇 정점들은 구분 되어야 합니다. 정점이 다중의 법선(normal)들 (하드 모서리 위에서) 을 가지거나, 다중의 UV
좌표를 가지거나, 다중의 꼭지점 색상을 가지면, 이는 분리되어야 합니다. Unity 에서 보는 정점의 숫자는 3D 어플리케이션에서 진열
되는 것과 항상 다릅니다.
질감 압축
iOS 의 네이티브 PVRT compression formats 압축 포맷을 사용하십시오. 질감의 사이즈를 감소시킬 뿐만 아니라(더 빠른 불러오기
시간과 더 작은 메모리 사용), 렌더링의 성능을 증가 시킵니다. 압축된 질감은 32bit RGBA 에 비교해서 메모리 대역폭의 아주
일부분만 필요합니다. 성능 비교를 위해서는 iOS Hardware Guide 를 참조하십시오.
몇몇 이미지는 PVRT 압축 질감의 알파 채널에서 시각적 조형물로 되기 싶습니다. 그런 경우 이미지 소프트웨어에 PVRT 압축
변수들의 직접적인 변경을 원할 수 있습니다. PVRT 포맷을 만든 Imagination Tech의 PVRTexTool을 사용하여 PVR export
plugin을 설치해서 직접적인 변경이 가능합니다.pvr확장을 가진 압축 이미지는 유니티 에디터에 가져오기 될 것이며, 수동으로
설정된 압축 변수들은 보존 될 것입니다.
PVRT 압축 포맷이 충분한 시각적 질을 전달하지 않는다면, UI 질감과 같은 추가의 이미지 작업이 필요합니다. 이 경우 32bit RGBA
질감대신 16bit 질감의 사용을 고려해야 합니다. 최소한, 메모리 대역폭이 반으로 줄 것입니다.
성능 좋은 쉐이더를 작성하기 위한 팁들
iPhone3GS 이후로 GPU 들은 픽셀과 정점 쉐이더(shader)들을 충분히 지원하지만, 복잡한 픽셀당 기능을 가진 데스코톱 쉐이더의
성능과 초당 30 프레임들을 동작하는 iOS 디바이스의 성능을 추월하는 기대는 하면 안됩니다. 대부분 쉐이더 들은 편리하게 최적화
되어있고, 연산과 질감은 좋은 프레임 비율을 달성하기 위해서는 최소화 하여야 합니다.
복잡한 수식 연산들
수식 연산들(pow,, exp, log, cos, sin, tan)은 GPU 에 많은 부하를 줍니다. 최고의 방법은 부분당(per fragment) 하나의 연산 이상을
가지지 않는 것입니다. 때로는 질감 찾기(lookup)가 더 좋은 대안입니다.
자신만의 규격화된 normalize, dot, inversesqrt 사용을 회피하십시오. 항상 내장되어있는 연산들을 사용하십시오. 이것이 더 좋은
코드를 생성할 것입니다.
Disscard 연산은 부분들(fragments)을 느리게 만들것입니다.
부동소수 연산들
사용자 쉐이더들을 작성할 때 부동 소수 변수들의 소수점 자리를 명시하십시오. 좋은 성능을 위해서는 작은 포맷이 더 중요하다는
것은 매우 중요합니다.
쉐이더가 GLSL ES 로 쓰여지면, 소수점 자리는 다음과 같습니다:
•
highp - full 32 비트의 부동소수 포맷입니다. 정점변환에 적합하지만 가장 느립니다
•
mediump - 16 비트의 부동소수 포맷입니다. 질감 UV 좌표에 적합합니다. 대략 highp 보다 x2 빠릅니다.
•
lowp - 비트의 부동소수 포맷입니다. 색상과 빛 연산, 그리고 고성능 연산에 적합합니다. highp 보다는 __x4 배 정도 빠릅니다.
쉐이더가 GG 또는 표면 쉐이더로 쓰여지면, 소수점은 다음과 같습니다:
•
float - - GLSL ES 에서 highp 와 유사, 가장 느림
•
half - GLSL ES 에서 mediump 와 유사, float 보다 _x2__ 빠름
•
fixed - GLSL ES 에서 lowp 와 유사, float 보다 4x4 빠름
일반적인 쉐이더 성능을 알아보시려면 Shader Performance page 페이지를 참조하세요.
하드웨어 문서
Apple hardware 문서를 공부하고 쉐이더를 작성best practices for writing shaders하는데 시간을 가지시길 바랍니다. 부동 소수점의
힌트를 더 공격적으로 사용하길 권유합니다.
Lightmaps 으로의 Bake Lighting
정적 라이팅의 장면을 Unity 내의 내장된 Lightmapper 를 사용해서 베이크(bake)하십시오. lightmapped 환경을 생성하는 과정은
Unity 에서 장면에 빛을 배치하는 것보다 더 시간이 걸립니다. ¬¬그러나:
•
더 많이 빠릅니다 (2-3 배, 2 픽셀 라이트)
•
더 좋게 보입니다. 왜냐하면, 전체적 조명을 베이크 할수 있고, lightmapper 는 결과들을 부드럽게 할 수 있습니다
재료들 공유
다수의 오브젝트들이 같은 카메라로 표현되면, 유니티 iOS 는 더 다양한 내부적 최적화를 할 수 있을 것입니다. 예:
•
다양한 렌더 상태들을 OpenGL ES 로 하는 것을 피함.
•
정점과 픽셀 프로세싱에 필요한 다양한 종류의 변수들 연산을 피함
•
그리기(draw)호출들의 감소를 위한 작은 오브젝트들의 일괄처리
•
그리기 호출을 줄이기 위한 정적 속성을 가능하게 하는 크고 작은 오브젝트들의 일괄 처리
모든 이런 최적화들은 CPU 사이클들을 줄여줄 것입니다. 그러므로, 질감들을 하나의 지도로 합하고 같은 재료(material)을 사용하기
위한 다수의 오브젝트를 만드는 것은 비용을 줄이므로, 권유합니다!
게임을 빠르게 하기 위한 간단한 체크리스트
•
정점 카운트를 아래로 유지하세요:
o
iPhone 3GS 와 더 최신의 디바이스를 타겟으로 할때는 프레임당 40K 를 하세요 (SGX GPU 를 사용).
o
더 오래된 디바이스들은 프레임당 10K 로 하세요 (MBX GPU 를 사용)
•
내장 쉐이더를 사용한다면, Mobile 카테고리를 살펴보세요. Mobile/VertexLit 는 현재 가장 빠른 쉐이더입니다.
•
장면당 다른 재료(material)의 개수를 낮게 유지하세요- 가능하면 다른 오브젝트들 사이에서 더 많은 재료를 공유하세요.
•
내부 최적화를 위해서 움직이지 않는 오브젝트들에게 Static 속성을 설정하세요.
•
가능한 질감들을 위해서는 PVRTC 포맷을 사용하세요. 아니면, 32bit 대신 16bit 질감을 선택하세요.
•
통합기(combiners)또는 픽셀 쉐이더를 사용하세요. 이는 다중 패스 접근법 대신에 부분당 몇몇 질감을 혼합하기 위함입니다.
•
사용자 설정 쉐이더를 작성시에는, 항상 가장 작은 부동 소수점을 사용하세요:
o
fixed / lowp -- 칼라와 라이팅 정보, 법선들을 위해서는 완벽합니다,
o
half / mediump -- 질감 UV 좌표들을 위해서 쓰입니다,
o
float / highp -- 픽셀 쉐이더에서는 피합니다. 정점 쉐이더에서 정점 위치 계산을 위한 사용에 괜찮습니다.
•
픽셀 쉐이더에서 복잡한 수식 연산(pow, sin, cos 등)을 최소화 합니다.
•
필요하지 않으면 Pixel Lights 는 쓰지 않습니다. – 기하에 영향을 주는 (가능한 방향성의) 하나의 픽셀 라이트를 선택하세요.
•
필요하지 않으면 동적 라이트를 사용하지 않습니다 – 베이크 라이트를 대신 선택하세요.
•
부분당 (per fragment) 더 작은 질감을 사용하세요.
•
알파 테스팅을 피하세요. 알파 블렌딩(alpha-blending)을 대신 사용하세요.
•
필요하지 않으면 안개를 사용하지 마세요.
•
폐색 누락(Occlusion culling) 의 장점을 알아보시고, 복잡한 정적 장면에 많은 폐색이 있을 시에는 가시 기하와 그리기 호출의 양을
줄이기 위해서 사용하세요. 폐색 누락으로부터 어떤 이득의 단계를 얻을 것인지 계획하세요.
•
원거리 기하를 “위장(fake)” 위해서는 스카이박스(skybox)들을 사용하세요.
더 살펴보기
•
iOS 성능 최적화 Optimizing iOS Performance
•
iOS 하드웨어 안내 iOS Hardware Guide
•
iOS 자동 그리기 호출 일괄처리 iOS Automatic Draw Call Batching
•
최적화 캐릭터들의 모델링 Modeling Optimized Characters
•
렌더링 통계 Rendering Statistics
그리기 호출 일괄처리
스크린에 오브젝트를 그리기 위해서는, 엔진은 그래픽 API(iOS 경우 OpenGL ES)에 그리기 호출을 하여야 합니다. 모든 그리기
호출은 그래픽 API 안에서 많은 량의 연산을 필요로 합니다. 그러므로, 그리기 호출은 CPU 측에 많은 부하를 초래합니다.
유니티는 실행시에 오브젝트 다수를 묶고, 한번의 그리기 호출로 동시에 오브젝트를 그리는 스마트기능이 있습니다. 이 기능을
일괄처리(batch)라고 부릅니다. 유니티가 더 많은 오브젝트를 일괄처리 할수록, 더 좋은 렌더링 성능을 가지게 됩니다.
유니티에서 내장된 일괄처리는 모델링 툴에서 단순히 기하를 통합(또는 Standard Asset 패키지로부터 CombineChildren 스크립트를
사용) 하는 것보다 이점이 있습니다. 유니티에서 일괄처리는 가시결정(visibility determination)단계 후에 발생합니다. 그러므로,
엔진은 각각의 오브젝트들을 누락시킬 수 있으며, 표현된(rendered) 기하의 양을 일괄처리 없는 단계로 유지합니다. 모델링 툴에서
기하를 통합하는 것은 반대로 효율적인 누락(cull)을 막아, 더 높은 양의 기하가 표현되는 것을 초래합니다.
재료들
같은 재료를 공유하는 오브젝트들만 일괄처리가 가능합니다. 그러므로, 좋은 일괄처리를 위해서는, 더 많은 오브젝트들의 재료를
공유할 필요가 있습니다.
질감에 있어서만 차이가 있는 두 동일한 재료를 가지고 있다면, 이 질감들을 하나의 큰 질감으로 통합할 수 있습니다. 이
과정을 texture atlasing라고 종종 부릅니다. 일단 질감들이 같은 지도 안에 있게 되면, 하나의 재료를 대신 사용할 수 있습니다.
스크립트로부터 공유 재료 속성들을 접근하려면, 변환하려는 Renderer.material 이 재료의 복사본을 만들 것임을 명심하십시오.
대신, 재료를 공유하려면 Renderer.sharedMaterial를 사용하십시오.
동적 일괄처리
유니티는 같은 재료를 공유하면, 하나의 그리기 호출로 움직이는 오브젝트들을 자동으로 일괄처리 할 수 있습니다. 동적
오브젝트들을 일괄 처리하는 것은 정점당오버헤드를 가집니다. 그러므로, 일괄처리는 300 정점 이하를 가지는 메쉬들에게
적용됩니다.
동적 일괄처리는 자동으로 이루어지며, 추가적인 작업을 필요로 하지 않습니다.
Tips:
•
균일한 비율을 사용하세요(예: X:1, Y:1, Z:1). 비 균일한 변환 비율 즉 X:1, Y:2, Z:3 또는 X:1, Y:1.00001, Z:1 는 일괄처리의 실패를
야기합니다.
•
다른 재료 인스턴스를 사용하는 것은 일괄처리의 실패를 야기합니다.
•
Prefab 의 인스턴스들을 사용하는 것은 같은 메쉬와 재료를 자동으로 사용하는 것입니다.
•
사용되는 쉐이더의 정점 구조 크기는 일괄처리 할 수 있는 모든 개수의 정점에 영향을 미칩니다. 만약 쉐이더가 Vertex Position 과
하나의 UV 를 사용한다면, 450 개 가량의 정점을 일괄처리 할 수 있습니다. 만약 쉐이더가 Vertex Position 과 표준의 UV 하나를
사용한다면, 300 개 가량의 정점이 일괄처리 됩니다. 만약 쉐이더가 Vertex Position 과 표준의 UV0 와 UV1, 탄젠트를 사용한다면,
180 개 가량의 정점이 일괄 처리 됩니다.
정적 일괄처리
정적 일괄처리는 반면에 엔진의 어떤 사이즈의 기하(같은 재료를 공유하고 움직이지 않는 조건에서)를 위한 그리기 호출 수를
줄입니다. 정적 일괄처리는 동적 일괄처리보다 훨씬 더 효율적입니다. 더 적은 CPU 파워를 소모하므로 정적 일괄처리를 선택해야
합니다.
정적 일괄처리를 이용하기 위해서는, 대상 오브젝트들에게 정적임을 지정해야 하며, 게임에서 움직이거나 회전 비율조정을 해서는
안됩니다. 그러기 위해서는, 인스펙터의 정적 체크박스를 사용하여, 대상 오브젝트를 표시해야 합니다:
정적 일괄처리를 사용하는 것은 통합기하를 저장하기 위해서 추가의 메모리를 필요로 합니다. 정적 일괄처리 전에 같은 기하를
공유하는 다수의 오브젝트가 있다면, 기하의 복사는 각각의 오브젝트를 위해 이루어 것입니다 (에디터 안에서나 실행 시). 이는 항상
좋은 생각이 아닙니다. 때로는 메모리의 공간을 적게 유지하고 특정 오브젝트들을 위해서는 정적 일괄처리를 피하여 표현
성능(rendering performance)의 희생을 치러야 합니다. 예를 들어, 밀집한 숲에서 나무들을 정적으로 표시하는 것은 중요한 메모리의
영향을 줍니다.
정적 일괄처리는 Unity iOS Advanced 에서만 사용가능 합니다.
더 읽기
•
내장 프로파일러로 성능 측정 Measuring performance with the Built-in Profiler
•
렌더링 통계 Rendering Statistics
최적화된 캐릭터 모델링
Skinned Mesh Renderer 사용하기
사용자 캐릭터는 하나의 skinned mesh renderer 를 사용하여야 합니다. 보통 하나의 캐릭터를 위해 여러개의 메쉬를 사용할 필요는
없습니다. 유니티에서도 하나의 animation component 와 하나의 skinned mesh renderer 가 같이 사용될 때 어떤 것을 보여주는지
선택하고 경계를 정하는 지에 관련된 최적화 기능을 가지고 있습니다. 성능을 고려한다면 캐릭터당 다수의 스킨이 있는 메쉬는 좋은
선택이 아닙니다. 한 캐릭터에 두개의 skinned mesh renderers 를 사용한다면 캐릭터를 렌더링하기 위해 두배의 시간이 들 것입니다!
여러 재료(Material)를 사용하지 마세요
메쉬에서 가능한 적은 수의 materials 를 사용하여야 할 것입니다. 한 캐릭터에서 한가지 이상의 재료를 사용하기 위한 이유는 다른
그림자(예를 들어 눈을 위한 특별한 그림자 사용을 원할 때)를 사용하기 위한 이유 한가지 뿐입니다. 그러나 대부분의 경우 캐릭터당
2-3 개의 재료가 충분할 것입니다. 만약 캐릭터가 총을 가지고 있다면 그 총이 분리 될수도 있으므로 총은 다른 객체로 정의하는 것이
유용할 것입니다.
뼈대의 양을 줄이세요
보통의 데스크탑 게임은 15-60 정도의 뼈대를 가진 구조를 사용합니다. 적은 수의 뼈대를 사용할 수록 더 빨라집니다. 30 개의 뼈대로
데스크탑 플랫폼과 모바일 플랫폼에서 상당히 괜찮은 결과를 보여줄 수 있습니다. 정말 필요한 경우가 아니면 모바일 플랫폼에선
30 개보다 적은 데스크탑 플랫폼에서는 30 개 정도의 빼대를 사용하기를 권장합니다.
다각형의 개수
다각형을 몇 개를 사용하여야 하는 것은 사용될 플랫폼과 필요로하는 퀄리티에 때라 달라집니다. 모바일 플랫폼에서 300-1500 개의
삼각형 데스크탑 플랫폼에서는 500-6000 개의 삼각형이 적당합니다. 화면에 많은 수의 캐릭터를 원하거나 오래된 시스템어서
돌리길 원하면 각 캐릭터별 다각형의 개수를 줄여야 할 것입니다. 예를 들어, Half Life2 의 캐릭터들은 2500-5000 개의 삼각형을
사용하였습니다. PS3 나 Xbox360 에서의 차세대 AAA 게임들은 5000-7000 의 삼각형으로 만든 캐릭터를 가지고 있습니다.
IK 의 FK 구분
Inverse kinematics (IK) 와 forward kinematics (FK)를 구분하세요. 애니메이션을 불러올 때 IK 노드들은 FK 로 구워집니다. 그러므로
유니티는 IK 노드 자체를 필요로하지 않습니다. 유니티에서 GameObjects 를 제거하거나 모델링 툴의 노드를 제거할 수 있습니다.
그것을 제거함으로써 IK 노드들이 더이상 매 프래임당 다시 애니메이션화 할 필요가 없어집니다. 이런 이유로 IK 와 FK 를 같이 섞여
있는 계층을 가지는 것은 정말 좋지 않은 생각 입니다. 대신 하나의 IK 만을 위한 계층과 하나의 FK 만을 위한 계층을 만들어야
합니다. 이런 방법으로해야 모든 IK 계층을 쉽게 제거할 수 있습니다.
재사용 가능한 Rig 사용하기
재사용 가능한 rig 을 만드십시오. 이것은 사용자가 다른 캐릭터간 애니메이션을 공유하게 하는 것을 가능하게 합니다.
뼈대의 이름을 정확히 만듭니다
뼈대의 이름을 정확히 만듭니다 (왼쪽 힙, 왼쪽 발목, 왼쪽 발, 등등). 특히 캐릭터에서 뼈대의 이름을 정확히 하는 것은 정말
중요합니다. 예를 들어 만약 사용자가 하나의 캐릭터를 Ragdoll 로 바꾼다면 각 몸체를 위해 맞는 뼈대를 찾아야 할 것입니다. 이름이
정확하지 않다면 모든 몸체를 찾는데 많은 시간이 걸릴 것입니다.
Rendering Statistics Window
Game View 는 오른쪽 상단에 Stats 버튼이 있습니다. 이 버튼이 눌리면 화면 위로보이는 창에 실시간 렌터링 통계자료가 보입니다.
이것은 사용자 게임을 최적화하는데 매우 유용합니다. 그 통계는 빌드 목적에 따라 매우 다양할 것입니다.
렌더링 통계 윈도우
통계 윈도우는 다음의 정보를 포함합니다:
게임의 하나의 프레임(FPS)을 처리하고 렌더링하는데 걸리는 시간. 이것은 프레임을 업데이트하고 게임뷰를
Time per frame
and FPS
렌더링하는 시간만을 포함합니다. 에디터에서 씬뷰, 인스펙터 그리고 다른 에디터에서만 처리하는 것들에 대한
시간은 포함되지 않습니다.
총 몇개의 객체가 그려졌는가. 이것은 여러번 그려진 객체들도 합쳐집니다. 예를들어 픽셀빛에 영향을 받는 어떤
Draw Calls
객체는 여러번의 드로 콜(Draw call)을 추가할 것입니다.
Batched (Draw
같이 배치된 그림 콜의 개수. 배치란 여러 객체의 렌더링을 하나의 드로 콜로 만들어 CPU 사용을 줄이는 것을
Calls)
말합니다. 좋은 배치를 위해서는 가능한 많은 객체어서 재료들을 공유해야 합니다.
Tris and Verts
삼각형와 꼭지점의 개수. 이것은 사양이 optimizing for low-end hardware 때 가장 중요한 것입니다.
Used Textures
프레임을 그리는데 사용된 텍스쳐의 수와 메모리 크기.
생성된 Render Textures 의 수와 메모리 크기. 또한 이 프레임에서 몇 번이나 액티브한 렌더 텍스쳐가
Render Textures
바뀌었는지도 포함합니다.
Screen
화면의 크기, 앤티 앨리어싱 단계, 차지한 메모리.
VRAM usage
대략의 현 비디오 메모리(VRAM) 사용량. 또한 사용자 그래픽 카드가 가지는 메모리 크기도 보여줍니다.
그래픽 카드에 로드된 유니크한 메쉬(vertex buffers)의 개수. 각각의 모델은 새로운 VBO 를 만들것입니다. 어떤
VBO total
경우에는 크기가 바뀐 객체가 추가로 VBO 를 만들기도 합니다. 정적 배치의 경우 여러개의 객체가 하나의
VBO 를 공유하기도 합니다.
Visible Skinned
렌더된 스킨이 있는 메쉬의 개수.
Meshes
Animations
플레이 되고 있는 애니메이션의 개수.
Desktop
좀더 자세한 사항은 Optimizing Graphics Performance 를 보세요.
iOS
Optimizing iOS Graphics Performance 를 보세요.
물리적 성능 최적화
유니티는 차세대 NVIDIA PhysX 물리엔진을 가지고 있습니다. 이것은 독특한 긴급 행동을 가능하게 합니다. 하지만 iOS 는 모바일
장치를 위한 OS 이며 쉽게 그 한계에 다르는 성능 제한을 가지고 있음을 잊지마세요. 다음은 iOS 에서 어떻게 최적의 성능을 가질 수
있도록 물리를 조율할 수 있는지에 대한 고급 팁이니다:
•
Time manager 의 Fixed Timestep 을 CPU 사이클을 저장할 수 있도록 높게 하지만 물리가 자연스럽게 동작할 수 있도록 낮게
유지합니다.
•
Time manager 의 Maximum Allowed Timestep 을 최악의 경우에 물리에 사용되는 시간을 커버할 수 있도록 8-10fps 로 설정합니다.
•
콜라이더(collider)들은 아주 조심히 사용하도록 합니다. 어떤 콜라이들은(메쉬 콜라이더 같은) 구 콜라이더 같은 저 성능의
콜라이더와 달리 아주 고 성능을 요 합니다. 아래 리스트는 고 성능을 요하는 순으로 콜라이더를 나열하였습니다:
o
구 콜라이더 (저성능)
o
박스 콜라이더
o
캡슐 콜라이더
o
메쉬 콜라이더
o
바퀴 콜라이더 (고성능)
전체 물리적 계산의 양은 자고 있지 않은 단단한 물체와 씬의 콜라이더 개소, 그리고 콜라이더의 복잡도에 따라 다릅니다. 이 개수를
줄이고 물리적 계산에 소요되는 시간에 미치는 영향에 대해 트랙하도록 노력하세요. internal profiler 에서 이런 통계들을 트랙할 수
있습니다.
스크립트 성능 최적화
이 페이지는 iOS 에서 어떻게 스크립트 성능을 향상시킬수 있는지에 대한 일반 힌트를 제공합니다.
감소된 고정 델타 타임
15-25fps 의 고정 델타 타임을 사용하세요. 사용자는 Edit->Project Settings->Time 에서 이것을 바꿀수 있습니다.이것은
FixedUpdate 가 불리고 물리 엔진이 충돌감지(collision detection)와 rigidbody 엡데이트하는 빈도수를 줄여줍니다.주요 캐릭터에
rigidbody 를 사용한다면 Rigidbody 컴포넌트에서 낮은 고정 델타 타임 스텝을 부드럽게하기 위해 interpolation 을 활성화 할 수
있습니다.
GetComponent 콜수 줄이기
GetComponent 나 BuiltIn 컴포넌트를 액세서를 사용하는 것은 주목할만한 오버헤드를 생기가 할 수 있습니다. 이것은 컴포넌트의
직접적인 참조를 캐슁하여 줄일수 있습니다.
예를 들어:
function Update () {
transform.Translate(0, 1, 0);
}
대신 아래와 같이 최적화 할수 있습니다:
myTransform : Transform;
function Awake () {
myTransform = transform;
}
function Update () {
myTransform.Translate(0, 1, 0);
}
메모리 할당을 피하세요
•
스크립트에서 할당을 최소화하세요.
•
Structs 를 사용하세요. Structs 는 메모리를 할당하지 않습니다. 대신 스택에 놓이게되며 값으로 전달을하며 이것이 더 빠릅니다.
GUI 를 줄이세요
•
GUILayout 대신 GUI functions 을 사용하고 화면에서 GUI 의 양을 최소화 하세요
•
GUI 오버헤드를 줄이기 위해 MonoBehaviour.useGUILayout = false 를 사용하세요
function Awake () {
useGUILayout = false;
}
iOS 스크립트 콜 최적화를 사용하세요
UnityEngine 내임스페이스에 있는 대부분의 함수는 C/C++로 구현되어 있습니다. 그런 함수를 스크립트에서 부르는 것은 성능에
추가적인 오버헤드가 있습니다. 프레임당 추가의 몇 밀리세컨드를 얻기 위해서는 Edit->Project Settings->Player 에 있는
iOS 스크립트 콜 최적화를 사용하세요:
•
Slow and Safe - 기본적인 단일의 내부 콜 핸들링 (익셉션 지원함) .
•
Fast and Exceptions Unsupported - 빠른 단일 내부 콜 구현, 그러나 익셉션이 지원되지 않으므로 조심히 사용하세요. 이것이
유용한 전형적인 경우:프로그램이 유니티엔진을 많이 사용하면서 익셉션이 생기지 않을때 입니다. 이 옵션은 1-4ms/frame 을 줄일
수 있습니다.
Garbage Collection 최적화
•
위에 서 말한 것처럼 어떤 할당도 피하도록 하세요
•
만약 피할수 없다면 두가지 할당/수집 방법이 있습니다:
o
작은 힙 빠르고 자주 일어나는 가비지 콜렉션 전략
이 방법은 아주 긴 액션 게임플레이가 있고 부드러움 framerate 가 필요한 게임에서 잘 작동합니다.
짧은 시간동안 작은 블락을 할당하는 유니티 iOS 게임에서 힙은 보통 ~5ms(iPhone 3G 에서)걸립니다. 1MB 힙에서는 가비지
컬력션은 ~7ms 정도 더 걸립니다.
가끔은 매 N 번 프레임마다 강제 가비지 콜렉션을 하는것도 유용합니다:
o
if (Time.frameCount % 30 == 0)
o
{
System.GC.Collect();
o
o
}
그러나 유의해서 사용하세요. 내부 프로파일러 통계를 보고 그것을 바탕으로 결정을 내리세요.
o
큰 힙 느리고 빈도수가 낮은 가비지 콜렉션
이 방법은 게임이 요구하는 부드러운 프레임 속도가 짧은 것과 중간 사이의 길이일 때 사용을 합니다. 아이디어는 게임이 실행될때는
가비지 컬렉션을 피하고 게임이 중단 되었을 때하는 것입니다. 게임 시작에 힙에 어느 정도의 공간을 미리 할당하는 것도 좋은
생각인데 그 공간은 게임 플레이 세션이 잘 돌아갈수 있을 만큼 크고 OS 의 낮은 메모리 시스템으로 인해 프로그램이 멈추지 않을
만큼의 작은 공간을 말합니다. 모노는 필요할 때문 힙을 늘리기 때문에 가끔 시작시에 강제적으로 확장하는 것도 좋은 생각입니다:
o
function Start() {
o
var tmp = new System.Object[1024];
o
// 할당은 작은 블락에해서 큰 블락은 위하 특별한 처리 방법을 피하도록 합니다
for (var i : int = 0; i < 1024; i++)
o
tmp[i] = new byte[1024];
o
// 참조를 풀어 줍니다
o
tmp = null;
o
o
}
나중에 게임 플레이가 중단 되었을때 강제적으로 가비지 콜렉션을 할 수 있습니다:
System.GC.Collect();
주의해서 사용하셔야 합니다. 내주 프로파일러 통계에 주목하시고 실제 숫자를 바탕으로 결정을 내리세요.
Measuring Performance with the Built-in Profiler
Unity iOS 는 사용자의 프로젝트를 내장된 성능 프로파일러와 함께 제공합니다. 이것은 기본으로 비활성화되어 있다는 것을
참고하세요. 그것을 활성화하기 위해서 사용자는 Unity 에서 생성된 XCode 프로젝트를 오픈해야만할 것이고 AppController.mm
파일을 선택하고 #define ENABLE_INTERNAL_PROFILER 0 을 #define ENABLE_INTERNAL_PROFILER 1 으로 변경합니다. XCode
메뉴에서 결과 (GDB) 콘솔을 보여주기 위해서 Run->Console 을 선택하고 후에 사용자의 프로젝트를 실행합니다. Unity iOS 는 매
30 프레임마다 콘솔 윈도우로 통계를 내보낼 것입니다. 예를 들어:
iPhone/iPad Unity internal profiler stats:
cpu-player>
min: 9.8
max: 24.0
avg: 16.3
cpu-ogles-drv> min: 1.8
max: 8.2
avg: 4.3
cpu-waits-gpu> min: 0.8
max: 1.2
avg: 0.9
cpu-present>
min: 1.2
max: 3.9
frametime>
min: 31.9
max: 37.8
draw-call #>
min:
4
max:
9
avg: 1.6
avg: 34.1
avg:
6
| batched:
10
tris #>
verts #>
min: 3590 max: 4561 avg: 3871
| batched: 3572
min: 1940 max: 2487 avg: 2104
| batched: 1900
player-detail> physx: 1.2 animation: 1.2 culling: 0.5 skinning: 0.0 batching: 0.2 render: 12.0 fixed-update-count: 1 .. 2
mono-scripts> update: 0.5
mono-memory>
fixedUpdate: 0.0 coroutines: 0.0
used heap: 233472 allocated heap: 548864 max number of collections: 1 collection total duration: 5.7
모든 시간은 프레임당 밀리 세컨으로 측정됩니다. 사용자는 마지막 30 프레임에 대한 최소, 최대 그리고 평균 시간을 볼 수 있습니다.
General CPU Activity
cpu-player
CPU 에서 스크립트를 실행하면서 Unity 엔진에서 사용자 게임이 사용한 시간을 보여줍니다.
cpu-ogles-
CPU 위의 OpenGL ES 드라이버에서 사용된 시간을 보여줍니다. 콜의 수, 내부적인 렌더링 상태 변화, 렌더링
drv
파이프라인 셋업 그리고 프로세스된 꼭지점의 수와 같이 많은 요인들이 드라이버 타임에 영향을 가질 수 있습니다.
cpu-waits-
GPU 가 렌더링을 끝낼 때까지 CPU 가 사용했던 시간을 보여줍니다. 이 숫자가 2-3 밀리 세컨을 넘어가면 사용자의
어플리케이션은 fillrate/GPU processing bound 와 같습니다.
gpu
cpu-
OpenGL ES 에서 presentRenderbuffer 명령을 실행하기 위해 사용하는 시간의 양.
present
게임 프레임의 전반적인 시간을 나타냅니다. iPhone/iPad 하드웨어는 항상 60Hz 재생 속도로 잠겨 있습니다. 그러므로
frametime
사용자는 항상 ~16.7ms (1000ms/60Hz = ~16.7ms)의 몇 배를 얻게 될 것입니다.
Rendering Statistics
draw-
프레임당 콜의 수. 가능한한 낮게 유지합니다.
call #
렌더링을 위해 보내지는 삼각형의 전체 갯수.
tris #
렌더링을 위해 보내지는 꼭지점의 전체 갯수. 사용자가 정적인 기하만을 사용한다면 사용자는 이 숫자를 10000 밑으로
verts #
유지해야 합니다. 반대로 사용자가 많은 skinned 기하를 가지면 사용자는 이 숫자를 훨씬 더 적게 유지해야 합니다.
엔진에 의해 자동적으로 일괄 처리되는 콜, 삼각형 그리고 꼭지점의 수. 콜의 수와 비교할 때 전체 삼각형 수는
batched
사용자에게 batching 을 위해서 사용자의 씬이 얼마나 잘 준비되어 있는지에 대한 생각을 줄 것입니다. Batching 을
향상하기 위해 사용자의 물체 중에서 많은 재질을 공유하세요.
Detailed Unity Player Statistics
player-detail 섹션은 엔진 내에서 무엇이 일어나고 있는지에 대한 자세한 것들을 제공합니다:
물리에서 쓰는 시간.
physx
골자를 움직이는데 쓰는 시간.
animation
카메라 frustum 밖에서 물체를 잘라내는 데 쓰는 시간.
culling
스킨이 있는 메쉬로 애니메이션을 적용하는데 쓰는 시간.
skinning
기하를 일괄적으로 처리하는데 쓰는 시간. 동적인 기하를 일괄적으로 처리하는 것은 정적인 기하를 그렇게 하는
batching
것보다 훨씬 많은 비용이 듭니다.
보이는 물체를 렌더링하는데 쓰는 시간.
render
fixed-update-
이 프레임 동안에 실행되는 FixedUpdates 의 최소와 최대 수. 너무 많은 FixedUpdates 은 성능을 빠르게
저해합니다. 효과적인 fixed delta time 을 셋업하기 위해서 간단한 가이드 라인을 따르세요.
count
Detailed Scripts Statistics
mono-scripts 섹션은 모노 런타임에서 사용된 시간의 자세한 것들을 제공합니다:
스크립트에서 모든 Update()을 실행하는데 쓰여진 전체 시간.
update
fixedUpdate
스크립트에서 모든 FixedUpdate() 함수를 실행하는데 쓰여진 전체 시간.
스크립트 coroutines 내부에서 쓰여지는 시간.
coroutines
Detailed Statistics on Memory Allocated by Scripts
mono-memory 섹션은 사용자에게 모노 garbage collector 에 의해 얼마나 많은 메모리가 사용되는지에 대한 정보를 줍니다:
오브젝트와 함께 채워질 수 있는 메모리의 총 양. 할당된 힙의 사이즈보다 더 많은 오브젝트가
allocated heap
필요하다면 Garbage Collector 는 모든 참조되지 않는 오브젝트들을 메모리로 부터 버리는 컬렉션 단계를 시작할
것입니다. 컬렉션 단계 후에도 남은 공간이 충분하지 않다면 할당된 힙은 하이즈를 증가할 것입니다.
오브젝트의 의해 현재 사용되는 할당된 힙의 양 (allocated heap). 사용자가 새로운 클래스의 인스턴스
used heap
max number of
(struct 가 아닌)를 생성할 때마나 컬렉션 단계가 불려지기 전까지 이 숫자는 증가할 것입니다.
마지막 30 프레임 동안에 garbage collection 패스들의 수.
collections
collection
total duration
마지막 30 프레임 동안에 일어났던 모든 garbage collection 패스들의 전체 시간 (밀리 세컨즈로 표현).
Tuning Main Loop Performance
Setting Up Desired Frame-Rate
Unity iOS 는 사용자가 일 초에 사용자의 어플리케이션이 얼마나 많이 그것의 렌더링 루프를 실행하려고 할 지를 조정하도록 합니다.
기본적으로 초당 30 번 입니다. 이 숫자를 낮추는 것에 의해 사용자의 어플리케이션은 더 많은 배터리 파워를 아낄 것이나 초당 더
적은 프레임을 렌더할 것입니다. 이 값을 증가하는 것에 의해 렌더링은 터치 입력과 가속계 프로세싱과 같이 다른 활동들을 통해
우선시되어질 것입니다. 사용자는 프레임 속도 선택과 함께 실험할 필요가 있을 것이고 사용자 스스로 그것이 사용자의 특정
게임에서 가지는 효과를 결정할 필요가 있을 것입니다.
사용자의 어플리케이션이 계산적이거나 또는 무겁게 렌더링되고 있고 초당 오직 15 프레임만을 말하도록 유지할 수 있다면 15 를
통해서 원하는 프레임 속도를 세팅하는 것은 적합하지 않습니다. 첫 째로 사용자는 사용자의 어플리케이션을 최적화할 필요가
있습니다. 그 후에 원하는 프레임 속도를 증가할 필요가 있습니다.
원하는 프레임 속도를 세팅하기 위해 Unity iOS 에 의해 생성되는 사용자의 XCode 프로젝트 오픈하고 AppController.mm 파일을
선택합니다. #define kFPS 30 을 위치시키고 원하는 값으로 변경합니다. 예를 들어: #define kFPS 60.
Choosing the Best Rendering Loop
렌더링을 스케쥴링하기 위해서 시스템 타이머를 사용하는 애플의 기본적인 방법은 렌더링 성능 이상의 배터리 수명과 올바른
양심적인 이벤트 처리를 하는 성능이 중요하지 않은 어플리케이션을 위해 완벽합니다. 그러나 어떤 게임들은 배터리 수명보다
프레임 속도를 더 좋아할지도 모릅니다. 그러므로 Unity 는 더욱 타이트한 렌더링 루프에서 사용자가 실행하는 다른 방법을
제공합니다:
•
System Timer - 애플에 의해 제안되는 접근법. 렌더링을 스케쥴하기 위해 NSTimer 를 사용합니다. 최악의 성능을 가지나 모든 입력
이벤트를 프로세스하는 것을 보장합니다.
•
Thread - 별개의 쓰레드가 렌더링을 스케쥴하기 위해서 사용됩니다. 시스템 타이머 접근법을 비교하는 좋은 성능 향상을 제공하나
때때로 터치 또는 가속계 이벤트를 놓칠 수 있습니다. 이 접근법은 셋업하기에 가장 평이합니다.
•
Event Pump - 이벤트를 재빨리 하기 위해 CFRunLoop 을 사용합니다. 시스템 타이머 접근법을 비교하는 좋은 성능 향상을
제공합니다. 사용자가 운영 체제가 터치와 가속계 이벤트를 프로세싱하는데 얼마나 많은 시간을 써야만 하는지 명확하게
정의하도록 합니다. 걱정은 시간의 부족이 손실되는 터치 또는 가속계 이벤트를 낳음에 따라 처리되어야만 합니다.
Unity 는 기본적으로 버전 3.1 보다 더 오래된 운영체계와 함께 있는 디바이스를 위해 쓰레드에 기반한 렌더링 루프를 사용합니다.
Setting up System Timer Based Main Loop
Unity iOS 에 의해 생성된 XCode 프로젝트를 오픈합니다. AppController.mm 파일을 선택하고 위치시키고 #define
MAIN_LOOP_TYPE NSTIMER_BASED_LOOP 의 주석처리를 풀고 양쪽 defines 들이 다른 주요 루프 타입들을 위해 삭제되거나 주석이
풀리게되는 것을 확실시 합니다:
#define MAIN_LOOP_TYPE NSTIMER_BASED_LOOP
//#define MAIN_LOOP_TYPE THREAD_BASED_LOOP
//#define MAIN_LOOP_TYPE EVENT_PUMP_BASED_LOOP
사용자가 시스템 타이머와 함께 입력 프로세싱을 렌더링하는 것을 우선시하고 싶어한다면 AppController.mm 파일 [예를 들어,
@#define kThrottleFPS 4.0@로]에서 @#define kThrottleFPS 2.0@]을 위치시키고 변경해야 합니다. 이 숫자를 증가시키는 것은
렌더링에 더 높은 우선순위를 줄것입니다. 이 값을 변화시키는 것의 결과는 다른 어플리케이션과 다를지도 몰라서 사용자 스스로를
위해서 그것을 시도해보고 사용자의 특정 경우 위에서 영향을 보는 것이 최선입니다.
Setting up Thread Based Main Loop
Unity iOS 에 의해 생성된 XCode 프로젝트를 오픈합니다. AppController.mm 파일을 선택하고 위치시키고 #define
MAIN_LOOP_TYPE THREAD_BASED_LOOP 의 주석처리를 풀고 양쪽 defines 들이 다른 주요 루프 타입들을 위해 삭제되거나 주석이
풀리게되는 것을 확실시 합니다:
//#define MAIN_LOOP_TYPE NSTIMER_BASED_LOOP
#define MAIN_LOOP_TYPE THREAD_BASED_LOOP
//#define MAIN_LOOP_TYPE EVENT_PUMP_BASED_LOOP
Setting up Event Pump Based Main Loop
Unity iOS 에 의해 생성된 XCode 프로젝트를 오픈합니다. AppController.mm 파일을 선택하고 위치시키고 #define
MAIN_LOOP_TYPE EVENT_PUMP_BASED_LOOP 의 주석처리를 풀고 양쪽 defines 들이 다른 주요 루프 타입들을 위해 삭제되거나
주석이 풀리게되는 것을 확실시 합니다:
//#define MAIN_LOOP_TYPE NSTIMER_BASED_LOOP
//#define MAIN_LOOP_TYPE THREAD_BASED_LOOP
#define MAIN_LOOP_TYPE EVENT_PUMP_BASED_LOOP
사용자가 렌더링 루프에 기반한 Event Pump 를 선택했다면 사용자는 원하는 응답을 얻기 위한
kMillisecondsPerFrameToProcessEvents 상수를 주의깊게 조절해야 합니다. kMillisecondsPerFrameToProcessEvents 상수는
사용자가 정확하게 얼마나 많은 시간동안 OS 가 이벤트를 프로세스하도록 할 것인지를 지정하는 것을 허용합니다 (밀리 세컨즈
단위로). 이 태스크를 위해 충분하지 않은 시간이 할당한다면 터치 또는 가속계 이벤트는 빠르고 덜 응답적인 어플리케이션을 낳는데
속실이 있을지도 모를 것입니다.
OS 가 이벤트를 프로세싱 하는데 사용할 시간의 양을 (밀리 세컨즈 단위로) 지정하기 위해 사용자는 AppController.mm 파일에서
#define kMillisecondsPerFrameToProcessEvents 7.0 을 위치시키고 변경해야 합니다. 예를 들어 #define
kMillisecondsPerFrameToProcessEvents 3.0
Display Link Support
CADisplayLink 가 OS3.1 에서 소개되었음에도 불구하고 이론적으로 렌더링을 스케쥴링하기 위한 선호되는 접근법 이어야 합니다.
몇몇의 개발자는 OS 3.1 과 함께 설치된 첫 번째 제너레이션 디바이스 위헤서 특별한 경우의 입력 lag 를 리포트 했습니다. 사용자가
사용자의 어플리케이션을 위해서 CADisplayLink 을 지원하기를 바란다면 사용자는 Unity iOS 에 의해 생성된 XCode 프로젝트를
오픈해야할 것이고 AppController.mm 파일을 선택할 것이고 #define USE_DISPLAY_LINK_IF_AVAILABLE 0 을 위치시키고 #define
USE_DISPLAY_LINK_IF_AVAILABLE 1 로 변경합니다.
Tuning Accelerometer Processing Frequency
가속계 입력의 높은 빈도수는 사용자 게임의 전반적인 성능으로의 부정적인 효과를 가질지도 모릅니다. 기본적으로 iOS Unity
어플리케이션은 초당 60 번 가속계 입력을 쿼리할 것입니다. 사용자는 사용자 게임이 가속계를 전혀 사용하고 있지 않으면 가속계
빈도를 낮추는 것에 의해 또는 그것을 0 으로 세팅하는 것에 의해 부가적인 성능 향상을 발견할지도 모릅니다.
가속계를 위해 원하는 프로세싱 빈도수를 지정하기 위해서 사용자는 Unity 의 생성된 XCode 프로젝트를
오픈하고 AppController.mm 파일을 선택하고 #define kAccelerometerFrequency 60 을 기본적인 값으로 변경해야 합니다. 예를 들어:
define kAccelerometerFrequency 10
iOS 플레이어(Player) 빌드 사이즈
유니티 iOS 에 의해 빌드되는 플레이어의 사이즈를 줄이는 방법은 두 가지 입니다:
1.
Xcode 안에서 Active Build Configuration 을 바꾸는 것과
2.
Unity iOS 에서 Stripping Level 을 바꾸는것입니다.
배포상태의 빌딩
Xcode 프로젝트 폴더를 빌딩 한 후, the Active Build Configuration 드롭 다운 메뉴에서 Debug 또는 Release 를 선택 할 수
있습니다. Debug 대신 Release 로 빌딩을 하면, 게임에 따라 플레이어의 사이즈는 2-3MB 로 줄어듭니다.
Active Build 설정(Configuration) 드롭 다운 메뉴
배포로 빌딩 했을 때는 플레이어로부터 디버그 정보가 빠집니다. 그러므로, 게임이 충돌하거나, 다른 문제가 있으면, 스택을 추적할
아웃풋이 없습니다. 이 경우는, 디버그 버전으로 게임을 빌드 하시면 충돌을 재생하여 완전한 디버그 정보를 얻을 수 있습니다.
iOS Stripping 단계 (고급 라이센스 기능)
Stripping 관련 크기 최적화는 다음과 같이 작동합니다:
A) Strip assemblies level: script 바이트 코드는 분석됩니다. 스크립트로부터 참조되지 않은 클래스들과 함수들은 DLL 에서
제거되고, AOT 스텝으로부터 제외됩니다. 이러한 최적화는 주요 바이너리와 동반하는 DLL 크기를 감소시킵니다. 이 기능은 반사가
사용되지 않을 때 안전합니다.
B) Strip ByteCode level: 동반되는 .NET DLLs (Data 폴더에 저장된)은 메타데이터 까지만 strip 됩니다. 이는 모든 코드가 AOT 로
미리 컴파일되어 메인 라이브러리로 링크가 되어서 가능합니다.
C) Use micro mscorlib level: 특별한, 작은 버전의 mscorlib 이 사용됩니다. 몇몇 컴포넌트들은 이 라이브러리로부터 제거됩니다.
예를 들어, Security, Reflection.Emit, Remoting, non Gregorian calendars 등이 제거됩니다. 또한, 내부 컴포넌트의 상호 의존도가
최소화 됩니다. 이러한 최적화는 메인 바이너리와 mscorlib.dll 의 크기를 줄입니다. 이 기능은 몇몇 System 과 System.Xml 어셈블리
클래스들에게는 호환되지 않습니다. 그러므로 주의 깊게 사용하십시오.
메모: 이러한 레벨들은 축적됩니다. 그러므로, 레벨 (C) 최적화는 레벨 (B) 와 레벨 (A) 최적화를 포함하며, 레벨 (B) 최적화는 레벨 (A)
최적화를 포함합니다.
메모: 마이크로 mscorlib 는 핵심 라이브러리의 스트립트된 버전입니다. 유니티 엔진에서 모노 실행시 필요한 아이템들을 그대로
남습니다. 마이크로 mscorlib 를 사용하는 가장 좋은 습관은 어플리케이션에 필요하지 않는 .NET 의 클래스/기능들을 사용하지 않는
것입니다. GUID 는 사용되지 말아야 할 좋은 예입니다. 이들은 사용자 제작의 pseudo GUIDs 로 쉽게 대체됩니다. 그리고 더 좋은
성능과 어플리케이션 크기를 제공합니다.
Tips
반사가 사용될 때 스트리핑(stripping)을 다루는 법
스트리핑은 정적 코드 분석에 많이 의존하며, 작업을 올바로 실행하는데 실패합니다. 특히, 동적인 기능들(반사와 같은)이 사용
되었을 때입니다. 그러한 경우, 어떤 클래스들을 접근하지 말아야 하는지의 힌트들이 필요합니다. Unity iOS 는 사용자 스트리핑
black list 를 지원합니다. 그 과정은 간단합니다:
1. link.xml 파일을 생성하고, 이를 Assets (project root) 폴더에 직접 위치 시킵니다.
2. link.xml 의 구조의 예는 다음과 같습니다:
<linker>
<assembly fullname="System.Web.Services">
<type fullname="System.Web.Services.Protocols.SoapTypeStubInfo" preserve="all"/>
<type fullname="System.Web.Services.Configuration.WebServicesConfigurationSectionHandler" preserve="all"/>
</assembly>
<assembly fullname="System">
<type fullname="System.Net.Configuration.WebRequestModuleHandler" preserve="all"/>
<type fullname="System.Net.HttpRequestCreator" preserve="all"/>
<type fullname="System.Net.FileWebRequestCreator" preserve="all"/>
</assembly>
</linker>
메모: 때로는 어떤 코드들이 스트립 되어야 하는지 확인하는 것은 문제가 있을 수 있습니다. 그러나, 어플리케이션이 동작하려면
여전히 필요합니다. 시뮬레이터에서 스트립된 어플리케이션을 실행하고 Xcode 콘솔에서 에러메시지들을 보는 것으로 약간의
힌트들을 얻을 수 있습니다.
배포를 가능한 최소화 시키는 간단한 체크리스트
1.
asset 들을 최소화 합니다: 모든 질감 PVRTC 를 압축하며, 질감의 해상도를 가능한 줄입니다. 압축되지 않는 사운드들은
최소화 홥니다. 파일크기 줄이기 문서는 here 에 있습니다.
2.
iOS 사용할 스트리핑 레벨을 Use micro mscorlib 로 설정합니다.
3.
스크립트 호출 최적화를 Fast but no exceptions 로 설정합니다.
4.
코드 안에서 System.dll 이나 System.Xml.dll 에 상주하는 코드를 사용하지 않습니다. 이들은 micro mscorlib 와 호환되지
않습니다.
5.
불필요한 코드들의 상호관계를 제거 합니다.
6.
불필요한 asset 들을 제거 합니다.
7.
.Net 2.0 subset 을 Api 호환 레벨로 사용합니다. .Net 2.0 서브셋은 다른 라이브러리들과 제한된 호환성을 가집니다.
8.
타겟 플랫폼을 armv6 (OpenGL ES1.1)로 설정하십시오.
9.
JS Arrays 를 사용하지 마십시오.
10. generic 컨테이너와 value types 을 함께 사용하지 마십시오 (모든 구조체는 value type 입니다).
Unity iOS 로 20 메가 바이트 아래로 가능한가요?
네, 빈(empty) 프로젝트는 모든 최적화 레벨을 끈 상태로 AppStore 에서 ~13 MB 이내로 가능합니다. 게임에서 압축된 asset 을 위한
아직 ~7MB 의 여유공간이 있습니다. 만약 고급 라이선스(스트리핑 옵션을 위해 필요함)를 가지고 계시면, 훨씬 더 좋습니다. 이
경우는 주요 카메라와 빈 장면으로 AppStore(zip 으로 압축하고 DRM 부착)에서 6MB 공간만 필요합니다. 이 경우 압축된 asset 을
위한 아직 ~14MB 의 여유공간이 있습니다.
나의 어플리케이션이 AppStore 로 배포되었을 때 사이즈가 늘어났습니다. 어떻게 사이즈가 늘어나는 것을 막을 수 있을까요?
AppStore 에 배포되었을 때, Apple 은 우선 바이너리 파일을 암호화 하고, 그것을 zip 으로 압축합니다. 종종, Apple 의 DRM 은
바이너리 크기를 4MB 정도 증가 시킵니다. 일반적인 룰로는, 마지막 크기를 다음과 같이 예측합니다: 실행파일을 제외한 모든
파일들의 압축 사이즈 + 압축되지 않는 실행파일의 사이즈.배포파일을 최대한 작게 만드는 방법은 위의 리스트를 참조하십시오.
계정 설정
iPhone/iPad 에서 빌드하고 코드(유니티 에서 빌드된 게임들도 포함합니다)를 실행 시키기 전에 반드시 따라야하는 절차가 있습니다.
사용자의 iOS 게임을 출시하기 전에 필요한 절차들 입니다.
1. iPhone/iPad 에 등록된 개발자가 됩니다:
애플 웹사이트를 통해 가능합니다: http://developer.apple.com/iphone/program/
2. 운영체제를 업그레이드하고 iTunes 을 설치합니다:
이것은 iPhone SDK 를 쓰기위한 필요사항이며 이것은 변할 수 있음을 주의하십시오.
3. iPhone SDK 을 다운로드 합니다
iPhone dev center에 가서 로그인 합니다. 최신 iPhone SDK를 다운로드받아 설치합니다. 베타버전의 SDK를 다운로드 받지
마십시오. 오직 최신 버전만을 받으십시오. iPhone SDK를 다운로드 받고 설치하면 XCode도 설치 되어집니다.
4. 장치 식별자를 얻으십시오
USB 케이블을 이용하여 iOS 를 플러그인 하고 XCode 를 실행하십시오. XCode 를 사용자 모바일 폰을 새로운 장치로 잡아낼
것입니다. "Use For Development" 버튼을 누릅니다. 만약 Organizer 창이 열리지 않으면 Window->Organizer 로 갑니다. 장치 리스트
왼편에 사용자의 iPhone/iPod Touch/iPad 가 보일 것입니다. 그것을 선택하고 사용자 장치 식별자 코드를 적어 놓습니다.(40 개
정도의 숫자).
5. 사용자 장치 추가
iPhone developer center에 로그인하고 포탈 프로그램(오른편에 버튼)에 들어갑니다. 장치 페이지에 들어가 오른편의 Add
Device버튼을 클릭합니다. 장치 이름과(오직 알파 숫자) 장치 식별 코드(위 절차 5 에서 얻은)을 입력합니다. 끝나면 Submit버튼을
누릅니다.
6. 인증서 만들기
iPhone 개발자 프로그램 포탈 왼편의 Certificate 링크를 클릭합니다. How-to...에 있는 명령을 따릅니다.
7. WWDR 중간 인증서 다운로드(그리고 설치).
"Important Notice"의 빨간 텍스트 블럭 바로 위의 같은 "Certificates"에 다운로드 링크가 있습니다. 링크는 WWDR 중간 인증서라
불립니다. 다운로드 하면 설치를 위해 인증서를 더블 클릭합니다.
8. 권한 설정(Provisioning) 파일 만들기
권한 설정 프로파일은 약간 복잡하며 어떻게 팀을 구성했는가에 따라 다르게 설정되어야 합니다. 모든 상황에 적합한 경우는
없으므로 애플 개발자 사이트에 Provisioning How-to section 어떻게 권한 설정이 작동하는지를 읽으십시오.
현재 유니티 iOS 에서 지원되지 않는 기능들
그래픽스
•
DXT 텍스쳐 압축은 지원되지 않습니다. 대신 PVRTC 형식을 사용하세요. 좀더 자세한 내용을 Texture2D Component page 을
봐주세요.
•
사각형 텍스쳐는 PVRTC 형식으로 압축되지 않습니다.
•
동영상 텍스쳐는 지원되지 않습니다. 대산 전체화면 시티리밍 재생을 사용하세요(streaming playback). 자세한 내용을 Movie
playback page 을 봐주세요.
•
지형 엔진은 지원되지 않습니다.
•
나무 생성은 지원되지 않습니다.
•
Open GL ES2.0 은 iPhone, iPhone 3G, iPod Touch 1st 와 iPod Touch 2nd Generation 하드웨어에서 지원되지 않습니다.
오디오
•
Ogg 오디오 압축은 지원되지 않습니다. Ogg 오디오는 에디터에서 iOS 플랫폼으로 바꿔었을때 자동으로 MP3 로 바뀝니다. 유니티
iOS 에서의 오디오 지원에 대한 자세한 사항은 AudioClip Component page 를 참조하세요.
스크립팅
•
OnMouseDown, OnMouseEnter, OnMouseOver, OnMouseExit, OnMouseDown, OnMouseUp, OnMouseDrag 이벤트는 지원되지 않습니다.
•
Duck Typing 과 같은 동적 기능은 지원되지 않습니다. 컴파일러가 동적 기능을 에러로 보고 할 수 있도록 #pragma strict 를
사용하십시오.
•
WWW 클래스를 통한 동영상 스트리밍은 지원되지 않습니다.
•
WWW 클래스를 통한 FTP 지원은 제한적 입니다.
유니티 iOS 고급 라이센스에 한정된 기능들
•
Static batching 은 유니티 iOS 고급에서만 지원합니다.
•
Video playback 은 유니티 iOS 고급에서만 지원합니다.
•
Splash-screen customization 은 유니티 iOS 고급에서만 지원합니다.
•
AssetBundles 은 유니티 iOS 고급에서만 지원합니다.
•
Code stripping 은 유니티 iOS 고급에서만 지원합니다.
•
.NET sockets 은 유니티 iOS 고급에서만 지원합니다.
주의: 외부 라이브러리 참조는 최소화 하는것을 추천합니다. 왜냐하면 1MB 의 .NET CIL 코드는 대략 3-4 MB 의 ARM 코드로
변환되기 때문입니다. 예를 들어 사용자 프로그램이 스티리핑(stripping)을 사용하지 않으면 System.dll 과 System.Xml 을 참조하는
것은 추가의 6MB 를 의미합니다. 프로그램은 어느 시점에서 링커가 코드를 링킹하는데 문제가 생길때 한계에 다다를 것입니다. 만약
프로그램 사이즈에 중요하다면 JavaScript 에 적게 의존하는 C#이 적당한 언어가 될 것입니다.
iOS
iOS 를 위한 본래 플러그인과 프로그램 빌드하기
1.
사용자 extern method 를 다음과 같이 정의합니다:
2.
[DllImport ("__Internal")]
private static extern float FooPluginFunction ();
3.
에디터를 iOS 플랫폼으로 바꿉니다
4.
사용자 본래 구현을 생성된 Xcode 프로젝트의 "Classes" 폴더에 추가합니다 (프로젝트가 업데이트 될때 이 폴다는
덮어씌여지지 않습니
다. 그러나 사용자 본래 코드를 백업하는 것을 잊지 마세요).
플러그인 구현을 위해 C++ (.cpp) 또는 Objective-C (.mm)를 이용한다면 name mangling issues를 피
하기 위해 함수가 C 링키지와 함께 선언되도록 해야합니다.
extern "C" {
float FooPluginFunction ();
}
C#에서 사용자 플러그인 사용하기
iOS 본래 플러그인은 실제 장치에서만 불릴수 있으므로 모든 본래 코드 함수를 추가적인 C#코드 레이어로 감싸세요. 이
코드는 Application.platform 를 확인할수 있으며 실제 장치에서 실행될때만 본래 함수를 부를수 있고 에디터에서 실행될 때는 모형
값을 리
턴합니다. Bonjour 브라우저 샘플 프로그램을 확인하세요.
본래 코드에서 C# / JavaScript 부르기
유니티 iOS 는 제한적인 native->managed callback 기능을 UnitySendMessage 을 통하여 지원합니다:
UnitySendMessage("GameObjectName1",
"MethodName1", "Message to send");
이 함수는 세개의 파라미터를 가지고 있습니다: 게임 객체 이름, 부를 게임 객체 스크립트 함수, 불려진 함수에 넘겨줄
메세지.알아야할 제한은:
1.
다음의 시그니쳐와 사응하는 스크립트 함수만이 본래 코드에서 불려질 수 있습니다: function MethoName(message:string)
2.
UnitySendMessage 으로의 콜은 비동기이고 하나의 프레임 딜레이가 있습니다.
자동화된 플러그인 통합
유니티 iOS 는 제한적인 자동화된 플러그인 통합을 지원합니다.
1.
Assets/Plugins/iOS 에 있는 모든 .a,.m,.mm,.c,.cpp 는 자동으로 생성된 Xcode 프로젝트로 통합 됩니다.
2.
통합은 symlinking 파일을 통해 가능한데 Assets/Plugins/iOS 에서 마지막 목적지로 통합하며 이것은 몇가지 workflow 에
영향을 줄것입니
다.
1.
Xcode 프로젝트 트리에 .h 파일은 포함되지 않았지만 그들은 마지막 목적지 파일 시스템에 나타나고
그래서.m/.mm/.c/.cpp 의 컴파일
을 가능하게 합니다.
주의: 하위 폴더는 지원되지 않습니다.
iOS 팁
1.
Managed -> unmanaged 콜은 iOS 에서 상당이 비쌉니다. 프레임당 여러개의 기본 함수를 부르지 않도록하세요.
2.
위에서 말한 것처럼 사용자 기본 함수를 장치에서 실제 코드를 부르고 에디터에서 모의 값을 리턴하는 추가적인 C#
레이어로 감싸세요.
3.
기본 함수에서 리턴된 스트링 값은 UTF-8 로 인코딩되고 힙에 할당되어야 합니다. Mono marshaling 콜은 이것을 위해서는
무료입니다.
4.
위에서 언급한것 처럼 Xcode 의 "Classes" 폴더는 상요자 기본 코드를 두기에 좋은데 왜냐하면 프로젝트가 업데이트되도
덮어씌여지지 않기 때문입니다.
5.
기본 코드를 저장하기 좋은 또다른 곳은 에셋 폴더나 그 하위의 다른 폴더들 입니다. Xcode 프로젝트에서 참조를 기본 코드
파일에 추가합니다. "Classes" 하위 폴더에서 오른쪽 클릭 후 "Add->Existing files..."를 선택합니다.
"In App Purchases"를 위한 프로그램 준비
이 장은 애플의 "StoreKit"과 어떻게 게임을 연계시키는지를 다루기 위한 것이 아닙니다. 이것은 사용자가 이미 native code plugin 를
통해 "StoreKit"과 연계하였음을 가정합니다.
애플의 "StoreKit"문서는 "In App Purchase" 과정을 통해 판매될 수 있는 네가지의 상품에 대해 정의합니다:
•
콘텐츠(Content)
•
기능(Functionality)
•
서비스
•
등록(Subscriptions)
이 장은 첫번째 경우만을 다르며 다운로드할 수 있는 콘텐트 개념에만 집중합니다. AssetBundles는 다운로드할 수 있는 콘텐츠의
가장 적합한 후보이며 두가지 경우가 다루어질 것입니다:
•
iOS 에서의 사용을 위해 어떻게 에셋들을 내보니는지
•
어떻게 다운로드하고 iOS 에 저장하는지
iOS 에서 에셋 내보내기
다운로드 가능한 콘텐츠를 위한 개별 프로젝트를 가지는 것은 주 프로그램과 같이 오는 다운로드 가능한 컨텐츠와 나중에 다운로드
받는 콘텐츠를 잘 구분하게 해주는 좋은 생각입니다.
다운로드 가능한 콘텐츠에 포함되어 있는 어떤 게임 스크립트도 주 실행프로그램안에 존재해야 합니다.
1.
Project View 안에 에디터 폴더를 만듭니다.
2.
ExportBundle.js 스크립트를 그곳에 만들고 다음 코드를 입력합니다:
3.
@MenuItem ("Assets/Build AssetBundle From Selection - Track dependencies")
4.
static function ExportBundle(){
5.
6.
var str : String = EditorUtility.SaveFilePanel("Save Bundle...", Application.dataPath, Selection.activeObject.name,
"assetbundle");
7.
if (str.Length != 0){
8.
BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, str,
BuildAssetBundleOptions.CompleteAssets, BuildTarget.iPhone);
9.
}
10. }
11. 다운로드 가능한"prefabs"인 객체를 디자인하세요
12. 내보내져야하는 prefab 를 선택 후 오른쪽 클릭하세요
첫 두 스텝이 잘 끝나면 Build AssetBundle From Selection - Track dependencies 메뉴 아이템이 보일 것입니다.
13. 이 에셋이 사용하는 모든 것을 포함하고 싶다면 그것을 선택하십시오.
14. 저장 대화창이 보일 것이고 원하는 에셋 파일 번들 이름을 입력합니다. .assetbundle확장자가 자동으로 생성됩니다.
유니티 iOS실행 시에는 오직 마지막 프로그램으로서의 같은 버전의 유니티 에디터와 같이 빌드된 에셋 번들만을
허락합니다. 좀더 자세한 사항은 BuildPipeline.BuildAssetBundle을 읽으십시오.
iOS 에서 에셋 다운로드
1.
2.
에셋 번들은 WWW class을 사용해서 다운로드하고 로드할 수 있으며 주 에셋을 인스턴스화 합니다. 코드 샘플입니다:
var download : WWW;
3.
4.
var url = "http://somehost/somepath/someassetbundle.assetbundle";
5.
6.
download = new WWW (url);
7.
8.
yield download;
9.
10.
assetBundle = download.assetBundle;
11.
12.
if (assetBundle != null) {
13.
// Alternatively you can also load an asset by name (assetBundle.Load("my asset name"))
14.
var go : Object = assetBundle.mainAsset;
15.
16.
if (go != null)
17.
instanced = Instantiate(go);
18.
else
19.
20.
Debug.Log("Couldnt load resource");
} else {
21.
22.
Debug.Log("Couldnt load resource");
}
23. 게임 데이터 폴더 옆에 문서폴더에 필요한 파일을 저장할 수 있습니다.
24.
25.
public static string GetiPhoneDocumentsPath () {
// Your game has read+write access to /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX/Documents
26.
// Application.dataPath returns
27.
// /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/myappname.app/Data
28.
// Strip "/Data" from path
29.
string path = Application.dataPath.Substring (0, Application.dataPath.Length - 5);
30.
// Strip application name
31.
path = path.Substring(0, path.LastIndexOf('/'));
32.
return path + "/Documents";
33.
}
34. NET파일 API를 이용해서 다운로드한 에셋을 캐쉬하고 나중에 다시 사용하기 위해서 WWW
class와 file:///pathtoyourapplication/Documents/savedassetbundle.assetbundle.를 통해 로드합니다. 캐슁을 위한
샘플코드 입니다:
35.
// Code designed for caching on iPhone, cachedAssetBundle path must be different when running in Editor
36.
// See code snippet above for getting the path to your Documents folder
37.
private var cachedAssetBundle : "path to your Documents folder" + "/savedassetbundle.assetbundle";
38.
var cache = new System.IO.FileStream(cachedAssetBundle, System.IO.FileMode.Create);
39.
cache.Write(download.bytes, 0, download.bytes.Length);
40.
cache.Close();
41.
Debug.Log("Cache saved: " + cachedAssetBundle);
모바일 타겟 Splash 화면 사용자 정의
iOS
어떻게 스플래시(splash) 화면을 만드나요?
게임 출판의 한 부분으로 장치에서 게임이 실행될 때 나타나는 스플래시 화면을 사용자 정의 할 수 있습니다. 유니티 iOS 기본
유저는 포함된 스플래시 화면의 네가지 다른 방향을 선택할 수 있으며 고급 유저는 자신만의 독특한 스플래시 화면을 만들기위해
어떤 텍스쳐도 사용할 수 있습니다.
스플래시 화면은 플레이어 설정에서 사용자 정의될 수 있습니다. 바람직한 스플래시 방향은 플레이어 설정(Resolution and
Presentation 섹션)에서 "Default Screen Orientation" 속성으로 명시되어 있습니다.
포함된 스플래시 화면 사용하기
사용자는 주어진 네가지 기본 스플래시 화면 방향 중 하나를 택합니다:
1.
세로 - 유저 인터페이스와 스플래시 화면이 수직으로 되어있으며 홈 버튼이 장치의 바닥에 옵니다.
2.
뒤집어진 세로 - 유저 인터페이스와 스플래시 화면이 수직으로 되어있으며 홈 버튼이 장치의 상단에 옵니다.
3.
가로 오른쪽 - 유저 인터페이스와 스플래시 화면이 수평으로 되어있으며 홈 버튼이 장치의 왼쪽에 옵니다.
4.
가로 왼쪽 - 유저 인터페이스와 스플래시 화면이 수평으로 되어있으며 홈 버튼이 장치의 오른쪽에 옵니다.
독특한 스플래시 화면 사용하기(프로 라이센스 기능)
유니티 iOS 프로 유저는 어떤 텍스쳐도 스플래시 화면으로 사용할 수 있습니다. 기준 스플래시 화면의 크기는 장치별로
다릅니다(320x480 픽셀은 1-3 세대 장치에서, 1024x768 은 iPad 에서, 640x960 은 4 세대 장치에서). 이 크기에 맞지 않는 텍스쳐는
자도으로 크기가 바뀔 것입니다. 지시 사항:
1.
스플래시 화면 텍스쳐를 에셋 폴더 아무곳에나 가져다 놓으세요.
2.
In Player Settings (Splash Image 섹션),에서, 모바일 스플래시 화면, 고해상도 아이폰 아이패드 세로/가로 속성을 위한
텍스쳐를 고릅니다. 사용자가 목표로하는 장치에 적용되는 것만 정의합니다.
그것이 전부 입니다! 게임이 빌드되면 사용자 저의 이미지가 사용될 것입니다.
iOS
iOS 장치에서의 문제 해결
유니티 iOS 에디터에서는 문제가 없다가 실제 장치에서는 작동하지 않는 알려진 케이스들이 있습니다. 그 문제는 주로 코드나
컨텐츠 퀄리티와 관련되어 있습니다. 이 챕터에서는 가장 흔한 경우를 설명합니다.
Xcode 3.2.x fails to build application with error "libiPhone-lib.a, missing required architecture i386 in file
Undefined symbols: "Register_UnityEngine_Input_GetMouseButtonDown()", referenced from:
RegisterAllStrippedInternalCalls() in RegisterMonoModules.o
이 빌드 에러는 보통 Player Settings 에서 non-simulator SDK 가 선택되면 발생하는데 나중에 Xcode 에서는 SDK 가 시뮬레이터로
바뀝니다. 시뮬레이터 빌드를 실행하기 위해서는 Player Settings 에서 simulator SDK 를 선택해야 합니다.
Xcode 4.x fails to build application with error "No architectures to compile for (ARCHS=armv6,
VALID_ARCHS=i386)."
현재 유니티는 Xcode 4.x 에 대한 제한된 지원을 하고 있고 최종 프로그램을 빌드하려면 약간의 수동 작업의 노력이 필요합니다.
빌드하고 실행하면 유니티 iOS 가 생성한 Xcode 프로젝트를 엽니다 하지만 이것은 적절한 빌드 타겟와 적절한 목표 장치를
선택하지 못합니다. 장치에서 테스트를 위해 빌드한다면 "Unity-iPhone"과 맥에 연결된 iOS 장치를 빌드 타겟으로 선택합니다.
시뮬레이터에서 테스트를 위해 빌드한다면(주의: Player Settings 에서 적절한 SDK 가 필요합니다) "Unity-iPhone-simulator"와
적절한 시뮬레이터 장치를 선택해야합니다.
얼마의 시간이 지나면 게임이 멈춥니다. Xcode 가 상태바에 "interrupted"를 보여줍니다.
이에는 몇 가지 이유가 있을 수 있습니다. 보통 아래와 같습니다:
1.
스크립트 에러. 초기화된 변수 사용하기 등.
2.
타사의 컴파일된 라이브러리 사용하기. 그런 라이브러리는 iOS SDK 링커에서 문제를 일으키고 랜덤 크래시를 만듭니다.
3.
Serializable 스크립트 속성에 파라미터로 generic type 을 value types 과 사용할 때(like List<int>, List<SomeStruct>,
List<SomeEnum>).
4.
코드 스트리핑이 활성화 되어있을 때 반사 사용하기.
5.
native plugin interface 에서의 에러(managed code method signature 가 native code function signature 와 맞지 않음).
자세한 사항은 XCode 디버거 콘솔을 검토해 봐야 합니다. Xcode 디버거 콘솔은 Xcode 메뉴의 Run->Console 에서 접근 가능합니다.
Xcode 콘솔은 "Program received signal: “SIGBUS” 또는 EXC_BAD_ACCESS 에러를 보여줍니다.
이 메세지는 사용자 프로그램이 Null Reference Exception 을 받으면 보통 iOS 장치에서 나타납니다. 무엇이 잘못 되었는지 알아내는
두 가지 방법이 있습니다:
Managed stack traces
유니티 버전 3.4 이후로 Null Reference Exception 를 핸들하는 프로그램이 포함되어 있습니다. AOT 컴파일러는 객체 함수나 필트가
접근될 때마다 널 참조를 작은 체크를 가지고 있습니다. 이 기능은 사용자 스크립트 성능에 영향을 주고 이것이 오직 개발
빌드에서만 활성화된 이유입니다(기본 라이센스 사용자는 Build Settings 대화창에서 "development build"를 활성화 한것으로
충분합니다. 프로 라이센스 사용자는 추가로 "script debugging" 옵션을 체크해야 합니다).모든 것이 제대로 설정이 되었고 .NET
코드에서 에러가 발생하면 더 이상 EXC_BAD_ACCESS 를 하지 않습니다. 대신 .NET 익셉션 텍스트가 Xcode 콘솔에
보여집니다(또는 사용자 캐치문에 잡힙니다). 보통 결과물은:
Unhandled Exception: System.NullReferenceException: A null value was found where an object instance was required.
at DayController+$handleTimeOfDay$121+$.MoveNext () [0x0035a] in DayController.js:122
위에서는 DayController 클래스의 coroutine 처럼 작동하는 handleTimeOfDay 함수에 문제가 있습니다. 또한 이 샘플
"DayController.js:122"처럼 스크립트 코드이면 정확한 코드라인을 볼 수 있을 것입니다. 다음 코드에 해당합니다:
Instantiate(_imgwww.assetBundle.mainAsset);
보통 이것은 스크립트 코드가 WWW 클래스가 성공적으로 에셋 번들을 다운로드 했는지 적절히 체크를 하지 않고 그 필드에
접근하면 발생합니다.
Native stack traces
Native stack traces 는 에러 조사에 좀더 강력한 툴입니다. 또한 보통 이 에러가(하드웨어 메모리 액세스) 발생하면 더 이상 진행이
되지 않습니다. native stack trace 를 얻기 위해서 타입 스레드가 Xcode 디버거 콘솔을 제외한 모든 곳에 적용됩니다. 스택
트레이스를 주의 깊게 조사하세요. 아마 어디에서 에러가 일어났는지 힌트를 줄 것입니다. 아마 아래와 같은 것을 볼 것입니다:
...
Thread 1 (thread 11523):
#0 0x006267d0 in OptionsMenu_Start ()
#1 0x002e4160 in wrapper_runtime_invoke_object_runtime_invoke_void__this___object_intptr_intptr_intptr ()
#2 0x00a1dd64 in mono_jit_runtime_invoke (method=0x18b63bc, obj=0x5d10cb0, params=0x0, exc=0x2fffdd34) at
/Users/mantasp/work/unity/unity-mono/External/Mono/mono/mono/mini/mini.c:4487
#3 0x0088481c in MonoBehaviour::InvokeMethodOrCoroutineChecked ()
...
무엇보다 "Thread 1"를 위한 스택 트레이스를 찾아야 합니다. 이것은 메인 스레드 입니다. 스택 트레이스의 첫 라인은 에러가
일어나는 곳을 가르쳐줍니다. 이 예제는 NullReferenceException 이 "OptionsMenu" 스크립트의 "Start"함수 안에서 발생했음을
알려줍니다. 이 함수의 구현을 주의 깊게 보는것은 문제의 원인을 파악하는데 도움이 될 것입니다. 보통 NullReferenceExceptions 은
Start 함수에서 초기화 순서에 대한 잘못된 가정이 만들어질 때 발생합니다. 어떤 경우에는 디버거 콘솔에 부분적인 스택
트레이스가 보여집니다:
Thread 1 (thread 11523):
#0 0x0062564c in start ()
이것은 사용자 프로그램을 위한 릴리즈 빌드 중에 native symbol 이 삭제된 것을 알려줍니다. 완전한 스택 트레이스는 아래의 지시를
따라 얻을 수 있습니다:
•
Xcode 프로젝트에서 디버그 설정을 선택합니다.
•
모든 타겟을 클리어 합니다.
•
빌드하고 실행합니다.
•
위 설명처럼 스택 트레이스를 얻습니다.
EXC_BAD_ACCESS 가 외부 라이브러리가 유니티 iOS 프로그램에 링크될 때만 발생합니다.
이것은 보통 외부 라이브러리가 ARM Thumb instruction set 과 함께 컴파일될 때 발생합니다. 현재 그런 라이브러리는 유니티 iOS 와
호환되지 않습니다. 이 문제는 라이브러리를 Thumb instruction 없이 다시 컴파일해서 쉽게 해결할 수 있습니다. 라이브러리의
Xcode 프로젝트를 위한 자세한 지시:
•
Xcode 메뉴에서 "Project" -> "Edit active target"
•
"Target Info"대화 창에서 "Configuration: All Configurations"선택
•
탐색 필드에 "thumb" 입력
•
"Compile for Thumb" 설정이 나타나면 체크를 해제하고 라이브러리 리빌드 .
만약 라이브러리 소스를 볼 수 없으면 라이브러리 제공자에게 thumb 버전이 아닌 라이브러리를 요청합니다.
Xcode 콘솔이 크래쉬 직후 "WARNING -> applicationDidReceiveMemoryWarning()"를 보여줍니다.
(가금 Program received signal: �0�같은 메세지를 볼 수 있습니다.)이 경고 메세지는 많은 경우 심각한 것은 아니고 iOS 가
메모리가 적어 프로그램에 메모리를 프리할 것을 요청하는 것입니다. 보통 메일 같은 백그라운드 프로세스들이 메모리를 풀어주며
사용자 프로그램은 계속 실행될 수 있습니다. 그러나 사용자 프로그램이 계속 메모리를 사용하거나 더 원할 경우 OS 는 어느
시점에서 프로그램을 종료하기 시작하고 사용자 프로그램이 종료 될 수도 있습니다. 애플은 어떤 메모리 사용이 안전한지 문서화
되지 않았지만 경험적 관찰에 의하면 25MB 이하의 RAM(80MB: 3 세대 장치)을 이용하는 프로그램은 메모리 사용 문제를 가지지
않습니다. 40MB 의 RAM 을 사용하는 프로그램은 1-2 세대 장치에서 문제를 야기하고 장치를 재시작해야 할 수도 있습니다.
사용자가 의존해야 하는 주요 통계는 프로그램이 얼마나 많은 RAM 을 사용하는가 입니다. 사용자 프로그램의 메모리 사용은 다음
세가지 주요 부분으로 이루어 집니다:
•
응용 프로그램 코드 (OS 는 RAM 에 프로그램을 로드하고 유지할 필요가 있습니다)
•
native heap (상태, 에셋 등을 RAM 에 저장하기 위해 엔지에서 사용됨)
•
managed heap (Mono 실행시에 C#과 JavaScript 객체를 유지하기 위해 사용됨)
사용자 프로그램의 메모리 사용은 Xcode Instruments 툴 (Activity Monitor 과 Object Allocations)에서 감시될 수 있습니다.
Xcode 의 performance 툴인 Run->Start with Performance Tool->Activity Monitor 과 Run->Start with Performance
Tool->Object Allocations 에서 실행될 수 있습니다. 첫 번째 툴은 모든 프로세스의 사용자 프로그램이 사용하는 전체 RAM 양을
나타내는 실제 메모리를 포함한 통계를 보여줍니다.
주의: internal profiler 은 .NET 스크립트에 의해 할당된 힙만을 보여줍니다. 총 메모리 사용은 위에서처럼 Xcode Instruement 에서
얻을 수 있습니다. 이 숫자는 메모리에 로드 되어 7MB 를 차지하는 프로그램 바이너리, 어떤 표준 프레임워크 버퍼, 유니티 엔진 내부
상태 버서, .NET 런타임 힙(internal profiler 에서 보여주는 값) 그리고 그 밖의 값들을 포함합니다.
다른 툴은 사용자 프로그램에 의한 모든 할당과 native heap + managed heap 통계를 포함합니다(프로그램의 현재 상태를 알기 위해
Created and still living 박스를 확인하는 것을 잊지마세요). Net bytes 값을 보아야 합니다.
어떻게 메모리 사용을 낮게 유지하는지에 대한 힌트:
•
가장 강력한 iOS 스트리핑 옵션(고급 라이센스 기능)을 사용해서 프로그램 바이너리 크기를 줄이고 다양한 .NET 라이브러리
불필요한 의존성을 피하세요. 자세한 사항은 player settings 과 player size optimization 를 보세요.
•
컨텐츠 크기를 줄이세요: 텍스트에는 PVRTC 압축을 사용하고 낮은 다각형 모델을 사용하세요. 자세한 것은 reducing filesize 을
참조하세요.
•
스크립트에서 너무 많이 할당하지 마세요. internal profiler 에서 mono heap 크기와 사용을 감시하세요.
•
주의: 유니티 3.0 에서는 씬을 로딩하는 구현이 많이 바뀌었고 이제 모든 씬에셋은 미리 로드됩니다. 이것은 게임 객체를 인스턴스화
할때의 급격한 하락을 줄여줍니다. 게임 플레이 동안 에셋의 로딩과 언로딩에 관해 좀더 미세한 컨트롤을 원하면Resources.Load
/ Object.Destroy을 사용하세요.
OS 에게 얼마나 메모리가 남아 있는지 물어보는 것은 사용자 프로그램이 얼마나 잘 돌아가고 있는지 알아보는 좋은 방법인듯 합니다.
하지만 이것은 실제 그렇지 않은데 왜냐하면 OS 는 많은 동적 버퍼와 캐쉬를 이용하기 때문입니다. 항상 사용자 프로그램의 메모리
사용을 확인하고 이것을 주요 통계로 사용하세요. 그것만이 가장 믿을만한 방법일 것입니다. 그저 OS 에게 얼마나 메모리가 남았나
물어보는 것은 별 소용이 없습니다. 툴에서 그래프가 위의 변화를 어떻게 보여주는지 주의깊게 보세요. 특히 새로운 레벨이 로딩된
후에 주의하세요.
게임이 Xcode 에서는 잘 시작되었는데 수동으로 장치에서 시작될 때 첫 번째 레벨 로드에서 크래쉬합니다.
몇 가지 이유가 있을 수 있습니다. 좀더 자세한 정보를 위해 장치 로그를 볼 필요가 있습니다. 장치를 맥에 연결하고 Xcode를
싲가하고 Xcode메뉴의 Window->Organizer로 가서 Organizer의 왼쪽 툴바에서 사용자 장치를 선택하고 "Console" 탭을 클릭하고
최근 메세지를 리뷰합니다. 추가로 크래쉬 리포트를 볼 필요가 있습니다. 어떻게 크래쉬 리포트를
얻는지는:http://developer.apple.com/iphone/library/technotes/tn2008/tn2151.html.
Xcode Organizer 콘솔이 "killed by SpringBoard"를 포함합니다.
iOS 프로그램에서는 첫 번째 프레임을 렌더하고 입력을 처리하는데 걸리는 시간의 제한에 대한 것은 잘 문서화 되지 않았습니다.
사용자 프로그램이 이 제한을 넘기게 되면 SpringBoard 에 의해 종료되게 됩니다. 전형적인 경우는 프로그램이 큰 첫 번째 씬을
가졌을 때입니다. 이 문제를 피하기 위해서는 스플래쉬 화면만 보여주고 하나나 두 개의 프레임을 기다리면서 실제 씬의 로드를
시작하는 작은 초기 씬을 만들 것을 권합니다. 이것을 위한 코드 샘플:
function Start () {
yield;
Application.LoadLevel("Test");
}
Type.GetProperty() / Type.GetValue()가 장치에서 크래쉬를 야기합니다
현재 Type.GetProperty()와 Type.GetValue()는 .NET 2.0 Subset 에서만 지원합니다. Player Settings 에서 .NET API 호환
레벨을 선택합니다.
주의: Type.GetProperty()와 Type.GetValue()는 managed code stripping 과 호환되지 않을 수 있으며 사용자 정의의 스트리핑이
되지 않는 타입 리스트를 제공함으로써 스트리핑을 사용하는 타입을 제외시켜야 할수도 있습니다. 좀더 자세한 사항은 iOS player
size optimization guide 을 보세요.
게임이 다음 에러와 함께 크래쉬합니다 "ExecutionEngineException: Attempting to JIT compile method
'SometType`1<SomeValueType>:.ctor ()' while running with --aot-only."
iOS 의 Mono .NET 구현은 AOT(ahead of time compilation to native code) 기술에 기반을 둡니다. 이 기술은 자체의 한계를 가집니다.
이것은 다른 코드에의해 사용되는 그 generic 타입의 함수(값 타입이 generic 파라미터로 사용 되었을 때)만을 컴파일합니다. 그런
함수가 반사나 본래의 코드(즉 serialization 시스템)를 통해 사용이 되면 AOT 컴파일 도중에 스킵됩니다. AOT 컴파일러는 모의
함수를 스크립트 어딘가에 추가함으로써 코드를 추가하라는 것을 알려주고 없는 함수를 터치하여 미리 컴파일 되게 합니다.
void _unusedMethod()
{
var tmp = new SometType<SomeValueType>();
}
주의: 값 타입은 기본 타입, enums, structs 입니다.
System.Security.Cryptography 과 managed code stripping 의 조합이 장치에서 겪는 다양한 크래쉬
.NET 암호화 서비스는 반사에 크게 의존하므로 정적 코도 분석에 의존하는 managed code stripping 과 호환되지 않습니다. 가끔
가장 쉬운 방법은 스트리핑 프로세스에서 모든 System.Security.Crypography 네임스페이스를 제외 시키는 것입니다.
스티리핑 프로세스는 사용자 정의된 link.xml 파일을 유니티 iOS 에셋폴더에 추가함으로써 사용자 정의 할 수 있고 어떤 타입 또는
네임스페이스를 스트리핑에서 제외 시켜야 하는지 지정합니다. 좀더 자세한 사항은 iOS player size optimization guide 을 보세요.
link.xml
<linker>
<assembly fullname="mscorlib">
<namespace fullname="System.Security.Cryptography" preserve="all"/>
</assembly>
</linker>
"Ran out of trampolines of type 1/2" runtime error
이 에러는 보통 사용자가 많은 recursive generics 을 사용하면 발생 합니다. 사용자는 첫번째 두번째 타입을 더 할당하기 위해
AOT 컴파일러에게 힌트를 줍니다. 추가적인 AOT 컴파일러 명령어 라인 옵션은 PlayerSettings 의 다른 설정 옵션에서 지정될 수
있습니다. Type 1 trampolines 은 nrgctx-trampolines=ABCD 를 지정합니다. 여기서 ABCD 는 새로운 trampoline count (즉
4096)입니다. Type 2 trampolines 은 nimt-trampolines=ABCD 을 지정합니다.
iOS 에서의 버그 크래쉬 리포팅
"크래쉬 되었습니다"라고 버그에 대해 보내시기 전에 이 페이지를 보십시오. iOS Troubleshooting. 어떻게 게임을 디버그하고
중요하지만 숨겨진 정보를 찾을 수 있습니다.
Xcode 디버거에서 프로그램이 크래쉬하면 아래 절차를 따르세요:
1.
Continue (Run->Continue)를 두번 누릅니다
2.
디버거 콘솔을 열고 (Run->Console) 콘솔에 다음을 입력합니다: thread apply all bt
3.
콘솔 출력을 모두 복사한후 사용자 버그 리포트와 함께 보내세요.
iDevice 에서 프로그램이 크래쉬 되었지만 Xcode 디버거에서 실행될 때는 그렇지 않다면 다음 절차를 따르세요:
1.
다음의 애플 웹사이트에 설명되어 있는 것처럼 크래쉬리포트를
얻습니니다: http://developer.apple.com/iphone/library/technotes/tn2008/tn2151.html#ACQUIRING_CRASH_REPORTS
2.
크래쉬리포트와 사용자 프로그램과 콘솔 로그를 버그 리포트에 첨부합니다
안드로이드 개발 시작하기
안드로이드 개발
안드로이드 OS 가 실행되는 장치에서 게임을 빌드하는 것은 iOS 개발과 같은 접근을 필요로 합니다. 그러나 장치의 하드웨어는
완전히 표준화 되지는 않았습니다. 이것은 iOS 개발에서 일어나지 않는 문제들을 만듭니다. 안드로이드 버전 유니티에는 iOS 버전에
있는 것처럼 조금다른 기능이 있습니다.
안드로이드 개발 환경 설정하기
유니티 안드로이드 게임을 실제 장치에서 실행하기 전에 안드로이드 개발 환경을 설정해야 합니다. 이것은 다른 안드로이드
플랫폼에서 안드로이드 SDK를 다운로드하고 설치하는 것 그리고 실제 장치를 사용자 시스템에 추가하는 것을 포함합니다(사용자가
윈도우즈에서 또는 맥에서 개발하느 냐에 따라 조금씩 다릅니다). 이 설정 프로세스는 안드로이드 개발자 웹사이트에 설명되어
있으며 사용자 장치의 제조사에 의한 추가 정보도 있을 수 있습니다. 이것은 복잡한 과정이므로 안드로이드 장치나 에뮬레이터에서
사용자의 코드를 실행하기 전에 완성해야 하는 일의 기본 개요를 제공합니다 basic outline 그러나 가장 좋은 방법은 Android
developer portal의 지시를 따르는 것입니다.
안드로이드 기능 액세스하기
유니티 안드로이드는 다양한 입력 데이터와 설정에 대한 액세스를 위해 하나의 스크립트 API 를 제공합니다. 그 새로운 스크립트
클래스에 대해 더 많은 정보를 원하면 Android scripting page 를 보세요.
Native C, C++ or Java 코드 스크립트에 노출하기
유니티 안드로이드는 C# 스크립트에서 C/C++로 쓰여진 사용자 정의 함수를 부르는 것을 가능하게 합니다. 어떻게 함수들을
연결하는지 좀 더 알고 싶으면 plugins page 를 보세요.
Occlusion Culling
유니티 안드로이드는 “occlusion culling”을 지원하는데 이것은 많은 객체로 이루어진 복잡한 씬에서 최대의 성능을 내게하는데
완변한 것입니다. “occlusion culling”가 어덯게 작동하는 지는 occlusion culling 페이지를 보세요.
스플래쉬 화면 사용자 정의
장치에서 사용자 게임을 시작했을 때 보이는 화면인 스플래쉬 화면을 사용자 정의하고 싶으면 splash screen customization page 를
방문하세요.
문제 해결
사용자 프로그램이 크래쉬하고 작동하지 않는데는 많은 이유들이 있습니다. how to troubleshoot on Android 여기를 보세요.
안드로이드 크래쉬 보그 리포트하기
버그를 제출하기 전에 Android troubleshooting page 을 처음으로 보세요. 이것이 문제를 해결하지 못하면 reporting an Android
bug 으로 가세요.
유니티 안드로이드가 데스크탑 유니티와 어떻게 다르나요
Strongly Typed JavaScript
JavaScript 의 동적 타입은 유니티 안드로이드에서 항상 꺼져 있습니다. 이것은 스크립트에 #pragma strict 를 추가하는 것과 같은데
대신 이것이 기본 입니다. 이것은 성능을(iPhone 과 iPad 장치에서 매우 중요합니다) 현저히 향상 시킵니다. 기존의 유니티
프로젝트를 시작할 때 사용자가 동적 타입을 이용하면 컴파일러 에러를 보게될 것입니다. 이것은 에러를 일으키는 변수에 정적
타입을 사용하거나 타입 인터페이스를 이용합니다.
지형 엔진
지형 엔진은 안드로이드 장치에서는 아직 지원되지 않습니다. 지형 엔진은 현대 PC GPU 에서 작동하도록 만들어 졌으며 현재
안드로이드에 맞게 작게 만들어 질수 없습니다. 사용자 정의된 다각 메쉬나 “occlusion culling”를 사용하는 것이 안드로이드 장치에서
지형을 만드는데 최선의 방법입니다.
추천하는 텍스트 압축 ETC
유니티 안드로이드가 DXT/PVRTC/ATC 텍스쳐를 지원하는 반면, 유니티는 만약 그 압축 함수가 실제 하드웨어에서 지원이 되지
않으면 그 텍스쳐를 실행 중에 RGB(A) 형식으로 압축을 풉니다. 이것은 GPU 렌더링 속도에 영향을주며 대신 ETC 형식을 사용하는
것을 권합니다. ETC 압축은 안드로이드에서 표준 압축으로 여겨지며 모든 2.0 장치에서 지원되어야 합니다. 그러나 ETC 는 alpha
channel 을 지원하지 않고 텍스쳐 사용에 따라 RGBA 16-bit 이 크기, 퀄리티 와 렌더링 속도간의 최고의 트레이드 오프일 것입니다.
또한 별개의 안드로이드 분배 아카이브(.apk)를 각 DXT/PVRTC/ATC 형식을 위해 만들고 안드로이드 마켓 필터가 다른 장치를 위해
정확한 아카이브를 선택하도록 할수 있습니다 (Publishing Builds for Android 를 보세요).
동영상 플레이백
동영상 텍스쳐는 안드로이드에서 지원되지 않습니다. 그러나 전체화면 스티리밍 플레이백은 스크립트 함수를 통해 제공됩니다.
지원되는 파일 형식과 스크립트 API를 위해 movie page 또는 Android supported media formats page를 보세요.
Further Reading
•
안드로이드 SDK 셋업
•
안드로이드 리모트
•
안드로이드 문제 해결
•
안드로이드 버그 보고
•
안드로이드 미지원 기능
•
안드로이드 플레이어 세팅
•
안드로이드 API
o
안드로이드 인풋
o
안드로이드 키보드
o
안드로이드 고급
o
안드로이드 .Net
•
안드로이드 플러그인
•
안드로이드 스플래쉬 스크린
•
안드로이드 테스트 된 기기
•
안드로이드 이클립스와 유니티 연동
o
안드로이드 유니티에서 안드로이드 앱 런칭하기
안드로이드 SDK 설정
안드로이드 장치에서 코드를 빌드하고 실행하기 전에 반드시 따라야하는 절차가 있습니다. 이것은 유니티를 사용하건 안드로이드
프로그램을 처음부터 작성하건 상관 없이 적용됩니다.
1. 안드로이드 SDK 다운로드
Android Developer SDK webpage로 갑니다. 최신 안드로이드 SDK를 다운로드하고 풀어줍니다.
2. 안드로이드 SDK 설치
Installing the SDK에 있는 지시를 따르고 이클립스에 관한 선택 부분은 넘어가도 됩니다.Installing the SDK 의 네번째 스텝에서는
API레벨 9 상(플랫폼 2.3 이상), Platform Tools 그리고 윈도우즈를 사용하면 USB drivers 를 가진 적어도 하나의 Android
platform을 추가하게 합니다.
3. 사용자 시스템에 장치 인식시키기
이것은 장치 드라이버가 주로 문제가 되는 윈도우에서 특히 더 까다롭습니다. 또한 사용자 장치는 제조사에서 추가의 정보와 특정
드라이버와 함께 나오기도 합니다.
•
Windows: 만약 안드로이드 장치가 자동으로 시스템에서 잡히면 안드로이드 SDK 와 함께 나오는 드라이버로 업데이트할 필요가
있습니다. 이것은 Windows Device Manager 을 통해 이루어 집니다.
만약 장치가 자동으로 잡히지 않으면 안드로이트 SDK 의 드라이버를 사용합니다. 또는 제조사에서 나오는 특정
드라이버를 사용합니다.
추가적인 정보는 여기서 찾을수 있습니다: USB Drivers for Windows
•
Mac: 맥을 사용하고 있으면 보통 추가적인 드라이버는 필요로하지 않습니다.
주의: 사용자 장치의 "USB Debugging" 를 켜는 것을 잊지 마세요. 이것은 홈스크린에서 할 수 있습니다: press MENU, MENU 를
누르고 Applications > Development 선택, 그리고 USB debugging 활성화.
시스템에 장치가 제대로 설치되었는지 확실하지 않으면 trouble-shooting page 를 읽으세요.
4. 유니티에 안드로이드 SDK 경로 추가하기
안드로이드를 위한 프로젝트를 처음으로 빌드하면(도는 유니티가 나중에 SDK 가 어디있는지 알아내지 못하면) 사용자가 어디에
안드로이드 SDK 를 설치하였는지 질문을 받게 됩니다. 안드로이드 SDK 의 루트 폴더를 지정해 주세요. 안드로이드 SDK 의 위치는
에디터에서 Edit 에 가서 Preferences 를 바꿈으로써 바꿀 수 있습니다.
안드로이드 리모트(Android Remote)
안드로이드 리모트(Android Remote)는 사용자의 유니티 프로젝트에서 안드로이드 장치를 원격 제어처럼 만들어주는 소프트웨어
프로그램입니다. 이것은 매 변화를 컴파일없이 프로젝트에 적용하고 싶고 그 대신 Editor Game 창을 이용하고 싶은 때 빠른 개발을
위해 아주 유용합니다.
안드로이드 리모트 사용법?
성공적인 안드로이드 리모트를 이용하기 위해서는 다음 단계를 잘 따르십시오.
•
최신 안드로이드 SDK 설치를 확인 하십시오. 사용자의 안드로이드 장치를위한 port forwarding 을 설치하여야 합니다.
•
안드로이드 장치를 USB 케이블을 통해 사용자 컴퓨터에 연결하십시오.
•
장치에서 안드로이드 리모트 프로그램을 시작합니다.
•
유니티 에디터에서 “Play”를 누리십시오. 이 시점에서 장치에서 에디터로 가속도계와 터치 인풋 장치를 보낼 수 있으며 에디터에서
장치로 압축된 스크린샷의 스트림을 받을 수 있습니다.
•
끝나면 에디터에서 겜임을 종료하고 안드로이트 리모트 프로그램은 기본 화면으로 돌아갈 것입니다.
유니티 리모트
Unity Remote 를 읽어 주십시오.
Android
안드로이드 개발 문제 해결
유니티가 사용자 프로그램을 장치에 설치 실패
1.
사용자 컴퓨터가 실제로 장치를 감지하고 연결 되었는지 확인합니다. 좀 더 자세한 사항은 Publishing Builds 에 있습니다.
2.
유니티 콘솔에서 빨간 사인으로 마크 되어있는 에러를 찾으세요. 그것을 유용한 에러 메세지 일 것입니다.
사용자 프로그램이 시작 후 바로 크래쉬 합니다.
1.
NativeActivity 를 지원하지 않는 장치와 사용하려 하지 마세요.
2.
사용자가 가지고 있는 본래의 플러그인을 제거하도록 하세요.
3.
스트리핑을 비활성화 하도록 하세요.
4.
크래쉬 리포트를 얻기위해 adb logcat 를 사용합니다.
DEX 빌스 실패
이것은 아래와 같이 자신을 나타낼 에러입니다
Building DEX Failed!
G:\Unity\JavaPluginSample\Temp/StagingArea> java -Xmx1024M
-Djava.ext.dirs="G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/"
-jar "G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/dx.jar"
--dex --verbose --output=bin/classes.dex bin/classes.jar plugins
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
이것은 주로 컴퓨터에 잘못된 버전의 Java 가 설치 되었을 때 입니다. 자바를 최신 버전으로 설치하고 이것은 이 문제를 해결할
것입니다.
슬립 버튼을 누르면 게임이 종료됩니다
here에 설명된 <android:configChanges> 태그를 포함하기 위해 AndroidManifest.xml 에 있는 <activity> 태그를 바꾸세요.
예제 활동 태그는 다음과 같습니다:
<activity android:name=".AdMobTestActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
안드로이드에서 충돌 버그 리포팅
메세지 내용에 단순히 “프로그램이 충돌했습니다.”라고 버그를 보내기 전에 Troubleshooting Android development 페이지를 먼저
봐주십시오.
현재 장치안에서의 앱 충돌 디버그하기 위한 고급 툴은 존재하지 않습니다. 하지만 logcat 매개 변수와 함께 adb 프로그램(AndroidSDK/platform-tools 에 있음)을 사용할 수 있습니다. 그것은 당신의 장치에 대한 상태 보고를 보여줍니다. 이 보고는 발생한 충돌에
대한 정보를 포함할 수 있습니다.
만약 그 충돌이 유니티 소프트웨어의 버그에 의한 것이 확실하다면 adb logcat 결과물을 저장해서 repro 프로젝트 수행 후
bugreporter(Help/Report a bug)를 이용해서 저희에게 알려주십시오. 가능한 빨리 답변드리겠습니다.
유니티 안드로이드에서 현제 지원하고 있지 않은 기능들
그래픽스
•
정사각형이 아닌 텍스쳐는 ETC 포멧에서 지원하지 않습니다.
•
동영상 텍스쳐는 지원하지 않으며, 대신 전체화면 스트리밍 플레이백을 사용하십시오. 좀 더 자세한 내용은 Movie playback page 을
보십시오.
•
지형 엔진은 지원되지 않습니다.
스크립팅
•
OnMouseEnter, OnMouseOver, OnMouseExit, OnMouseDown, OnMouseUp, and OnMouseDrag 이벤트는 안드로이드에서 지원되지
않습니다.
•
Duck Typing 과 같은 동적 기능은 지원되지 않습니다. 컴파일러가 동적기능을 오류로 보고하기 위해서는 스크립트에서#pragma
strict 를 사용하십시오.
•
WWW 클래스를 통한 동영상 스트리밍은 지원되지 않습니다.
Android
Resolution And Presentation
안드로이드 프로젝트 빌드를 위한 Resolution 과 presentation.
Property:
Function:
Resolution
Default Orientation
(iOS 와 안드로이드 장치에서 공유하는 설정입니다.)
Portrait
이 장치는 세로 모드입니다. 장치가 똑바로 서있고 홈 버튼이 아래쪽에 위치합니다.
Portrait Upside Down
이 장치는 뒤집어진 세로 모드입니다. 장치가 똑바로 서있고 홈 버튼이 상단에 위치합니다.
Landscape Right
이 장치는 가로모드 입니다. 장치가 똑바로 서있고 홈 버튼이 좌측에 위치합니다.
Landscape Left
이 장치는 가로모드 입니다. 장치가 똑바로 서있고 홈 버튼이 우측에 위치합니다.
Icon
프로젝트 빌드 시 가지게 될 아이콘들.
Property:
Function:
Override for
안드로이드게임을 위해 사용될 커스텀 아이콘을 지정하고 싶으면 선택합니다. 여러 크기의 아이콘이 아래
Android
정사각형을 채워야 합니다.
SplashImage
프로텍트 시작시 보여질 Splash image.
Property:
Function:
Mobile Splash Screen (Pro-
iOS Splash 화면에 사용될 텍스쳐를 지정합니다. 기준 Splash 화면 사이즈는 320x480.(이것은
only feature)
안드로이드와 iOS 에서 공유됩니다.)
Splash Scaling
장치에서 splash 이미지의 크기를 어떻게 정할지 정합니다.
Other Settings
안드로이드 빌드의 다른 설정들.
Rendering
Static Batching
빌드시 Static batching 사용을 원할시 체크(기본으로 활성화 되어있음). Unity Pro 에서만 지원.
Dynamic Batching
빌드시 Dynamic Batching 사용을 원할 시 체크 (기본적으로 활성화 되어있음).
Identification
사용자의 애플 개발자 네트워크 계정에서 사용자 공급 인증에 사용되는 문자열 (이것은 iOS 와
Bundle Identifier
안드로이드에서 공유됩니다)
출시 되었거나 그렇지 않은 번들의 반복을 나타내주는 빌드 버전 넘버를 정해줍니다. 이것은 하나 이상의
Bundle Version
구간구분으로 구성 되어진 일정하게 증가하는 문자열 입니다
내부 버전 넘버. 이 넘버는 하나의 버전이 다른 버전보다 최근 것인지를 결정할 때만 쓰이는데 높은 넘버가
최근 버전을 의미합니다. 이것은 versionName 속성에서 정의되는 유저에게 보여지는 버전 넘버와 다릅니다.
Bundle Version
Code
그 값은 100 과 같은 정수이어야 합니다. 사용자는 이것을 나중 버전이 높은 넘버만 갖는다면 원하는데로
정의할 수 있습니다. 또는 버전 넘버를 정수 x 와 y 를 각 위 아래 16bit 에 저장함으로써 x.y 형식으로 해석할
수도 있습니다. 또는 간단히 새로운 버전이 나올 때마다 1 씩 늘려도 됩니다.
Configuration
Device Filter
빌드할 대상 아키텍처를 지정 합니다.
프로그램이 ARMv7 CPU 아키텍쳐에 최적화 되어있음. 이것은 또한 정확한 안드로이드 마켓 장치 필터링을
ARMv7 only
활성화 해서 안드로이드 마켓에 게시 할때 추천합니다. (Unity 안드로이드를 지원하는 장치에서만
안드로이드 마켓에 이 프로그램을 보여줍니다.)
프로그램이 ARMv6 CPU 아키텍쳐(VFP 지원을 필요로함)에 최적화 되어있음. 안드로이드 마켓의 필터링
기능에 의존하기 보다는 하드웨어의 실행 탐지(runtime detection) 기능을사용하십시오. 이것은 안드로이드
ARMv6 with VPF
마켓에 게시 되었을 때 Unitiy 안드로이드를 지원하지 않는 장치에서도 프로그램이 보여지게 됨을
말해줍니다. 물론 이것을 추천하지는 않습니다. 특히 유료 프로그램이라면 더욱 그렇습니다. (대신
OpenGLES 버전과 같이 다른 필터링과 같이 합쳐질 수 있습니다.)
Emulator
안드로이드 SDK Emulator 의 지원과 함께 빌드를 생성할 것입니다.
Graphics Level
ES 1.1 ('fixed function') 나 ES 2.0 ('shader based') Open GL level 을 선택하십시오
Force Internet
사용자의 스크립트가 네트워크를 사용하지 않아도 네트워크 퍼미션을 활성화 할것입니다. 개발 빌드를 위해
Permission
자동으로 활성화 되어있음.
Force SD-Card
SD-Card 같은 외장 스토리지의 접근을 활성화 합니다. 개발 빌드를 위해 자동으로 활성화 되어있음.
Permission
Use NativeActivity 화면이외의 Xperia Play 같은 터치 입력 기능을 지원하기 위해서 활성화 하십시오.
Optimization
Api Compatibility
활성화된 .NET API profile 을 지정합니다
Level
.Net 2.0
.Net 2.0 라이브러리. 최대 .net 호환, 최대 파일 크기
.Net 2.0 Subset
부분 적인 .net 호환, 작은 파일 크기
Stripping Level
빌드된 플레이어 사이즈를 줄이기위해 스크립팅 기능들을 제거하는 옵션. (이 설정은 iOS 에서과
(Pro-only feature) Android 플랫폼에서 공유되어 집니다.)
Disabled
감소가 행해지지 않음.
Strip Assemblies
Level 1 크기 감소.
Strip ByteCode
(iOS only)
Level 2 크기 감소(Level 1 크기 감소를 포함함).
Use micro mscorlib Level 3 크기 감소(Levels 1 과 2 크기 감소를 포함함).
Enable "logcat"
프로젝트 테스트 중 사용자의 장치에서 피드백을 받고 싶으시면 활성화 하십시오. 그래서 adb logcat 이
profiler
장치에서 콘솔로 로그를 프린트 합니다. (개발 빌드에서만 가능 합니다.).
Publishing Settings
안드로이드 마켓에서의 게시 설정
Property:
Function:
Keystore
Use Existing Keystore / Create New
새로운 Keystore 를 사용하기위해 사용하십시오. 그렇지 않으면 기존의 Keystore 를
Keystore
사용합니다.
Browse Keystore
기존 Keystore 를 선택하게 해줍니다.
Keystore password
Keystore 를 위해 암호.
Confirm password
암호 확힌, Create New Keystore 옵션이 선택 되었을 때만 활성화 됩니다.
Key
Alias
키 가명
Password
키 가명을 위한 암호
안드로이드 마켓 라이센싱(LVL)
Android developer site에서 제공되는 공개 키.
Public Key
보안을 이유로 Unity 는 어떤 Keystore 암호나 Key 암호를 저장하지 않는것에 주의하십시오. 또한 사인잉은 Unity 의 player 설정에서
이루어져야 함을 명심하십시오. (jarsigner 는 되지 않습니다.).
안드로이드 스크립팅
유니티 안드로이드는 핸드헬드 장치 기능에 접근할 수 있는 몇가지 스크립팅 API 를 제공합니다. 다중 플랫폼 프로젝트를
위해서안드로이드 만을위한 C#코드의 제한적 컴파일을 위해 UNITY_ANDROID 가 정의되어 있습니다. 다음의 스크립팅 클래스들은
안드로이와 관련된 변화를 포함하고 있습니다 (어떤 API 는 안드로이드와 iOS 에서 공유될 수 있습니다):
Input
멀티 터치 스크린, 가속도계 및 장치 방향에 관한 접근.
iPhoneSettings
화면 방향, 어두워짐, 장치 하드웨어에 관한 정보 등에 관한 안드로이드 설정.
iPhoneKeyboard
기본 화면 키보드에 대한 지원.
iPhoneUtils
동영상 재생, 불법 복제 방지 보호및 진동을 위한 유용한 기능들.
Further Reading
•
안드로이드 인풋
•
안드로이드 키보드
•
안드로이드 고급
•
안드로이드 .Net
Android
유니티 안드로이드는 시스템 키보드를 보여주기 위해 iOS API 를 재사용합니다. 유니티 안드로이드가 대부분의 iPhone 의 기능을
지원하지만 지원되지 않는 두가지가 있습니다:
•
iPhoneKeyboard.hideInput
•
iPhoneKeyboard.area
또한 iPhoneKeyboardType 의 레이 아웃이 장치마다 조금씩 다를 수 있음에 주의하세요.
Android
고급 iOS 스트립팅
장치 세대 정하기
장치의 다른 세대는 다른 기능을 지원하고 다양한 성능차이를 보입니다. 사용자는 느린 장치의 성능 보완을 위해 어떤 기능을
비활성화 해야하는지 결정하기 위해 장치의 세대를 물어보아야 합니다. 사용자가 접근해서 장치의 세대를 알아낼 수 있는 몇가지
장치별 속성이 있습니다.
주의: 안드로이드 마켓플레이스는 추가적인 호환 필터링을 합니다. 그래서 OGLES2 에서만 최적화된 유일한 앱인 ARMv7 이 어떤
오래되고 느린 장치에서 제공되는지 신경쓸 필요가 없습니다.
장치 속성
Property:
Function:
iPhoneSettings.uniqueIdentifier 유일한 장치 식별자.
iPhoneSettings.model
iPhone 인지 iPod Touch 인지 알려줌
iPhoneSettings.systemName
운영체제.
SystemInfo.operatingSystem
운영체제버전.
불법 복제 방지 체크
해커가 앱스토어의 응용 프로그램에서 애플 DRM 방지를 제거하고 무료로 재배포하는 일은 흔한 일입니다. 유니티 iOS 는 앱스토에
프로그램 제출후 프로그램에 변화가 있는지 확인하는 불법 복제 방지 기능이 있습니다.
사용자는 iPhoneUtils.isApplicationGenuine 속성에 접근함으로써 프로그램이 해킹되었는지 확힌할 수 있습니다. 만약 이 속성이
false를 리턴하면 유저에게 해킹당한 프로그램을 사용 중이라 알릴수 있고 또는 프로그램의 어떤 기능을 비활성화 시킬 수있습니다.
주의: iPhoneUtils.isApplicationGenuineAvailable 속성에 접근하는 것은 성능에 많은 영향을 주는 작업이며 절대 프레임 단위로
접근해서는 안됩니다.
주의: iPhoneUtils.isApplicationGenuine 속성에 접근하는 것은 성능에 많은 영향을 주는 작업이며 절대 프레임 단위로 접근해서는
안됩니다.
진동 지원
사용자는 iPhoneUtils.Vibrate. 을 부름으로써 iOS진동을 일으킬 수 있습니다. 그러나 iPod Touch장치는 진동 하드웨어가 없으며 그
부름은 무시될 것입니다.
기준 에셋
"기준 에셋(Standard Assets)" 은 특별한 의미 (same as "Plugins" and "Editor) 를 지닌 폴더이고 그것의 내용은 다른 모든 스크립트
보다 먼저 컴파일 됩니다. 스크립트는 특별한 이름을 가지지 않은 폴더에 저장하여야 합니다.
Android
유니티 안드로이드는 두가지 .NET API 호환 레벨을 지원합니다: .NET 2.0 그리고 부분적인 .NET 2.0. 사용자는 classPlayerSettings 에서 알맞은 레벨을 선택할 수 있습니다.
.NET API 2.0
안드로이드를 목표로한 유니티는 .NET 2.0 API 프로파일을 지원합니다; 이것은 전체 .NET 2.0 API 와 흡사하며 기존의 .NET 코드와
최상의 호환성을 제공합니다.
장점:
1.
더 낳은 데스크탑 유니티와 타사 라이브러리의 코드 호환성
2.
기준 API 의 더 많은 기능들
단점:
1.
응용 프로그램 빌드 크기가 커짐
2.
약간 나빠지는 응용 프로그램 시작 타임
주의: 유니티 안드로이드는 스크립트에 네임스페이스(namespace)를 지원하지 않습니다. 만약 타사의 라이브러리가 코드와 함께
존재한다면 그 라이브러리를 유니티 iOS 에디터 외부에서 컴파일하고 .dll 라이브러리를 에셋 폴더에 넣는 것이 최선입니다.
.NET 2.0 Subset
유니티 iOS 타겟은.NET 2.0 Subset API 프로파일 또한 지원합니다. 이것은 Mono “monotouch”프로파일에 가장 가까우므로
“monotouch”프로파일에 적용되는 많은 제한들 또한 이 .NET 프로파일의 유니티 iOS 구현에 적용됩니다. “monotouch”프로파일의
제한들에 대한 더 많은 정보는 here에서 볼수 있습니다.
장점:
1.
특히 스트립핑이 쓰이지 않았을 때 작은 응용 프로그램 배포 사이즈
단점:
1.
기준 그리고 타사 라이브러리와의 나쁜 호환성
Android
안드로이드 플러그인 빌드하기
안드로이드 플러그인을 시작하려면 Android NDK가 필요합니다. 어떻게 공유 라이브러리를 만드는지에 익숙해 지세요.
플러그인을 만드는데 C++ (.cpp)를 사용한다면 name mangling issues를 피하기 위해 함수가 C linkage와 선언되야 합니다.
extern "C" {
float FooPluginFunction ();
}
C#에서 플러그인 사용하기
일단 공유 라이브러리를 만들면 그것을 Assets->Plugins->Android 폴더에 복사합니다. 유니티는 아래와 같은 함수를 정의할때
이름으로 그것을 찾을 것입니다:
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
PluginName은 ‘lib’로 시작하거나 ‘.so’ 로 끝이나면 안되는 것을 명심하세요. 모든 기본 코드 함수를 추가적인 C#코드 레이어로
감싸기를 권합니다. 이 코드는 [[ScriptRef:Application-platform.html |
Application.platform]] 를 체크할 수 있고 실제 장치에서 실행될 때만 기본 함수를 부르며 에이터에서 실행될 때는 모의 값을
리턴합니다. 사용자는 플랫폼에 의존하는 코드 컴파일을 제어하기 위해
platform defines 를 사용할 수 있습니다.
배치
크로스 플랫폼 플러그인을 위해서는 플러그인 폴더가 몇가지 다른 플랫폼(즉 libPlugin.so 는 Android, Plugin.bundle 는 Mac 그리고
Plugin.dll 는 Windows)을 위한 플러그인을 포함합니다. 유니티가 자동으로 개발 플랫폼에 맞는 플러그인을 선택하고 플레이어에
포함합니다.
자바 플러그인 사용하기
안드로이드 플러그인 메카니즘은 또한 안드로이드 OS 와 상호작용을 가능하게 하는데 자바가 사용되는 것을 허용합니다. 자바
코드는 C#에서 직접 불릴 수 없으으로 사용자가 C#와 자바사이에서 그 콜을 해석하기 위해 기본 플러그인을 작성 합니다.
안드로이드에서 자바 플러그인 빌드하기
자바 플러그인을 만드는 것에는 몇가지 방법이 있습니다. 공통점은 필러그인에 필요한 .class 파일들을 포함하는 .jar파일로 끝난다는
것입니다. 한가지 방법은 JDK를 받는 것으로 시작해서 사용자 .java파일을 명령 라인에서 javac로 .class파일을 만들기 위해 컴파일
하고 그들을 jar 명령어 라인 툴을 이용해 .jar로 패기지화합니다. 다른 방법은 Eclipse IDE를 ADT와 함께 사용하는 것입니다.
기본 코드에서 자바 플러그인 사용하기
일단 자바 플러그인(.jar)을 만들었으면 Assets->Plugins->Android 폴더로 복사해야 합니다. 유니티는 .class파일과 나머지 자바
코드를 패키지화하고 Java Native Interface (JNI)라는 것으로 그것을 부릅니다. JNI는 두가지 방법으로 동작하는데; 자바에서 기본
코드 부르기 그리고 기본 코드에서 자바(또는 JavaVM)와 상호작용하기.
기본 코드에서 사용자 자바 코드를 찾기 위해서는 자바 VM 에 액세스 해야합니다. 다행히 그것은 매우 쉬운데 사용자의 C(++)코드에
다음과 같은 함수를 추가합니다:
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* jni_env = 0;
vm->AttachCurrentThread(&jni_env, 0);
}
이것이 C(++)에서 자바를 이용하기 전부 입니다. JNI 에 대한 완전히 설명하는 것은 이 문서의 내용을 넘어선 것이지만 클래스 정의
찾기, 생성자 (<init>) 함수 해결하기 그리고 아래와 같이 새로운 객체 인스턴스 만들기 등을 포함합니다:
jobject createJavaObject(JNIEnv* jni_env) {
jclass cls_JavaClass = jni_env->FindClass("com/your/java/Class");
// find class definition
jmethodID mid_JavaClass = jni_env->GetMethodID (cls_JavaClass, "<init>", "()V");
// find constructor method
jobject obj_JavaClass = jni_env->NewObject(cls_JavaClass, mid_JavaClass);
// create object instance
return jni_env->NewGlobalRef(obj_JavaClass);
// return object
with a global reference
}
헬퍼 클래스와 사용자 자바 플러그인 만들기
AndroidJNIHelper 와 AndroidJNI 는 JNI 사용을 쉽게해 줍니다.
AndroidJavaObject 와 AndroidJavaClass 는 많은 것을 자동화해주고 캐쉬를 사용해서 자바 콜을 빠르게 해줍니다.
AndroidJavaObject 와 AndroidJavaClass 조합은 AndroidJNI 와 AndroidJNIHelper 위에서 만들어 지고 그 안에 많은 로직이
있습니다(자동화를 다루는). 이런 클래스틀은 자바 클래스의 정적 멤버를 다루기 위해 ‘static’ 버전으로도 있습니다.
사용자가 원하는 어떤 방법을 사용해도 되지만 JNI 와 AndroidJNI 클래스 멤버 또는 AndroidJNIHelper 와 AndroidJNI 그리고 결국
최대 자동화와 편의를 위해 AndroidJavaObject/AndroidJavaClass 를 이용하세요.
•
UnityEngine.AndroidJNI는 C에 있는 JNI콜을 위한 wrapper입니다. 이 클래스의 모든 멤버는 static이며 Java Native Interface와
일대일 관계를 갖습니다.
•
UnityEngine.AndroidJNIHelper는 다음 레벨에서 사용 되는 헬퍼 기능을 제공하지만 아마 어떤 특별한 이유로 유용할 수 있기 때문에
public 함수로 사용 됩니다.
•
UnityEngine.AndroidJavaObject 와 UnityEngine.AndroidJavaClass
의 인스턴스는 각각 java.lang.Object 와 java.lang.Class (또는 서브클래스)의 인스턴스와 일대일 매핑이 됩니다. 그들은 자바와
3 가지 타입의 상호작용을 제공합니다:
•
함수 콜하기
•
필드 값 얻기
•
필드 값 지정하기
Call 은 두가지 타입이 있습니다:
'void'
리턴 타입으로 generic 타입이 사용됩니다.
Call 타입과
non-void return
Call
타입이 있습니다.
Get/Set 은 항상 generic 타입만을 취합니다.
Example 1
//The comments is what you would need to do if you use raw JNI
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");
// jni.FindClass("java.lang.String");
// jni.GetMethodID(classID, "<init>", "(Ljava/lang/String;)V");
void 타입이 아닌 콜은
// jni.NewStringUTF("some_string");
// jni.NewObject(classID, methodID, javaString);
int hash = jo.Call<int>("hashCode");
// jni.GetMethodID(classID, "hashCode", "()I");
// jni.CallIntMethod(objectID, methodID);
여기서는 java.lang.String의 인스턴스를 만들고 있으며 초기화하고 그 스트링을 위해
hash value를 되찾습니다.
AndroidJavaObject 생성자는 적어도 하나의 파라미터를 취합니다: 인스턴스를 생성하고자 하는 클래스의 이름. 클래스 이름 뒤에
있는 것은 모두 객체의 생성자 콜을 위한 파라미터이며 이 경우 스트링은 "some_string". 그러면 Call 함수에서 왜 generic 타입을
파라미터로 사용하는 지에 대한 이유인 int 를 리턴하는 hashCode()를 사용합니다.
주의: dotted notation 를 사용해서 중첩 자바 클래스를 인스턴스화 할 수 없습니다. 내부 클래스는 $ 분별자를 사용해야하며 이것은
점과 슬래스 형식에서 모두 작동할 것입니다. 그래서 LayoutParams 클래스가 ViewGroup 클래스가 중첩되었을
때 android.view.ViewGroup$LayoutParams 또는 android/view/ViewGroup$LayoutParams 가 사용될 수 있습니다.
Example 2
위 샘플 플러그인중 하나는 어떻게 현 프로그램을 위한 캐쉬 디렉토리를 얻을 수 있는지를 보여줍니다:
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
// jni.FindClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
// jni.GetStaticFieldID(classID, "Ljava/lang/Object;");
// jni.GetStaticObjectField(classID, fieldID);
// jni.FindClass("java.lang.Object");
Debug.Log(jo.Call<AndroidJavaObject>("getCacheDir").Call<string>("getCanonicalPath"));
// jni.GetMethodID(classID, "getCacheDir", "()Ljava/io/File;"); // or any baseclass thereof!
// jni.CallObjectMethod(objectID, methodID);
// jni.FindClass("java.io.File");
// jni.GetMethodID(classID, "getCanonicalPath", "()Ljava/lang/String;");
// jni.CallObjectMethod(objectID, methodID);
// jni.GetStringUTFChars(javaString);
여기서는 of AndroidJavaObject 대신 AndroidJavaClass 로 시작하는데 왜냐하면 사용자가 com.unity3d.player.UnityPlayer의
static멤버의 액세스를 원하며 새로운 객체 생성을 윈치 않습니다(이미 Android UnityPlayer에 하나가 만들어져 있습니다). 그러면
static필드인 “currentActivity”에 액세스하지만 이번에는 generic파라미터로 AndroidJavaObject 를 사용합니다. 왜냐하면 실제 필드
타입 ([[http://developer.android.com/reference/android/app/Activity.html |
android.app.Activity]])이 java.lang.Object 위 하위 클래스이기 때문이고 어떤
non-primitive type도 AndroidJavaObject (이 룰에 스트링은 예외인데 자바에서 primitive타입이 아니라도 스트링이 직접 액세스
될수 있습니다)로 액세스 되어야 하기 때문입니다.
그런 후 캐쉬 디렉토리를 대표하는 File객체를 얻기위해 이제
[[http://developer.android.com/reference/android/content/Context.html#getCacheDir() |
getCacheDir()]]를 통해 간단히 Activity를 이동하고 스트링 표현을 얻기위해
[[http://developer.android.com/reference/java/io/File.html#getCanonicalPath() |
getCanonicalPath()]]를 부르세요.
물론 요즘엔 캐쉬 디렉토리를 얻기위해 그럴 필요가 없습니다; 저희는
Application.temporaryCachePath, [[ScriptRef:Application-persistentDataPath.html |
Application.persistentDataPath]]를 통해 프로그램의 캐쉬와 파일 디렉토리 액세스를 제공합니다.
Example 3
마지막으로 UnitySendMessage 를 사용해 어떻게 데이타를 자바에서 스크립트 코드로 보내는지에 대한 작은 트릭입닌다.
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
void Start () {
JNIHelper.debug = true;
using (JavaClass jc = new JavaClass("com.unity3d.player.UnityPlayer")) {
jc.CallStatic("UnitySendMessage", "Main Camera", "JavaMessage", "whoowhoo");
}
}
void JavaMessage(string message) {
Debug.Log("message from java: " + message);
}
}
자바 클래스인 com.unity3d.player.UnityPlayer 은 이제 static 함수인 UnitySendMessage 를 가지며 이것은 iOS 의
[[KrMain.Plugins#iPhonePlugins |
UnitySendMessage]] 와 같고 자바에서 스크립트 코드로 데이터를 보낼 때 쓸수 있습니다.
그러나 여기서 우리는 그것을 스크립트 코드에서 직접 부릅니다. 그것은 결국 자바쪽으로 메세지를 전달하며 자바쪽에서는
“JavaMessage”라는 함수가 있는 “Main Camera”이라는 이름의 객체에 메세지 전달을 위해 유니티에서 콜백 합니다.
유니티에서 자바 플러그인을 사용하는 가장 좋은 방법들
이 섹션은 주로 JNI, Java, 안드로이드 경험이 많지 않은 사람을 목표로 했기에 우리는 AndroidJavaObject/AndroidJavaClass 접근이
유니티 자바 코드와 상호작용 한다고 가정합니다.
첫번째로 알아야 할것은 AndroidJavaObject / AndroidJavaClass 에서의 모든작업은 비싸다는 것입니다(JNI 접근 처럼). managed 와
native/java 사이의 변환을 최소화 하기를 권합니다. 이것은 성능과 복잡도 모두를 위한 것입니다.
기본적으로 자바 함수가 실제 모든 작업을 하게하고 AndroidJavaObject / AndroidJavaClass 를 이용해 그 함수와의 대화를 통해
결과를 얻을 수 있습니다. JNI 헬퍼 클래스로 가능한 많은 양을 캐쉬하려 한다는 것을 아는 것은 도움이 될 것입니다.
//The first time you call a Java function like
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string"); // somewhat expensive
int hash = jo.Call<int>("hashCode"); // first time - expensive
int hash = jo.Call<int>("hashCode"); // second time - not as expensive as we already know the java method and can call it
straight
이것은 JIT 와 같은 방법입니다: 그것을 처음에 콜할 때는 코드가 존재하지 않아 느릴 것입니다. 다음에는 빨라집니다. 다시 말해
모든 객체의 .Call /.Get / .Set 마다 대가를 치뤄야하지만 처음으로 콜한 다음에는 대가가 적다는 말입니다. AndroidJavaClass /
AndroidJavaObject 를 생성하는 데도 대가가 따릅니다.
Mono garbage collector 는 AndroiJavaObject / AndroidJavaClass 의 생성된 모든 인스턴스를 해제해야 하는데 그것을 $$using(){}
문에 두고 가능한 빨리 지워지도록 하기를 권합니다. 그렇지 않으면 그들이 언제 지워질지 장담할 수 없습니다.
AndroidJNIHelper.debug =
true;$$ 를 설정하면 디버그 출력문이 Garbage Collector 의 행동도 보여줄 것입니다.
//Getting the system language with the safe approach
void Start () {
using (AndroidJavaClass cls = new AndroidJavaClass("java.util.Locale")) {
using(AndroidJavaObject locale = cls.CallStatic<AndroidJavaObject>("getDefault")) {
Debug.Log("current lang = " + locale.Call<string>("getDisplayLanguage"));
}
}
}
사용자는 또한 자바 객체 lingering 을 없게 하기위해 .Dispose()함수를 직접 부를수 있습니다. 실제 C# 객체는 좀더 오래 존재할
수있는데 mono 에 의해 결국 가비지 콜렉트될 것입니다.
UnityPlayerActivity 자바 코드 확장하기
유니티 안드로이드는 UnityPlayerActivity(안드로이드 유니티 플레이어 주요 자바 클래스, 유니티 iOS 의 AppController.mm 와
비슷함)의 확장이 가능합니다.
UnityPlayerActivity (UnityPlayerActivity.java 는 맥의
/Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/src/com/unity3d/player 그리고 보통
C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\src\com\unity3d\player에서 찾을 수
있습니다)에서 유도된 새로운Activity 를 생성 함으로써 프로그램은 안드로이드 OS와 유니티 안드로이드의 어떤 또는 모든 기본
상호작용을 오버라이드할 수 있습니다.
그렇게 하기 위해서는 유니티 안드로이드에 있는 classes.jar를 찾습니다. 이것은 PlaybackEngines/AndroidPlayer/bin라고 불리는
설치 폴더(윈도우즈에서는 보통/Applications/Unity그리고 맥에서는/Applications/Unity)에서 찾을 수 있습니다. 그러면 classes.jar
파일을 새로운 활동을 컴파일하는 classpath에 추가합니다. manifest이 어떤 활동이 시작되어야 하는지 나타내듯이
새로운AndroidManifest.xml의 생성 또한 필요합니다. 그 AndroidManifest.xml 또한Assets->Plugins->Android에 위치하여야 합니다.
그 새로운 활동은 OverrideExample.java 처럼 보일 수 있습니다:
package com.company.product;
import com.unity3d.player.UnityPlayerActivity;
import android.os.Bundle;
import android.util.Log;
public class OverrideExample extends UnityPlayerActivity {
protected void onCreate(Bundle savedInstanceState) {
// call UnityPlayerActivity.onCreate()
super.onCreate(savedInstanceState);
// print debug message to logcat
Log.d("OverrideActivity", "onCreate called!");
}
public void onBackPressed()
{
// instead of calling UnityPlayerActivity.onBackPressed() we just ignore the back button event
// super.onBackPressed();
}
}
그리고 이것은 매치하는 AndroidManifest.xml 을 보여줍니다:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product">
<application android:icon="@drawable/app_icon" android:label="@string/app_name">
<activity android:name=".OverrideExample"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
어떻게 스플래시(splash) 화면을 만드나요?
게임 출판의 한 부분으로 장치에서 게임이 실행될 때 나타나는 스플래시 화면을 사용자 정의 할 수 있습니다. 유니티 iOS 기본
유저는 포함된 스플래시 화면의 두가지 다른 방향을 선택할 수 있으며 고급 유저는 자신만의 독특한 스플래시 화면을 만들기위해
어떤 텍스쳐도 사용할 수 있습니다.
스플래시 화면은 플레이어 설정에서 사용자 정의될 수 있습니다. 바람직한 스플래시 방향은 플레이어 설정(Resolution and
Presentation 섹션)에서 "Default Screen Orientation" 속성으로 명시되어 있습니다.
포함된 스플래시 화면 사용하기
사용자는 주어진 네가지 기본 스플래시 화면 방향 중 하나를 택합니다:
1.
세로 - 유저 인터페이스와 스플래시 화면이 수직으로 되어있으며 홈 버튼이 장치의 바닥에 옵니다.
2.
뒤집어진 세로 - 세로로 돌아옵니다.
3.
가로 왼쪽 - 유저 인터페이스와 스플래시 화면이 수평으로 되어있으며 홈 버튼이 장치의 오른쪽에 옵니다.
4.
가로 오른쪽 - 가로 왼쪽으로 돌아옵니다.
독특한 스플래시 화면 사용하기(프로 라이센스 기능)
유니티 안드로이드 프로 유저는 어떤 텍스쳐도 스플래시 화면으로 사용할 수 있습니다. 지시사항:
1.
스플래시 화면 텍스쳐를 에셋 폴더 아무곳에나 가져다 놓으세요.
2.
In Player Settings (Splash Image 섹션)에서 모바일 스플래시 화면 속성을 위해 텍스쳐를 선택합니다.
o
Center (오직 크기가 작아지기만 함) 는 사용자 이미지를 정확한 픽셀에 화면에 맞게하기 위해 크기 조절이 필요하지 않는
한 크기 조절 없이 이미지를 그린다.
o
Scale to fit (letter-boxed) 는 사용자 이미지를 전체 화면에 잘라냄없이 빈 공간은 검은 픽셀로하고 나타냅니다.
o
Scale to fill (잘라짐) 는 사용자 이미지를 전체화면에 보여주고 화면 밖의 화면은 잘라냅니다.
그것이 전부 입니다! 게임이 빌드되면 사용자 정의 이미지가 사용될 것입니다.
테스트를 실행한 장치
여기 저희가 테스트를 실행했고 유저들이 저희에게 개발 가능하다고 알려준 안드로이드 장치들의 리스트가 있습니다. 만약 이곳에
게시된 장치 이외의 장치에서 개발 중이고 잘 작동되고 있다면 [email protected] 로 어떤 장치이고 어떤 버전의 안드로이드
운영체제를 사용하고 있는지 알려주십시오. 사용자는 좀 더 자주 업데이트되는 우리의 forum 에서도 리스트를 보실 수 있습니다.
ARMv7 devices
Device
Android OS Versions
Google Nexus One
OS 2.1 and newer
Google Nexus S
OS 2.3 and newer
Motorola Droid X
OS 2.1 and newer
Motorola Droid
OS 2.1 and newer
Motorola XT701
OS 2.1
HTC EVO 4G
OS 2.1 and newer
HTC Droid Incredible
OS 2.1 and newer
HTC Desire HD
OS 2.1 and newer
HTC Desire Z
OS 2.1 and newer
HTC Desire
OS 2.1 and newer
SE X10
OS 2.1 and newer
Samsung Galaxy S
OS 2.2 and newer
Samsung Galaxy S (Fascinate)
OS 2.1
Samsung Galaxy Tab
OS 2.2
ARMv6 w/ VFP Devices
Device
Android OS Versions
Orange San Francisco / ZTE Blade
OS 2.1 and newer
SE X10 mini
OS 2.1 and newer
Samsung Galaxy 580
OS 2.1 and newer
유니티와 이클립스 통합하기
이 가이드는 가능한 새로운 사용자들에게 친근하도록 만들어졌습니다. 그러나 사용자가 이클립스나 자바 프로그래밍 언어와
안드로이드 sdk 에 익숙하다면 더욱 쉬울 것입니다.
이클립스에서 유니티 안드로이드를 사용하기 위해서는 이클립스를 안드로이드와 사용할 수 있도록 설정해야합니다. 이것을 어떻게
해야하는 지에 대한 좋은 가이드가 있습니다. android developer documentation.
라이브러리로서의 유니티
최신 이클립스가 설치 되었으면 사용자 유니트 프로젝트가 이클립스에서 라이브러리로 상용되게 하기 위해 몇가지 절차가
필요합니다.
•
빈 유니티 프로젝트를 만들고 안드로이를 위해 빌드하세요. 지금은 유니티 프로젝트가 코드나 에셋을 포함하고 있는지는 중요하지
않습니다. 이 부분의 프로세스는 앞으로 바뀔 것입니다.
•
그 새로운 프로젝트 폴더로 이동후 Temp 폴더로 갑니다. 그곳에 staging area 라는 폴더가 있습니다.
•
그 staging area 폴더를 복사후 홀딩 영역으로 사용할 수 있는 사용자 파일 시스템에 위치 시킵니다. 그 홀딩 영역은 이클립스
워크스페이스 안에 있으면 에러가 생기니 그곳에 놓지 마세요.
•
이클립스를 열고 File --> New --> Project 를 눌러 새로운 안드로이드 프로젝트를 만드세요.
•
안드로이드 프로젝트를 선택하고 누르세요.
•
이것은 사용자 프로젝트의 라이브러리가 될 것이므로 혼돈을 피하기위해 이름을 적절히 만드세요.
•
또한 기존의 소스로부터 새로운 프로젝트를 만들 수도 있습니다. 이 소스는 사용자가 홀딩 영역으로 사용하는 위치시킨 파일입니다.
사용자가 Staging Area 폴더를 선택하고 OK 를 누르면 이클립스가 관련된 필드를 채워 놓은것을 볼수 있습니다.
•
프로젝트 생성 위자드에서 finish 를 누르세요.
•
마지막으로 이클립스의 패키지 탐색기의 루트 폴더를 오른쪽 클릭하고 속성 옵션을 선택하고 안드로이드 탭을 누릅니다. “Is Library”
체크 박스를 체크하고 Apply 를 누르고 OK 를 누릅니다.
이것은 이클립스안에서 사용자 프로젝트가 라이브러리로 사용되도록 만드는 과정을 완성합니다.
자바 프로젝트
다음 스텝은 이클립스 프로젝트의 실행되는 부부분을 만드는 것입니다.
•
새로운 안드로이드 프로젝트를 만듭니다.
•
프로젝트 이름을 정하고 생성한 라이브러리 프로젝트와 같은 Build Target 과 Min SDK Version 을 선택합니다.
•
패키지 이름을 유니티 프로젝트안의 번들 식별자와 같게 만들어야 합니다. 그렇지 않으면 프로젝트에서 생성된 자바 파일에 충돌
문제가 생길수 있습니다.
•
이제 생성한 라이브러리를 프로젝트에 추가합니다. 이것은 JavaProject 를 클릭해서 속성을 선택하면 됩니다.
•
안드로이드를 선택하고 add 를 클릭합니다. 그럼 창이 뜨고 생성된 라이브러리 프로젝트를 선택하고 ok 를 누릅니다. 메인 창으로
돌아오면 apply 를 누릅니다.
•
이제 왼쪽 리스트에서 Java Build Path 를 선택하고 add external jar 를 클릭합니다. 그럼 창이 뜨고 사용자 유니티 설치 디렉토리로
이동하고 Unity\Editor\Data\PlaybackEngines\androidplayer\bin 에 classes.jar 라는 파일이 있습니다. 그 파일을 더블클릭하고 ok 를
클릭합니다.
이것은 사용자의 유니티 프로젝트와 나중에 쓰이기될 관련 라이브러리가 링크된 기본 자바 프로젝트를 설정합니다.
프로젝트 에셋 이동하기
사용자 유니티 콘텐츠를 자바 프로젝트로 옮거서 나중에 자바 프로젝트를 빌드하고 실행할때 보여줄수 있게 하는 매우 중요한
부분입니다. 이제 라이브러리 프로젝트의 에셋 폴더에 있는 모든 파일을 새로운 프로젝트로 옮겨야 합니다. 왜냐하면
안드로이드에서는 에셋이 라이브러리에 있을 수 없기 때문입니다. 이것을 하기 위한 가장 좋은 방법은 이클립스 IDE 안에서 하는
것입니다. 양쪽의 패키지 탐색기의 에셋 파일을 확장하고 단순히 bin 과 libs 폴더를 사용자 프로젝트에서 다른 프로젝트로
드래그하면 됩니다. 이 마지막 스텝은 사용자 유니티 프로젝트가 다시 빌드될 때마다 반복해야하는데 스크립트를 만들어 빌드할
때마다 자동으로 파일을 옮기게 할수도 있습니다. 이것은 또한 symlinks 나 junctions 을 이용해서도 할수 있습니다. 이 시점에서
이클립스 IDE 에서 프로젝트를 실행시키면 어떤 종류의 프로젝트를 실행하고 싶은지 묻게 됩니다. 안드로이드를 선택하고 ok 를
누릅니다. 이클립스가 프로젝트 빌드를 마치면 그것은 연결된 안드로이드 장치로 옮겨지고 헬로우 월드 스타일의 프로그램이
실행되는 것을 볼수 있습니다.
사용자 유니티 컨텐츠 실행하기
사용자 유니티 프로젝트를 얻기 위해서는 자바 소스 코드를에 몇가지 변화를 줄 필요가 있습니다. 사용자의 이클립스 프로젝트에
하나의 소스파일(.java)가 있는데 이것을 엽니다. 그 파일의 내용은 아래와 비슷할것 입니다.
package com.Unity3D.EclipseIntegration;
import android.app.Activity;
import android.os.Bundle;
public class EclipseIntegration extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
이것을 바꾸어야 합니다. 첫째로 객체의 베이스 클래스를 바꾸어야 합니다. 이제 그것은 UnityPlayerActivity 를 상속해야 합니다.
이것을 했을때 에러를 의미하는 빨간 밑줄이 생기는 것을 알수 있습니다. 이것은 파일에 관련된 import 가 빠진걸 말해줍니다. 이것을
자동으로 해결해주는 이클립스 단축키는 ctrl+shift+o 입니다. 그 파일은 이제 import 문을 가져야 합니다.
import com.unity3d.player.UnityPlayerActivity;
이제는 전체화면의 헬로우 월드 프로그램을 보게될 것입니다. 이것은 사용자가 원하는 것이 아니고 사용자의 유니티 콘텐츠가
실행되는 것을 보기위해서는 한가지를 더 바꾸어야 합니다.
onCreate 함수에 안드로이드 프로그램에서 유니티 뷰를 오버라이드하는 하나의 라인이 있습니다. 그 라인을 지우면.
setContentView(R.layout.main);
이제 완전한 파일은 아래와 같을 것입니다.
package com.Unity3D.EclipseIntegration;
import android.os.Bundle;
import com.unity3d.player.UnityPlayerActivity;
public class EclipseIntegration extends UnityPlayerActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
이제 이것을 실행하면 안드로이드 장치에서 사용자의 유니티 콘텐츠가 실행되는 것을 볼수 있습니다.
유니티안에서 안드로이트 프로그램 시작하기
the guide on integrating unity with eclipse 를 따랐다면 이것을 하는 기본이 있는 것입니다. 이 예제는유니티 안드로이드
프로그램에서 어떻게 미디어 갤러리를 시작하는 지를 보여줍니다.
유니티에 시작 제어기능 추가하기
사용자가 해야할 일은 유니티에 자바 프로젝트를 부르고 유니티 프로그램을 시작시키는 제어를 추가하는 일입니다. 이 예제에서
버튼이 사용될 것입니다.
버튼 추가하기
유니티 프로젝트에서 새로운 스크립트를 만드십시오. 스크립트안에 OnGUi함수를 추가합니다. 이 함수에서 버튼을 만들고 자바
콜을 만듭니다. 그 자바 콜은 AndroidJavaClass 와 AndroidJavaObject 를 사용하여 만듭니다. 사용자가 해야할 것은 currentActivity
를 얻고 그 안에 함수를an intent를 시작하기 위해 부릅니다.
void OnGUI()
{
if(GUI.Button(new Rect(100,100,100,100) , "launch"))
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
jo.Call("Launch");
}
}
이제 그것은 제 위치에 있게되며 사용자는 프로젝트를 빌드하고 프로젝트 디렉토리의 에셋 폴더 내용을 이클립스 프로젝트로
이동시킵니다.
자바 코드
이전에는 안드로이드에서 활동을 시작하기 위해서 버튼을 작성하였습니다. 이제는 실제 이것을 하기위해 자바 코드를 사용합니다.
•
자바 코드에 하나의 intent 를 추가할 필요가 있습니다.
private Intent myIntent;
•
이 intent는 onCreate함수에서 설정되어야 합니다. intent에 관한 자세한 사항은 android sdk documentation를 보세요
myIntent = new Intent();
myIntent.setAction(Intent.ACTION_VIEW);
myIntent.setData(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
•
마지막 스텝은 사용자 유니티 프로그램에서 부를 함수를 작성하는 스텝이고 startActivitiy 를 부릅니다. 이 예제 초기에 그 함수가
시작을 위해 불렸듯 그것이 이 예제에서 우리가 불러야 할 것입니다.
public void Launch()
{
startActivity(myIntent);
}
이제 사용자가 이클립스에서 프로그램을 빌드하고 실행하면 눌렸을 때 사용자 장치에서 미디어 갤러리가 시작되는 버튼이 유니티
프로그램과 함께 안드로이드 장치에 보일 것입니다. 안드로이드 장치로 돌아가기 위해 뒤로가기 버튼을 누르고 이 과정을
반복하세요.
FAQ
유니티 프로젝트 2.x 에서 3.x 로 업그레이드 하기
유니티의 정기적인 발표에서 저희는 같은 메이져 버전의 이전 마이너 버전 프로젝트들이 처음으로 새로운 에디터에서 열릴때
자동으로 업그레이드 되도록 합니다. 새로운 속성에는 기본값이 들어가며 형식이 바뀌는 등의 일이 일어납니다. 그러나 메이저 버전
체인지인 2.x 에서 3.x 의 버전 변화는 서로 호환되지 않는 변화들이 있습니다.
주요한 변화로는 이전 버전에서 작성한 내용이 새로운 엔진에서 조금 다르게 플레이 될 수 있다는 것이고 어떤 변화들은 원하는데로
플레이 시키기 위해서는 많은 노력을 필요로 합니다. 아래의 문서들은 이런 2.x 에서 3.x 의 변화들을 보여줍니다:
•
피직스 업그레이드 상세설명
•
모노 업그레이드 상세설명
•
렌더링 업그레이드 상세설명
•
SL-V3 변환
피직스 업그레이드 상세설명 Physics upgrade details
유니티 3.0 에서 우리는 사용자에게 더 많은 새로운 기능들을 제공하기 위하여 NVIDIA PhysX 라이브러리를 2.6 에서 2.8.3 으로
업그레이드 했습니다. 일반적으로 기존의 프로젝트에서 행동 (behavior)는 유니티 2.x 버젼에서와 대략적으로 비슷한 것이나 물리
시뮬레이션에서는 약간의 차이점이 있을 것입니다.그러므로 만약 사용자의 콘텐츠가 정확한 행동이나 물리적 이벤트들의
연쇄반응에 기대고 있는 경우, 유니티 3.x 의 설정을 다시 조정해야 할지도 모릅니다.
만약 Configurable Joints 를 사용하고 있다면, JointDrive.mode 가 JointDriveMode.Position 일때, JointDrive.maximumForce 속성이
감안되야 할 것입니다. 만약 이 값이 기본 값인 0 으로 설정해놓았다면, 조인트는 어떤 힘도 가하지 않을 것입니다. 만약
JointDrive.mode 가 JointDriveMode.Position 이라면 이전 버젼으로부터 가져온 모든 JointDrive 속성들을 우리가 자동적으로 바꾸어
놓을 것입니다. 또한, 우리는 JointDrive.maximumForce 를 기본값으로 무한으로 설정해 놓았습니다.
모노(Mono) 업그레이드 세부 사항
유니티 3 에서는 모노 런타임을 1.2.5 에서 2.6 으로 그리고 추가로 JavaScript 와 Boo 개선사항을 업그레이드 하였습니다. 두 버전의
모든 버그 해결과 개선이외에 이 페이지에서는 몇가지 하이라이트를 나열합니다.
C# 개선사항
기본적으로 C# 3.5 과 C# 2.0 의 차이점은 다음을 포함합니다:
•
변수 타입 추론. 더 많은 정보는here를 보세요.
•
Linq .
•
Lambdas. 더 많은 정보는here를 보세요.
JavaScript 개선사항
•
네배 빠른 컴파일러;
•
'extends'는 더 이상 인터페이스와 사용될 수 없으며 unityscript 는 그 이유로 개선사항이 있습니다(아래를 보세요);
•
일반 콜렉션과 같은 일반 타입의 소모를 위한 추가된 지원:
var list = new System.Collections.Generic.List.<String>();
list.Add("foo");
•
anonymous functions/closures 에 대한 추가 지원:
list.Sort(function(x:String, y:String) {
return x.CompareTo(y);
});
•
파라미터와 리턴 값을 위한 타입 추론과 간략화된 람다 표현 형태 지원:
list.Sort(function(x, y) x.CompareTo(y));
•
함수 타입:
function forEach(items, action: function(Object)) {
for (var item in items) action(item);
}
•
타입이 추론된 javascript array 이해:
function printArray(a: int[]) {
print("[" + String.Join(", ", [i.ToString() for (i in a)]) + "]");
}
var doubles = [i*2 for (i in range(0, 3))];
var odds = [i for (i in range(0, 6)) if (i % 2 != 0)];
printArray(doubles);
printArray(odds);
•
인터페이스 선언과 구현에 대한 추가 지원:
interface IFoo {
function bar();
}
class Foo implements IFoo {
function bar() {
Console.WriteLine("Foo.bar");
}
}
•
모든 함수는 내부적으로 모두 virtual 이며 그 결과'virtual'키워드는 더이상 사용되지 않으며 virtual 함수가 아닌 함수의 정의를 위해
'final' 키워드가 소개되었습니다:
final function foo() {
}
•
Value types (structs)은 System.ValueType 으로 부터 상속하여 클래스로 정의 될수 있습니다:
class Pair extends System.ValueType {
var First: Object;
var Second: Object;
function Pair(fst, snd) {
First = fst;
Second = snd;
}
override function ToString() {
return "Pair(" + First + ", " + Second + ")";
}
}
Boo 개선사항
•
Boo 는 0.9.4 버전으로 업그레이드 됨.
렌터링 업그레이드 세부사항
유니티 3 은 많은 그래픽 관련 변화를 가져왔는데 기존 유니티 2.x 프로젝트에서 업그레이드할 때 어떤 것들은 변화가 필요할
것입니다. 쉐이더에 관련된 변화는 Shader Upgrade Guide 를 보세요.
포워드 렌더링(Forward Rendering) 경로 변경
유니티 2.x 은 유니티 3 에서 Forward 라고 불리는 하나의 레더링 경로를 가지고 있었습니다. 유니티 2 와 비교한 주요한 변화로는
다음이 있습니다:
•
가장 흔한 경우(빛 픽셀당 한 방향)에 이제 하나의 패스로 그려집니다(주로 두개의 패스였음).
•
포인트 & 스포트라이트 그림자는 지원되지 않습니다. 오직 단방향 빛만 그림자를 만들 수 있습니다. 더 많은 그림자를 원하면
Deferred Lighting 경로를 이용하세요.
•
대부분의 "Vertex" 빛은 구형 고조파(Spherical Harmonics) 빛으로 바뀌었습니다.
•
포워드 렌더링 경로는 온전히 쉐이더를 기반으로 하므로 OpenGL ES 2.0, Xbox 360, PS3 에서 작동합니다 (즉 고정된 기능
렌더링을 지원하지 않는 플랫폼).
쉐이더 변경
더 자세한 사항은 Shader Upgrade Guide 을 참조하세요. 사용자가 빛과 상호작용하는 쉐이더를 구현하기 원한다면 Surface
Shaders 를 사용해야 합니다.
아무도 알아 차리지 못할 눈에 띄지 않는 그래픽 변경TM
•
Mac Radeon 9200 픽셀 쉐이더 지원 제거(!!ATIfs 어셈블리 쉐이더).
•
pre-ShaderModel2.0 하드웨어에서 픽셀단위 빛 지원 제거. 그 결과 Diffuse Fast 쉐이더는 단지 VertexLit 입니다.
•
약해지지 않는 빛 제거. 모든 포인트와 스포트라이트 빛은 점점 약해집니다.
•
스크립트 콜백 제거: OnPreCullObject 와 RenderBeforeQueues 속성.
•
p-buffer 에 기반을 둔 RenderTextures 제거. OpenGL 에 있는 RenderTextures 는 FBO 지원을 필요로 합니다.
•
대부분의 Pass LightMode tags 는 사라졌고 새로운 태그로 교체 되었습니다. 사용자는 어쨌든 보통 Surface Shaders 를 사용해야할
것입니다.
•
Texture instanceIDs 는 더이상 OpenGL 텍스쳐 이름이 아닙니다. 이것에 의존하는 C++ 플러그인에 영향을 줄 수 있습니다. 대신
texture.GetNativeTextureID()를 사용하세요.
•
쉐이더 키워드인 SHADOWS_NATIVE 부터 SHADOWS_DEPTH 까지, SHADOWS_PCF4 부터 SHADOWS_SOFT 까지 삭제.
•
객체에서 8 개 이상의 꼭지점 빛에 영향을 받는 주위의 부스트 제거.
•
_ObjectSpaceCameraPos 와 _ObjectSpaceLightPos0 의 제거 (_WorldSpaceCameraPos 와 _WorldSpaceLightPos0 가 추가됨).
•
쉐이더 텍스쳐 속성의 LightmapMode 태그는 아무것도 하지 않습니다.
•
Skybox 쉐이더는 depth buffer 에 쓰여지지 않습니다.
•
GrabPass (즉 굴절되는 유리 쉐이더)는 항상 화면 크기의 텍스쳐를 잡습니다.
•
#pragma multi_compile_vertex 와 #pragma multi_compile_fragment 는 사라졌습니다 .
•
ShaderLab 의 다각형 오프셋은 더이상 변수를 참조 못합니다 (예를 들어 Offset [_Var1], [_Var2]).
•
TRANSFER_EYEDEPTH/OUTPUT_EYEDEPTH 를 to UNITY_TRANSFER_DEPTH/UNITY_OUTPUT_DEPTH 로 개명. 이것은 유니티 3 에서
float2 로도 작동.
•
특별한 쉐이더 패스 타입제거: R2TPass, OffscreenPass.
•
내장된 _Light2World0, _World2Light0 쉐이더 메트릭스 삭제.
•
내장된 쉐이더 벡터인 _SceneAmbient, _MultiModelAmbient, _MultiAmbient, _ModelAmbient, _MultiplyFog, _LightHackedDiffuse0,
_ObjectCenterModelLightColor0 제거.
•
내장된 쉐이터 float 인 _FirstPass 삭제.
•
쉐이더 파일의 안개 모드는 변수에서 올 수 없음(예를들어 Fog { Mode [_MyFogMode] }). 글로벌 안개 모드사용을 위해서는 Fog
{ Mode Global }와 같이 사용하세요.
•
ShaderLab 에서 BlendColor 색 삭제.
•
값이 있는 쉐이더 속성에 의한 텍스쳐 메트릭스 선언의 지원 삭제.
•
"static" 쉐이더 속성 지원 삭제.
•
텍스쳐 경계 색 지원 삭제 (RenderTexture.SetBorderColor).
•
ColorMaterial Ambient, Diffuse, Specular 지원 삭제(ColorMaterial AmbientAndDiffuse 와 Emission 는 남아있음). 플랫폼에
따른 사라진 것에 대한 지원은 혼란의 야기하고 별로 유용하지도 않습니다.
•
내장된 _CameraToWorld 와 _WorldToCamera 메트릭스가 이제 사용자가 기대했던 것을합니다. 이전에는 회전만 포함하며 Y 축에서
카메라와 세계가 뒤집혔었습니다. 저희도 왜 그러는지 알지 못합니다:)
•
Shader.ClearAll()의 삭제. 2007 년부터 사용되지 않았습니다. 이제 보내야할 때입니다 Was deprecated since 2007, time to let it
•
꼭지점 쉐이더는 이제 쉐이더 모델 2.0 으로 컴파일 됩니다(이전에는 1.1). SM1.1 로 컴파일하길 원하면 쉐이더에 #pragma target 1.1
go.
를 추가하세요.
유니티 3.x 그림자 변환 가이드
유니티 3 은 그 렌더링 시스템에 많은 새로운 기능과 변화가 있고 ShaderLab 도 업데이트 되었습니다. 유니티 2.x 에서 쓰였던 어떤
고급 쉐이더는, 특히 픽셀당 빛에 쓰였던 것은 유니티 3 에서 업데이트가 필요합니다. 업데이크에 문제가 있다면 저희의 도움을
받으십시오!
유티니 3 에서의 전반적인 그래픽관련 업그레이드에 대한 자세한 내용은 Rendering Upgrade Details 을 보세요.
로젝트 파일을 유니티 3.x 에서 열면 그림자 파일이 가능한 최대로 업그레이드 됩니다. 아래 문서에서는 그런 모든 쉐이더에 생기는
변화와 수동 업그레이드가 필요할 때 어떻게 해야하는 지를 설명합니다.
픽셀 단위 쉐이더 (Per-pixel lit shaders)
유니티 2.x 에서는 쉐이더가 픽셀 단위의 빛을 내는 것은 아주 복잡했습니다. 그런 쉐이더는 LightMode 태그가 켜진 (보통
PixelOrNone, Vertex 그리고 Pixel) 여러 개의 경로를 가졌습니다. 유니티 3.x 에서 추가된 Deferred Lighting 과 오래된 포워드
렌더링의 변화로 좀 더 간단하고 견고하고 미래를 보장하는 빛과 상호작용하는 쉐이더 쓰는 방법이 필요하였습니다. 모든 오래된
픽셀 단위의 쉐이더는 Surface Shaders 로 다시 쓰여져야 합니다 .
Cg 쉐이더 변화
내장된 변수 "glstate"에 다시 이름주기
유니티 2.x 에서는 어떤 내장된 변수(예를 들어 model*view*projection matrix)에의 접근은 내장된 Cg 이름(예를
들어 glstate.matrix.mvp) 을 통해 가능합니다. 그러나 어떤 플랫폼에서는 그것이 작동하지 않는다. 그래서 유니티 3.x 에서는 그
내장된 변수의 이름을 다시 정하게 되었습니다. 이 모든 대체는 사용자 프로젝트가 업그레이드 될 때 자동으로 이루어 질 것입니다:
•
glstate.matrix.mvp 를 UNITY_MATRIX_MVP 로
•
glstate.matrix.modelview[0]를 UNITY_MATRIX_MV 로
•
glstate.matrix.projection 를 UNITY_MATRIX_P 로
•
glstate.matrix.transpose.modelview[0]를 UNITY_MATRIX_T_MV 로
•
glstate.matrix.invtrans.modelview[0]를 UNITY_MATRIX_IT_MV 로
•
glstate.matrix.texture[0]를 UNITY_MATRIX_TEXTURE0 로
•
glstate.matrix.texture[1]를 UNITY_MATRIX_TEXTURE1 로
•
glstate.matrix.texture[2]를 UNITY_MATRIX_TEXTURE2 로
•
glstate.matrix.texture[3]를 UNITY_MATRIX_TEXTURE3 로
•
glstate.lightmodel.ambient 를 UNITY_LIGHTMODEL_AMBIENT 로
•
glstate.matrix.texture 를 UNITY_MATRIX_TEXTURE 로
Semantics 변화
추가로 vertex-to-fragment 구조에서의 위치를 위해서 SV_POSITION (POSITION 대신)를 사용하는 것을 귄장합니다.
엄격한 에러 확인
플랫폼에 따라 쉐이더는 조금더 엄격한 에러 확인을 가진 Cg(예를 들어 윈도우즈에서의 HLSL) 이외의 다른 컴파일러로 컴파일될 수
있습니다. 대부분의 공통된 경우들:
•
모든 vertex/fragment 쉐이더 입력과 출력은 “semantics”의 할당을 필요로 합니다. 유니티 2.x 에서는 semantics 를 할당하지 않는
것이 가능했습니다(이런 경우 TEXCOORD 가 쓰임). 유니티 3.x 에서는 semantic 을 필요로 합니다.
•
모든 쉐이더 출력 변수들은 쓰여져야 합니다. 예를 들어, 사용자가 꼭지점 쉐이더의 출력으로 float4 color : COLOR 를 가지고 있다면
사용자는 단지 rgb 에 쓰고 알파를 초기화하지 않을 수 없습니다.
다른 변경 사항
RECT 텍스쳐는 더이상 없습니다
유니티 2.x 에서 RenderTextures 는 “RECT”텍스쳐로 불리는 2 의 제곱수의 크기를 갖지 않을 수 없었습니다. 그 것은 쉐이더
속성에서 “RECT” 텍스쳐로 명시되었고 Cg 쉐이더에서 samplerRECT 와 texRECT 등으로 사용되었습니다. OpenGL 에서는 RECT
텍스쳐를 위한 텍스쳐 좌표는 특별한 케이스 였습니다. 그 것은 픽셀로 되었었습니다. 다른 모든 플랫폼에서는 텍스쳐 좌표는 다른
어떤 텍스쳐와도 같았습니다. 그것은 텍스쳐위에 0.0 부터 1.0 로 표기되었습니다.
유니티 3.0 에서는 이 OpenGL 의 특별한 케이스를 제거하기로 결정하여서 2 의 제곱수가 아닌 크기의 RenderTextures 도 모든
곳에서 동일하게 여겨졌습니다. samplerRECT, texRECT 또는 비슷한 사용을 보통의 sampler2D 와 tex2D 로 바꿀 것을 권합니다.
또한 OpenGL 을 위해 특별한 픽셀 주소를 사용하고 있다면 쉐이더에서 그것을 제거할 필요학 있습니다. 즉 OpenGL 부분이 아닌
부분만 남기십시오 (쉐이더에서 SHADER_API_D3D9 또는 SHADER_API_OPENGL 매크로를 찾으십시오).
What's New in Unity?
유니티 3 는 새로운 기능과 기존 기능의 개선 사항으로 가득차 있습니다. 리스트를 탐색하거나 클릭해서 새로운 기능의 더 많은
정보를 얻으세요.
Unified Editor
유니티는 현재 다중 플랫폼 프로젝트를 위한 최고의 에디터 입니다. 새로운 Build Settings 윈도우는 사용자가 주 에디터 모드를
설정할 수 있게하고 어떤 타겟 플랫폼에서도 빌드 되도록 할 수도 있습니다. 새로운 Platform Defines 는 사용자가 컴파일 때 특정
플랫폼의 코드를 포함 또는 실행할 수 있게 하므로 사용자는 하나의 프로젝트와 하나의 스크립트 집합으로 일할 수 있습니다.
Editor Improvements
다양한 에디터 워크플로워 개선과 향상이 추가 되었고 다음을 포함합니다:
•
Redesigned Player Settings -- 다중 플랫폼에서의 게임 경험을 사용자 정의 합니다
•
All-new Object Picker -- 객체 할당을 빨리 보거나 선택합니다
•
Smarter Texture Importer -- 텍스쳐가 어떻게 사용되느냐에 따라 최적화를 합니다
•
Vertex Snapping -- 빠르게 레벨과 환경을 디자인 합니다
•
Curve Editor -- 인스펙터 안의 곡선을 정의 합니다
•
Searching -- 씬에서 또는 전체 프로젝트에서의 탐색
Asset Store
전세계적으로 250,000 이 넘는 유저가 있는 에셋 스토어는 사용자에게 세계에서 가장 많은 개발자들이 꿈꿀수 있는 규모의 이점을
제공합니다. 개발시에는 사용자의 제품에 다른 유저의 작업을 쉽게 활용할 수 있습니다. 사용자가 게임을 마치면 사용자의 작업을
팔아서 추가적인 수입을 낼 수 도 있습니다.
사용자는 유니티에서 직접 에셋 스토어에 접근할 수 있습니다. 에셋 스토어 윈도우를 열기 위해서는 메뉴 바에서 Window->Asset
Store 를 선택합니다.
Lightmapping
Beast by Illuminate Labs 은 유니티에 완전 통합되었습니다. 유니티에 사용자 빛을 설정하고 사용자 게임에 굉장히 세련된 모습을
보이기 위해 높은 퀄리티의 빛맵으로 굽습니다.
Deferred Rendering (Pro only)
좀더 많은 실시간 빛을 렌더링 합니다.
Occlusion Culling (Pro only)
Occlusion Culling 은 카메라 뷰에서 보이지 않는 객체의 렌더링을 비활성화 시킵니다. 유니티에서 사용자는 세밀하게
occlusion 설정을 할 수 있으며 구운 occlusion 데이터를 시각화 할 수 있습니다.
Debugger (Pro only)
실행시에 모든 사용자 코드의 모든 다이내믹을 검사합니다. 사용자 코드를 라인별로 검사하고 속성의 상태를 감시합니다.
스크립트의 문제를 빠르게 해결하세요!
Audio Features
사용자 환경을 class-AudioReverbZone와 Rolloff Curves로 디자인 하세요. 아무 플레이되고 있는 사운드에 실시간 Audio Effect
Filters(Pro only)을 적용하세요. Audio API additions로 세밀하게 제어하세요.
Physics
수많은 물리가 추가 되었고 다음을 포함합니다:
•
Interactive Cloth -- 메쉬에서의 옷의 행동을 시뮬레이션 합니다.
•
Skinned Cloth -- rigged 특성에 옷 시뮬레이션을 가져옵니다.
•
Continuous Collision Detection -- 빠르게 움직이는 객체의 충돌을 다룹니다.
•
Layer-Based Collision Matrix -- 어떤 객체의 레이어를 어떤 것과 충돌할 수 있는지 정의합니다.
•
SphereCasts와 CapsuleCasts
Tree Creator
트리 생성기는 사용자가 강력한 인터페이스를 이용해 나무를 점차적으로 생성 그리고 수정하는 것을 가능하게 합니다. 이것은
지형이나 보통 GameObject 에 사용 가능합니다. Wind Zones 은 나무에 추가적인 행동 리얼리즘을 부여합니다.
IME Text Input
IME 입력은 일본어 또는 전통 중국어 같은 영어 문자가 아닌 문자가 사용자 게임이나 에디터에 입력될 수 있게 합니다.
Native Font rendering
다이나믹한 폰트는 크기를 위해 최적화 되어 있고 유니티 엔진이 실행되는 OS 에 의해 렌더링 됩니다. 이것은 게임 에셋의 불필요한
크기 증가 없이 일본어 Kanji 같은 큰 문자를 위한 IME 입력을 활성화 합니다.
Mono Update
몇가지 스크립트 개선 사항과 추가가 만들어 졌습니다.
Networking Update
RakNet 가 version 3.732 로 업그레이드 되었고 개선 사항이 Master Server 와 NAT Punchthrough 에 만들어졌습니다.
Security Sandbox
유니티 3.0 에서는 웹 플레이어가 새로운 보안 모델을 구현합니다. 이것은 사용자가 사용자의 .unity3d 파일을 가지는 도메인 이외의
도메인 데이터에 접근하기 위해서 WWW 클래스를 이용하거나 사용자 컨텐츠가 소켓을 사용하면 컨텐츠 개발자로서의 사용자에게
영향을 줍니다.
프로그램 활성화
Unity 프로그램을 사용하기 위해서는 활성화를 하셔야 합니다. 다운로드 받으신 버전은 Unity 와 Unity Pro 모두를 포함하고 있습니다.
Unity 를 실행하시면 Unity 나 30 일 시범사용 가능한 Unity Pro 를 선택하실 수 있는 저희 오라인 활성화 웹페이지가 열리게 됩니다.
개인 정보는 필요로 하지 않습니다.
Unity 를 구매하시게 되면 이메일로 시리얼 넘버를 받게 되실 것입니다. 그 번호는 고객마다 고유하며 잃어버리거나 다른 사람들과
공유하시면 않됩니다. 시리얼 넘버는 XY-ABCD-1234-EFGH-5678-IJ90 와 같은 문자열로 되어있습니다. Unity 를 활성화하실 때 이
넘버가 필요로하게 됩니다. 이 라이센스 시스템은 사용자의 하드웨어와 시스템 소프트웨어에 관한 정보를 저희 서버에 보내게
되어있습니다. 이 단계는 사용자의 컴퓨터를 사용자의 시리얼 넘버에 고정시키게 됩니다. 사용자 라이센스 동의는 사용자가 Unity 를
두 대의 컴퓨터까지 설치 가능하게 합니다. 만약 세번째 컴퓨터에 설치하려 한다면 활성화 한계를 넘었다는 메세지를 받게 되게
될것입니다. (교육용 또는 할인된 버전의 Unity 는 한 대의 컴퓨터에만 사용되어 질 수도 있습니다. 구매 전 어떤 제한이 있는지 꼭
알아보시기 바랍니다.)
주의: 하드웨어와 시스템 소프트웨어에 관한 정보는 많은 것에 영향을 받게 됩니다. 예를들어, 운영체제를 다시 설치하거나
하드드라이브를 포멧하거나 네트워크 카드를 다시 설치하면 그 정보가 바뀌게 될 것입니다.
Unity 를 다시 활성화 할때, 활성화 횟수가 제한을 넘었다는 메세지를 받을 수도 있습니다. 이것은 에러가 아니며 저희 서버가
사용자의 컴퓨터가 바뀌었음을 반영한 것입니다. 컴퓨터 오류로 고생하는 고객을위해 저희는 a Unity migration service 를 제공하고
있습니다. 이 서비스를 이용하기 이해서는 [email protected] 으로 컴퓨터가 어떠 한지를 가능한 많은 정보와 함께 이메일을
보내주십이오. 그리고 시리얼 넘보도 꼭 같이 보내주십이오. 그럼 저희가 제품 이동을 도와드리겠습니다.
자주받는 질문 (FAQ)
내 컴퓨터가 귀하의 활성화 서버와 연결할 수 없습니다. 어떻게 하여야 하나요?
저희는 온라인 활성화에 어려움이 있거나 인터넷이 연결되어 있지않은 컴퓨터에서 활성화 하려하는 사용자가 직접 활성화 파일을
생성할 수 있게 하기 위한 웹페이지를 제공하고 있습니다. 주소는 아래와 같습니다:
https://store.unity3d.com/manual/
Unity(무료 버전)를 사용하고 있다면 Free activation tickbox 를 클릭하고 ILR 파일을 업로드한 후 Activate Unity 를 누르시면 됩니다.
그렇지 않다면 주어진 칸에 시리얼 넘버를 넣어주십시오. 1~2 초 후에 ILF 파일이 컴퓨터로 다운로드 되이질 것입니다.
Unity 를 다시 시작하면, 활성화 윈도우로 가서 (시작시 열리거나 또는 Help>Enter Serial Number (win) or Unity>Enter Serial Number
(osx)를 선택해 주십시오.) Manual Activation 을 선택하고 Next 를 누른 후 Read License 를 누른 후 위에서 다운로드한 파일을
선택해 주십시오. Next 를 누르면 Unity 가 그 파일을 읽을 것이며 활성화가 완료될 것입니다.!
수동으로 활성화를 해주십시오. 그렇게 하기 위해서는 그 과정을 설명해줄 고객 서비스로 연락 주십시오.
Unity 를 한 컴퓨터에서 다른 컴퓨터로 옮기고 싶습니다. 무엇을 하여야 하나요?첫번째로 사용자의 컴퓨터에서 Unity 를 제거를
하십시오. 그리고 고객 서비스에 이동에 관해 도움을 받으십시오. 만약 게임 개발 중간의 중요한 단계에서 이 과정을 거쳐야 한다면
주의를 기울여야 합니다. 사용자의 프로젝트를새로운 컴퓨터로 옮기고 프로그램을 재설치 등을 위해 고객 서비스에 연락하기
위해선 미리 계획을 세워두십시오. Unity 를 두 대의 컴퓨터에 설치 가능하므로 개발이 중단될 시간이 없다는 거을 명심하십시오.
이메일은 아래의 사항을 포함하여야 합니다.:
•
사용하고 있는 시리얼 넘버
•
이동 전의 컴퓨터의 이름
•
이동 할 컴퓨터의 이름
•
시리얼 넘버가 할당된 사용자의 이름
저의 하드드라이브가 고장이 났습니다. 어떻게 하여야 하나요?하드 드라이브 고장으로 Unity 를 제거하실수 없다면 고객 서비스에
연락하십시오. 저희는 사용자의 프로젝트를 백업 해드릴 수 없고 사용자의 컴퓨터에 설치만 도와드릴 수 있다는 것을
상기하십시오. :)
활성화를 몇 번이나 할 수 있나요? 사용자의 시리얼 넘버로 두번의 활성화가 가능합니다.
Unity iOS 로 업그레이 했을 때 활성화 코드를 받았습니다. 왜 기존의 활성화 코드는 더이상 작동하지 않나요?iOS 제품은 저희의
Unity 와 Unity Pro 라이센스이 연장된 것입니다. Unity iOS 로 업그레이드시 기존의 활성화 코드를 대체할 시리얼 넘버를 받게 될
것입니다. 그 새로운 시리얼 넘버는 기존 설치된 Unity 와도 작동할 것입니다.
PC 와 Mac 에서 같은 시리얼 번호를 사용할 수 있나요? 그렇습니다. 같은 시리얼 넘버는 PC 와 Mac 에서 모두 사용되어 질 수
있습니다. 사용자 라이센스에 따르면 Unity 는 사용자가 사용하고 소유하는 두 대의 컴퓨터에 사용될 수 있습니다. 그 두대의
컴퓨터는 모두 Mac 또는 PC 또는 하나는 PC 나머지는 Mac 일 수 있습니다.
노트북과 데스크탑 컴퓨터에 같은 시리얼 넘버를 사용할 수 있나요?예, 시리얼 넘버는 노트북과 데스크탑 모두에 사용될 수 있습니다.
Unity 를 한 컴퓨터에서 제거하면 자동으로 새로운 컴퓨터에 활성화가 가능해 집니까? 아니요. 저희 Unity 서포트 팀에서 라이센스
이동에 동의 하여야 하며 그 이후에 새로운 컴퓨터에서 활성화가 가능합니다.
2.x 시리얼 넘버로 Unity3 을 사용할 수 있나요?아니요. Unity3 을 사용하기 위해서는 3.x 라이센스로 업그레이드 하여야 합니다.
아래 웹주소의 저희 웹스토어에서 하실 수 있습니다. https://store.unity3d.com/shop/
저의 라이센스가 온라인으로 활성화가 되지 않습니다!!이것은 여러가지 이유가 있을 수 있습니다. 문제 해결을 위한 가장 쉬운 방법은
수동 활성화를 통해 활성화를 하는 것입니다. 아래의 링크에서 어떻게 하는지 아실 수
있습니다.: http://answers.unity3d.com/questions/205/manual-offline-activation-of-unity
저의 하드웨어중 하나가 교체 되었는데 Unity 를 재등록 하여야 합니다. Unity 는 컴퓨터의 몇 곳에서 정보를 수집하여 유일한
라이센싱 파일을 만들게 됩니다. 하나의 하드웨어가 교체되어지면 저희 라이센싱 서버는 이것을 새로운 컴퓨터에서 오는 요청으로
받아들일 것입니다. 위의 이동 절차처럼 서포트 팀에([email protected])에서 사용자의 라이센스를 재활설화 할 수 있도록
이메일을 보내야 합니다.
활성화 서버에서 응답을 기다릴때 제 에디터가 멈춰버립니다. 가끔 온라인 활성화 과정 중간에 활성화 서버에서 응답을 기다리다보면
응답이 없고 예상보다 많은 시간이 걸릴 수 있습니다. 이럴때 에디터를 닫지마시고 5-10 분간 기다리기를 권합니다.!
[email protected] 로 연란 전에 FAQ 를 보아주십시오. 대부분의 라이센싱 문제들은 사소한 것들입니다. FAQ 에서 다루어져야
하는데 그렇지 않은 것이 있다면 저희에게 연락을 해주십시오.
간단한 일인칭 만들기
여기 어떻게 사용자의 아트 작품과 간단한 일인칭을 만들 수 있는지를 보여줍니다:
1.
사용자의 레벨을 불러옵니다. 사용자의 아트 패키지에서 기하 배열(geometry)을 어떻게 유니티로 불러오는지 여기를
보세요. here
2.
불려온 모델파일을 선택하고 인스펙터의 Import Settings 에 있는 Generate Colliders 에 있는 in the Inspector.
3.
프로젝트 뷰에있는 Standard Assets->Prefabs->First Person Controller 에 위치하고 그것을 씬뷰에 드래그 합니다 in the
Project View and drag it into the Scene View.
4.
사용자의 레벨 크기를 확실히 하십시오. First Person Controller 는 정확히 2 미티 크기여서 사용자의 레벨 크기가 그
컨트롤러와 맞지 않으면 사용자의 모델 프로그램에서 그 레벨의 크기를 조정해야합니다. 올바른 크기를 가지는 것은
물리적 시물레이션에서 매우 중요하며 다른 이유들은 this page 의 아래에 기록되어 있습니다. 잘못된 크기는 객체들을
떠있어 보이거나 너무 무겁게 보이게 만듭니다. 사용자의 모델 프로그램에서 크기를 바꿀 수 없다면 Import Settings...에서
바꿀 수 있습니다.
5.
Transform 핸들을 이용해 일인칭 제어자(First Person Controller)가 시작 위치에 오게 움직입니다. 이것은 매우 중요한데
게임 시작시 그 일인칭 제어자가 어떤 층 기하 배열도 가로지를 수 없기 때문입니다. (그렇지 않으면 움직일 수 없게 됩니다.)
6.
계층 뷰에서 기본 카메라인 "Main Camera"를 제거합니다. 일인칭 제어자는 이미 자신의 카메라를 가지고 있습니다.
7.
사용자의 레벨에서 돌아나니기 위해 Play 를 누릅니다.
Graphics Questions
다음은 유니티에서의 그래픽 관련 질문과 어떻게 해결하는 지에대한 리스트입니다.
색, 범프, 렌즈, 반사 매핑을 포함하는 텍스쳐 생성을 위한 훌륭한 튜토리얼이 있습니다. here.
•
알파맵
•
노멀맵
•
디테일텍스쳐 사용
•
큐브맵 만들기
•
스카이박스 사용
•
메쉬파티클에미터
•
스플래쉬 스크린
•
라이트쿠키
•
Z 축 위방향 설정 고치기
•
물
How do I Import Alpha Textures?
유니티는 똑바른 alpha blending 을 사용합니다. 그러므로 칼라 레이어를 늘릴 필요가 있습니다. 유니티의 알파 채널은 포토샾
파일의 첫번째 알파 채널에서 읽히게 될 것입니다.
설정하기
이것을 하기 전에 알파 유틸리티 포토샆 액션을 설치하십시오: AlphaUtility.atn.zip
설치후 Action Palette 는 AlphaUtility 라는 폴더를 포함하고 있어야합니다:
Getting Alpha Right
포토샾의 투명 레이어에 알파 텍스쳐가 있다고 가정해보세요. 아래와 같이:
1.
레이어를 복사(duplicate)합니다.
2.
가장 낮은 레이어를 선택합니다. 이것은 배경화면 확장의 소스가 됩니다.
3.
Layer->Matting->Defringe 을 선택하고 기본 속성(default properties)을 적용합니다.
4.
"Dilate Many"액션을 두 번 실행합니다. 이것은 배격ㅇ화면을 새로운 레이어로 확장합니다.
5.
모든 확장된 레이어(dilation layer)를 선택후 Command-E 로 병합(Merge)합니다.
6.
이미지 스택의 아래쪽에 “solid color layer”를 선택합니다. 이것은 사용자의 문서 일반적 색(이 경우에는 녹색)과 매치되어야
합니다.
이제 알파 레이어에 투명성을 복사해야 합니다.
1.
Layer Palett 에서 명령을 클릭함으로써 사용자의 메인 레이어의 콘텐츠가 선택되어 지도록 합니다.
2.
채널 팔레트로 바꿉니다.
3.
투명의 새로운 채널을 생성합니다.
PSD 파일을 저장합니다. – 이제 준비가 되었습니다.
Normal Maps 은 어떻게 사용하나요?
Normal maps 은 오목하게 나오거나 들어오는 표면을 나타내기위해 객체의 높이 맵으로 쓰이는 회색빛의 이미지입니다. 아래와
같이 생긴 모델이 있다고 가정해보세요:
3D 모델
텍스쳐
우리는 객체의 밝은 부분이 올라오게 만들기는 원합니다.
1.
포토샆에서 텍스쳐의 회색빛의 높이 맵을 그립니다. 흰색은 높고 검은 색은 낮습니다. 아래와 같습니다:
2.
이미지를 사용자의 메인 텍스쳐에 저장합니다.
3.
3. 유니티에서 이미지를 선택한후 24bit RGB 형식을 선택하고 인스펙터의 Import Settings 에서 Generate Normal Map 을
활성화 합니다:
1.
모델의 Material Inspector 에서 Shader 의 드랍다운 창에서 'Bumped Diffuse'를 선택합니다:
2.
프로젝트 창에서 'Normalmap' 텍스쳐 칸으로 텍스쳐를 드래그 합니다:
이제 사용자의 객체에 normal map 이 적용되었습니다:
힌트
•
튀어오른 부분을 좀더 잘 보이게하기 위해서는 “Texture Import Settings”에서 “Bumpyness slider”를 사용하거나 포토샆에서
텍스쳐를 흐리게 하십시오. 어떤지 실험을 해보십시오.
세부 텍스쳐(Detail Textures)는 어떻게 이용하나요?
세부 텍스쳐는 작고 표면에 접근할수록 사라지는 미세한 패턴을 가집니다. 예를들어, 나무결, 석재의 불완전함 또는 지형의 지구적인
세부사항들이 있습니다. 그 것은 명시적으로 Diffuse Detail shader 와 함께 쓰입니다.
세부 텍스쳐는 모든 방향으로 타일을 해야합니다. 값이 0-127 인 색상은 어두운 객체를 어둡게, 128 은 변화를 주지 않고, 더 밝은
색상은 객체를 밝게 보이게 합니다. 이미지를 128 근처에 중심이 맞춰지도록 하는것이 중요한데 그렇지 않으면 객체가 접근할 수록
어두워 지거나 밝아 집니다.
1.
세부 텍스쳐의 그레이 스케일 이미지를 그리거나 찾으세요.
세부 텍스쳐
색상 수준(Levels)
2.
사용자 주 텍스쳐 옆에 이미지를 저장하세요.
3.
유니티에서 이미지를 선택하고 "Generate Mip Maps"에서 Fades Out 을 활성화하고 슬라이더를 Inspector 의 Import
Settings 에 있는 이것과 같이 설정합니다.
4.
탑 슬라이더는 사라지기 전에 텍스쳐가 얼마나 작아야 하는지를 결정하고 바닥에 있는 슬라이더는 세부 텍스쳐가 완전히
사라지기 전에 얼마나 멀리 떨어져야 하는지를 정합니다.
s.
5.
오른쪽의 Material Inspector 의 쉐이더 드랍다운에서 Diffuse Detail 를 선택합니다:
6.
Project View 에서 텍스쳐를 드래그해서 세부 텍스쳐 칸으로 옮깁니다.
7.
기울기 값은 높은 값으로 설정합니다
어떻게 큐브맵(Cubemap) 텍스쳐를 만드나요?
큐브맵반사적인 유니티에 설치되어 있는 쉐이더에 쓰입니다 Reflective built-in shaders. 만들기 위해선 여섯개의 2D 텍스쳐를
만들고 새로운큐브맵 에셋을 만들거나 하나의 정사각형 텍스쳐로 큐브맵을 만듭니다. 좀더 자세한 사항을 Cubemap Texture 에
있습니다.
정적이고 동적인 큐브맴 반사는 스크립트로 만들어질 수 있습니다. 코드 예는 Camera.RenderToCubemap에 있으며 에디터에서
바로 만들어 볼 수 있는 간단한 위저드 스크립트가 포함되어 있습니다.
어떻게 Skybox 를 만드나요?
A Skybox 는 게임에서 모든 그래픽의 뒤에 그려진 여섯개의 면을가진 큐브입니다. 여기에 그것을 만드는 방법이 있습니다:
1.
Skybox 의 여섯 면에 맞는 여섯 개의 텍스쳐를 만들고 그것을 프로젝트의 에셋 폴더에 넣습니다.
2.
각 텍스쳐에서 Wrap Mode 를 Repeat 에서 Clamp 로 바꿉니다. 이것을 하지 않으면 가장자리의 색이 맞지 않을 것입니다:
3.
메뉴 바에서 Assets->Create->Material 를 선택하여 새로운 Material 를 생성합니다.
4.
Inspector 맨위의 드랍다운에서 Shader 를 선택하고 RenderFX->Skybox 를 선택합니다.
5.
재료의 텍스쳐 칸에 여섯개의 텍스쳐를 할당합니다. 각 텍스쳐를 Project View 에서 상응하는 칸으로 드래그해서 하실 수
있습니다.
Skybox 를 작업 중인 씬으로 할당하기 위해서는:
1.
메뉴 바에서 Edit->Render Settings 를 선택합니다.
2.
Inspector 의 Skybox Material 칸에 새로운 Skybox Material 를 드래그 합니다.
주의: Standard Assets 패키지는 몇가지 준비된 Skyboxes 를 포함하고 있습니다 – 이것은 시작을 위한 가장 빠른 방법입니다!
어떻게 Mesh Particle Emitter 를 만드나요?
Mesh Particle Emitters 는 보통 어디에 조각들을 방출 할 것인지에 대한 강한 제어가 필요할때 사용됩니다.
예를 들어, 불붙은 칼을 만들 때:
1.
씬에 메쉬를 드래그 합니다.
2.
메쉬 렌더러 인스펙터의 타이틀 바에서 오른쪽 클릭을 하고 Remove Component 를 선택해 메쉬 렌더러를 제거 합니다.
3.
Component->Particles 메뉴에서 Mesh Particle Emitter 를 선택합니다.
4.
Component->Particles 메뉴에서 Particle Animator 를 선택합니다.
5.
Component->Particles 메뉴에서 Particle Renderer 를 선택합니다.
이제 메쉬에서 조각들이 나오는 것을 볼수 있습니다.
Mesh Particle Emitter 에서 값을 가지고 실험해 보세요.
특히 Mesh Particle Emitter Inspector 에 있는 Interpolate Triangles 를 활성화하고 Min Normal Velocity 와 Max Normal
Velocity 를 1 로 설정하세요.
나오는 조각들의 모양을 사용자 정의하기 위해서는:
1.
메뉴 바에서 Assets->Create->Material 를 선택합니다.
2.
Material Inspector 에서 shader 의 드랍다운에서 Particles->Additive 를 선택합니다.
3.
Project view 에서 Material Inspector 의 텍스쳐 칸에 텍스쳐를 드래그해서 가져다 놓습니다.
4.
프로젝트에서 Scene View 의 "Particle System” 으로 재료를 드래그 합니다.
이제 메쉬에서 텍스쳐화 된 조각이 나오는 것을 볼 수 있습니다.
See Also
•
Mesh Particle Emitter Component Reference page
어떤게 스플래쉬 화면을 만드나요?
Desktop
유니티에서 어떻게 스플래쉬 화면 또는 다른 형태의 전체화면 이미지를 만드는지에 대한 것이 여기에 있습니다. 이 방법은 여러개의
해상도와 비율에서 가능합니다.
1.
첫째로 큰 텍스쳐가 필요합니다. 이상적으로 텍스쳐의 크기는 2 의 제곱수여야 합니다.대부분의 화면에 맞는 1024x512 가
예입니다.
2.
메뉴 바에서 GameObject->Create Other->Cube 를 사용하여 박스를 만듭니다.
3.
Scale 란에 첫 두칸에 16 과 9 를 넣음으로써 크기가 16:9 형식이 되게 합니다:
4.
텍스쳐를 큐브안에 드래그한 후 Camera 가 그것을 가리키게 합니다. 큐브가 16:9 비율에서도 보일수 있도록 카메라를
위치합니다. 결과를 보기 위해서는 Scene View 의 Aspect Ratio Selector 를 사용합니다.
iOS
Customising IOS device Splash Screens
Android
Customising Android device Splash Screens
어떻게 Spot Light Cookie 를 만드나요?
유니티는 Standard Assets 에 몇 개의 빛쿠키(Light Cookie)를 가지고 있습니다. 표준 에셋이 프로젝트에 불려올 때 Standard
Assets->Light Cookies 에서 찾을 수 있습니다. 이 페이지에서는 어떻게 사용자 자신의 것을 만드는 지를 설명합니다.
사용자 씬에 다양한 비주얼 디테일을 추가하는 좋은 방법은 게임의 빛의 정확한 모양의 제어를 위해 사용하는 그레이 스케일의
텍스쳐인 쿠키를 사용하는 것입니다. 이것은 움직이는 구름과 짙은 안개효과를 내는데 아주 훌륭합니다. Light Component
Reference page 은 이 모든 것에 대한 더 많은 정보를 가지고 있습니다. 그러나 쿠키에서 텍스쳐가 사용되기 위해서는 다음의
속성들이 설정 되어야 합니다:
스포트라이트를 위한 빛 쿠키를 생성하기:
1.
포토샾에서 쿠키 텍스쳐를 페인트합니다. 이미지는 그레이 스케일이어야 합니다. 하얀 픽셀은 빛 전체 강도를 의미하며
검은 픽셀은 빛이 없음을 의미합니다. 텍스쳐의 경계는 완전한 검은색이어야 하며 그렇지 않으면 빛이 스포트라이트에서
새어 나가는 것처럼 보일것입니다.
2.
Texture Inspector 에서 Repeat Wrap 모드를 Clamp 로 바꾸세요.
3.
텍스쳐를 선택하고 Inspector 에 있는다음의 Import Settings 을 바꾸세요.
4.
Border Mipmaps 를 활성화 하세요.
5.
Build Alpha From Grayscale(이런 식으로 그레이스케일 쿠키를 만들고 유니티가 이것을 자동으로 알파맵으로
바꿉니다)를 활성화 하세요.
6.
텍스쳐 형식을 Alpha 8 Bit 으로 바꿉니다.
가져온 모델의 회전을 어떻게 고치나요?
어떤 3D 아트 패키지는 z 축이 위를 향하도록하여 내보내기가 됩니다. 대부분의 유니티의 기준 스크립트는 3D 에서 y 축이 up 을
나타냅니다. 유니티에서는 이 문제를 고치기 위해 스크립트를 바꾸는 것보다 회전을 바꾸는 것이 더욱 쉽습니다.
z 축이 위를 가리키는 모델
가능하면 3D 모델 프로그램에서 내보내기전에 y 축이 위를 향하도록 모델을 고칠것을 추천합니다.
만약 이것이 가능하지 않다면 유니티에서 추가적인 부모 변환을 통해 이것을 고칠수 있습니다:
1.
GameObject->Create Empty 를 이용해 빈 GameObject 를 생성합니다.
2.
GameObject 가 메쉬의 중간이나 객체가 회전하기 윈하는 곳에 오도록합니다.
3.
빈 GameObject 에 그 메쉬를 드래그합니다.
이제 그 메쉬를 똑바른 방향으로 빈 GameObject 의 Child 으로 만듭니다. y 축을 위로나타내는 스크립트를 만들 때마다 그것을 빈
Parent GameObject 에 붙여줍니다.
추가적인 빈 변환을 가진 모델
어떻게 물(Water)를 이용하나요?
주의: 이 페이지의 내용은 데스크탑 에디터에서만 적용됩니다.
유니티는 Standard Assets and Pro Standard Assets packages 안에 몇가지 물 prefabs(필요한 쉐이더, 스크립트, 아트 에셋을
포함)를 포함합니다. 유니티 프로는 실시간 반사와 굴절을 포함하는 반면 유니티는 기본 물을 포함하고 두 경우 모두 일광 과 야간
물로 따로 제공됩니다.
반사되고 있는 일광 물(유니티 프로)
반사/굴절 되고 있는 일광 물(유니티 프로)
물 설정
대부분의 경우 기존의 Prefab 중 하나를 씬에 위치시기면 됩니다(Standard Assets installed 이 설치되었나 확인하세요):
•
유니티는 Standard Assets->Water 에 Daylight Simple Water 와 Nighttime Simple Water 를 가지고 있습니다.
•
유니티 프로는 Pro Standard Assets->Water(그러나 Standard Assets->Water 에서 몇가지 에셋을 필요로 합니다)에 Daylight
Water 와 Nighttime Water 를 가지고 있습니다. Inspector 에서 물 모드(Simple, Reflective, Refractive)를 선택할 수 있습니다.
Prefab 은 물을 위해 타원 모양의 메쉬를 사용합니다. 다른 메쉬를 사용하고 싶다면 가장 쉬운 방법은 물 객체의 메쉬 필터에서
그것을 바꾸면 됩니다:
물 처음부터 생성하기 (고급)
유니티으 간단한 물은 평면같은 메쉬에 스크립트를 첨가하는 것과 물 쉐이더를 사용하는 것을 필요로 합니다:
1.
물을 위한 메쉬를 가집니다. 이것은 수평으로 평평한 메쉬여야 합니다. UV 좌표는 필요하지 않습니다. 물 GameObject 는
Inspector 에서 설정할 수 있는 물 레이어를 사용하여야 합니다.
2.
WaterSimple 스크립트(Standard Assets/Water/Sources 에 있는)를 객체에 첨부합니다.
3.
재료의 FX/Water (simple) 쉐이더를 사용하거나 제공된 물 재료 (Daylight Simple Water 또는 Nighttime Simple Water)에
변화를 줍니다.
유니티 프로의 반사/굴절 물은 처음부터 생성하려면 비슷한 절차가 필요합니다:
1.
물을 위한 메쉬를 가집니다. 이것은 수평으로 평평한 메쉬여야 합니다. UV 좌표는 필요하지 않습니다. 물 GameObject 는
Inspector 에서 설정할 수 있는 물 레이어를 사용하여야 합니다.
2.
Water 스크립트(Pro Standard Assets/Water/Sources 에 있는)를 객체에 첨부합니다.
o
Inspector 에서 물 렌더링 모드를 설정할 수 있음: Simple, Reflective or Refractive.
3.
재료의 FX/Water 쉐이더를 사용하거나 제공된 물 재료(Daylight Water 또는 Nighttime Water)에 변화를 줍니다.
물 재료의 속성
이 속성들은 반사/굴절 물 쉐이더에서 사용됩니다. 대부분은 간단한 물 쉐이더에서도 사용됩니다.
Property:
Wave scale
Function:
보통 맵에서의 파도 크기. 작은 값일 수록 큰 물 파도를 말함.
Reflection/refraction
파도 보통 맵에의한 반사/굴절의 분산 정도.
distort
Refraction color
Environment
반사에 의한 추가 색상.
실시간 반사와 굴절을 위한 텍스쳐 렌더.
reflection/refraction
파도의 모양을 정의합니다. 마지막 파도는 각자 다른 방향, 크기, 속도로 넘어가는 두 보통 맵을
Normalmap
합쳐 생성됩니다. 두번제 보통 맵은 처음 것의 반만한 크기입니다.
Wave speed
첫번째 보통 맵과(첫번째 두번째 숫자) 두번째 보통 맵(세번째 네번째 숫자)의 넘어가는 속도.
Fresnel
Fresnel 영향을 제어하는 알파 채널의 텍스쳐 – 보는 각도에 따른 반사/굴절의 보여지는 정도.
나머지 속성들은 반사와 굴절 쉐이더 자체에서는 사용되지 않지만 사용자 비디오 카드가 지원하지 않아 간단한 쉐이더로 돌아가야
할 수도 있으므로 모든 속성은 설정되어야 합니다:
Property:
Reflective color/cube and
Function:
보는 각도에 따른 물 색(RGB)과 Fresnel 영향(A)을 정하는 텍스쳐 .
fresnel
Horizon color
지평선의 물 색상(간단한 물 쉐이더에서만 쓰임)
어떤 더 낳은 쉐이더가 실행될 수 없을 때 정말 오래된 비디오카드에서 물을 나타내기 위해
Fallback texture
쓰이는 텍스쳐.
하드웨어 지원
•
반사 + 굴곡 물은 pixel shader 2.0 지원이 되는 그래픽 카드(GeForce FX 이상, Radeon 9500 이상, Intel 9xx)와 작동합니다. 더
오래된 카드에서는 반사 물이 사용됩니다.
•
반사 물은 pixel shader 1.4 지원이 되는 그래픽 카드(GeForce FX 이상, Radeon 8500 이상, Intel 9xx)와 작동합니다. 더 오래된
카드에서는 간단한 물이 사용됩니다.
•
간단한 물은 하드웨어의 성능에따라 다양한 단계의 디테일을 보여주면서 거의 모든 곳에서 작동합니다.
FBX export guide
유니티는 많은 유명한 3D 프로그램에서 생성되는 FBX 파일을 지원합니다. 믿을수 있는 결과물을 위해서 이 가이드를 사용하십시오.
Select > Prepare > Check Settings > Use 2011.3 > Verify > Import
무엇을 내보내길 원하나요? – 메쉬, 카메라, 빛, 애니메이션 장비 등의 내보내는 범위에 대해 알아두세요.
응용 프로그램들은 보통 selected objects 나 whole scene 을 내보낼 수 있게합니다.
선택적으로 내보내거나 씬에서 원치않는 데이타를 제가함으로써 원하는 객체만 내보낼 수 있도록 하십시오.
좋은 작업 방법이란 작업중인 파일을 모든 빛, 가이드, 제어 장치 등과 함께 두지만 export selected 로 필요한 것만 또는 사용자 정의
씬 내보내기로 내보내는 것을 말합니다.
무엇을 포함해야 하나요? – 에셋을 준비하십시오.
•
Meshes - 구성 기록을 지우고 다각형으로 변환하고, 필요하면 , 삼각형이나 사각형으로 분할 하세요
•
Animation - 정확한 장치를 선택하고 프레임율, 애니메이션 길이 등을 확인합니다.
•
Textures - 텍스쳐가 사용자의 유니티 프로젝트나 “\textures “ 폴더에 살아 있도록 합니다
•
Smoothing - 스무딩그룹 및/또는 부드러운 메쉬를 원한다면 체크하세요
어떻게 그런 요소들을 포함하나요? – FBX 내보내기 설정을 확인하세요
내보내기 대화상자에서 설정을 잘 알아두어서 유니티에서 무엇을 원하고 fbx 와 무엇을 매치시킬 수 있는지를 알고계세요
어떤 버전의 FBX가 사용되어지고 있나요? 의심이 간다면 2011.3을 사용하세요.
Autodesk 는 FBX 설치자를 정기적으로 업데이트하며 자신의 소프트웨어 버전과 다른 타사의 프로그램 버전에 따라 다른 결과를
제공합니다.
See Advanced Options > FBX file format 를 확인하세요.
그것이 작동할까요? – 내보내기를 확인하세요.
•
파일 크기를 확인하세요 – 파일 사이즈를 체크합니다. (예를들어 >10kb?)
•
사용자의 FBX 를 생성하기 위해 사용하는 3D 패키지 씬에 그 FBX 를 다시 불러오기를 하세요. – 이것이 원하던 결과를 보여주나요?
불러 오기!
•
유티티에서 불러오기
•
인스펙터에서 FBX 불러오기를 확인하세요: 텍스쳐, 애니메이션, 스무딩, 등.
마야 FBX 대화상자 예입니다:
어떻게 3D 프로그램에서 객체를 불러올 수 있나요?
유니티는 대부분의 유명한 3D 프로그램에서 불러오기를 지원합니다. 아래에서 작업 중인 것을 하나 고르세요:
•
Maya
•
Cinema 4D
•
3ds Max
•
Cheetah3D
•
Modo
•
Lightwave
•
Blender
다른 프로그램들
유니티는 FBX, dae, 3DS, dxf , obj 파일을 읽을 수 있어서 사용자의 프로그램이 이런 파일을 내보낼 수 있으면 됩니다.
Hints
•
내보내진 메쉬 옆에 텍스쳐라는 폴더에 텍스쳐를 저장합니다. 이것은 유니티가 항상 텍스쳐를 찾을수 있게하고 자동으로 그
텍스쳐를 다른 것에 연결할 수 있도록 합니다.
See Also
•
Modeling Optimized Characters
•
How do I use normal maps?
•
Mesh Import Settings
•
How do I fix the rotation of an imported model?
Maya 에서 객체 불러오기
유니티는 Maya 파일을 그대로 불러옵니다. 시작하려면 .mb 또는 .ma 파일을 프로젝트 에셋 폴더에 위치 시킵니다. 유니티로
돌아오면 자동으로 씬이 불려오며 프로젝트 뷰에 보이게 될 것입니다.
유니티에서 사용자 모델을 보기 위해서는 프로젝트 뷰에서 씬뷰나 계층뷰로 드래그 합니다.
현재 유니티가 Maya 에서 불러오는것:
1.
모든 노드와 그 위치, 방향 그리고 크기. 피벗점과 이름.
2.
메쉬와 그 꼭지점 색상, 법선 그리고 최대 2 개의 UV sets.
3.
재료와 그 확산 텍스쳐와 색상. 메쉬당 다수의 재료.
4.
애니메이션 FK 와 IK
5.
뼈대 중심의 애니메이션
유니티는 블랜드 모양은 불러오지 않습니다. 대신 뼈대 기반의 애니메이션을 이용하세요. 유니티는 불러올때 다각형의 메쉬를
자동으로 삼각 측정하므로 Maya 에서 수동으로 이 작업을 할 필요가 없습니다.
캐릭터를 애니메이션화 하기위해 IK 를 사용한다면 프로젝트 뷰에서 불려온 .mb 파일을 선택하고 Inspector 의 Import Settings
대화창에서 Bake IK & Simulation 을 선택합니다.
요구사항
유니티에서 Maya 의 .mb 와 .ma 파일을 불러오기 위해서는 사용하는 컴퓨터에 Maya 가 설치되어 있어야 합니다. Maya 8.0 이상이
지원됩니다.
Maya가 설치되지 않은 컴퓨터에서 다른 컴퓨터의 Maya파일을 불러오고 싶다면 유니티가 그대로 불러오는 to fbx format 형식을
내보낼 수 있습니다. 최고의 결과를 위해 ->2011.3를 설치하세요. 내보내기를 위해선 HOWTO_exportFBX를 보세요.
일단 내보내지면 유니티 프로젝트 폴더에 fbx 파일을 위치시킵니다. 유니티가 자동으로 그 fbx 파일을 불러올 것입니다.
HOWTO_exportFBX 에서 언급 된것처럼 Inspector 에서 FBX 불러오기 설정을 확인하세요.
불러오기 과정의 이면 (고급)
유니티가 Maya 파일을 불러올때 백그라운드에서 Maya 를 실행시킬 것입니다. 그러면 유니티는 .mb 파일을 유니티가 읽을 수 있는
형식으로 바꾸기위해 Maya 와 대화할 것입니다. 유니티에 처음으로 Maya 파일을 불러올때 Maya 는 명령어 과정에서 시작되며
이것은 20 초 정도 소요되지만 계속되는 불러오기에선는 아주 빠를 것입니다.
문제해결
•
씬은 간단히하고 유니티에서 필요한 객체만 포함하는 파일로 작업하도록 노력합니다.
•
메쉬에 문제가 생기면 패치, 표면 등이 (Modify > Convert + 또한 Mesh > Quadragulate/Triangulate)으로 바뀌었는지 확인합니다.
유니티는 오로지 다격형만을 지원합니다.
•
흔치않게 Maya 는 노드 히스토리를 망치는데 이것은 모델이 정확하게 내보내지는데 문제가 됩니다. 다행히 Edit->Delete All by
Type->History 를 선택함으로써 간단히 이문제를 해결할 수 있습니다.
•
유니티는 가능한 최신 FBX 와 작동되므로 모델을 불러오는데 문제가 있다면 Autodesk최신 버전이나 fail-safe install 2011.3을
확인합니다.
•
Maya 에서의 애니메이션 베이킹은 있는 그대로 되기보다는 FBX 에서 이루어 지는데 이것은 좀더 복잡한 애니메이션이 알맞게
FBX 형식으로 바뀌는 것을 가능하게 합니다. 사용자가 구동키를 사용한다면 적어도 하나의 키를 애니메이션의 제대로된 베이킹을
위해 설정하십시오.
Cinema 4D 로 부터 객체 가져오기
유니티는 Cheetah3D 파일을 그대로 가져옵니다. 시작하기 위해서는 .c4d 파일을 프로젝트의 에셋폴더에 가져다 놓습니다.
유니티로 다시 돌아 갔을때 씬은 자동으로 불려오고 프로젝트 뷰에 나타날 것입니다.
유니티에서 당신의 모델을 보기위해서는 씬뷰의 프로젝트뷰에서 드래그 합니다.
당신이 .c4d 파일을 수정한다면 저장 될 때마다 유니티는 자동으로 업데이트 할 것입니다.
유니티는 현재 다음을 불러옵니다
1.
모든 노드의 위치, 회전, 크기. 피벗 위치와 이름도 불러옵니다.
2.
메쉬의 꼭지점, 다각형, 삼각형, UV, 법선.
3.
재료의 텍스쳐와 퍼지는 색. 메쉬당 여러개의 재료.
4.
애니메이션 FK(IK 는 수동으로 구워져야 합니다).
5.
뼈대를 바탕으로한 애니메이션.
유니티는 포인트 수준의 애니메이션(PLA)들을 현재 임포트하지 않습니다. 뼈대 기본 애니메이션들을 대신하여 쓰십시오.
IK 를 이용한 애니메이션화 된 캐릭터
Cinema4D 에서 IK 를 사용해서 캐릴터를 애니메이션화 했다면 내보내기 전에 Plugins->Mocca->Cappucino 를 선택해서 IK 를
구워야 합니다. 만약 유니티에서 불러오기 전에 IK 를 굽지 않는다면 거의 확실히 애니메이션화 된 뼈대가 아닌 애니메이션화된
위치들만 가지게 될 것입니다.
요구사항
•
.c4d 파일을 불러오기 위해서는 적어도 Cinema 4D 버전 8.5 이상이 설치되어야 합니다.
만약 Cinema 4D 가 설치되어 있지 않은데 다른 컴퓨터에서 Cinema 4D 파일을 불러오고 싶다면 유니티가 지원하는 FBX 형식으로
내보낼 수 있습니다:
1.
Cinema 4D 파일을 엽니다.
2.
Cinema 4D 에서 File->Export->FBX 6.0 를 선택합니다.
3.
유니티의 프로젝트 에셋 폴더에 내보내진 fbx 파일을 가져다 놓습니다. 유니티가 자동으로 그 fbx 파일을 불러올 것입니다.
힌트
1.
Cinema 4D 파일을 가져오는 속도를 최대화 하기 위해서는: Cinema 4D 환경설정(Edit->Preferences)에가서 FBX 6.0 환경
설정을 선택합니다. 이제 Embed Textures 의 체크를 해제합니다.
불러오기 과정에서 더 나아가(고급)
유티티가 Cinema 4D 파일을 불러올때 자동으로 Cinema 4D 플러그인을 설치하고 Cinema 4D 를 백그라운드에서 실행합니다.
그러면 유니티는 .c4d 파일을 자신이 읽을수 있는 형식으로 바꾸기위해 Cinema 4D 와 데이타를 주고 받습니다. .c4d 파일을 처음
가져오고 Cinema 4D 가 아직 열리지 않았으면 그것을 열기위해 시간이 조금 걸리는데 그 이후르는 .c4d 파일을 가져오는 것은 아주
빠를 것입니다.
Cinema 4D 10 지원
.c4d 파일을 직접 가져올 때 유니티는 Cinema 4D 가 그 파일을 FBX 로 변환하도록 합니다. Maxon 에서 Cinema 4D 10.0 이 나왔을
때 FBX 내보내기가 아주 심각하게 망가졌었 습니다. Cinema 4D 10.1 에서는 많은 문제가 해결되었습니다. 그래서 저희는 10.0
버전으로 업그레이드 하기를 추천합니다.
Maxon FBX 내보내기는 아직도 문제들이 남아있습니다. 아직까지는 Cinema 4D 10 에서 새로 생긴 관절을 사용하는 애니메이션화
된 캐릭터를 문제없이 내보내는 방법이 없어 보입니다. 그러나 9.6 에서 있는 오래된 뼈대 시스템은 완벽하게 내보내기가 가능합니다.
그러므로 애니메이션화 된 캐릭터를 생성할 때 관절대신 뼈대를 사용하는 것은 아주 중요합니다.
3D Studio Max 에서 객체 불러오기
사용자가 3dsMax 에서 3D 객체를 만든다면 .max 파일을 직접 프로젝트에 저장할 수 있고 또는 Autodesk .FBX 형식을 이용해
유니티로 내보낼 수 있습니다. 그것을 본래의 .max 형식으로 저장할 것을 권합니다.
현재 유니티가 3ds Max 에서 불러오는것
1.
모든 노드와 그 위치, 방향 그리고 크기. 피벗점과 이름.
2.
메쉬와 그 꼭지점 색상, 법선 그리고 하나 이상의 two UV sets.
3.
재료와 그 확산 텍스쳐와 색상. 메쉬당 다수의 재료.
4.
애니메이션.
5.
뼈대 중심의 애니메이션.
3DS Max 에서 FBX 로 수동으로 내보내기
1.
Autodesk website에서 최신 fbx exporter를 다운로드하고 설치 합니다 .
2.
씬을 .fbx 형식으로 내보냅니다(File->Export or File->Export Selected). 기본 내보니기 옵션 사용이 괜찮아야 합니다.
3.
내보내진 fbx 파일을 유니티 프로젝트 폴더로 옮깁니다.
4.
유니티로 돌아올 때 .fbx 파일이 자동으로 불립니다.
5.
프로젝트 뷰에서 씬뷰로 그 파일을 드래그 합니다.
내보내기 옵션
모든 경우에 FBX 내보내기 옵션(기본적으로 모든것을 내보냄)이 괜찮아야 합니다.
기본 FBX 내보내기 옵션 (fbx 플러그인 2009.3 버전)
뼈대 기반 애니메이션 내보내기
뼈대 기반의 애니메이션을 내보낼 때는 따라야할 절차가 있습니다:
1.
원하는 데로 뼈대 구조를 설정합니다.
2.
FK 와/또는 IK 를 이용하여 원하는 애니매이션을 만듭니다.
3.
모든 뼈대와 IK solver 를 선택합니다.
4.
Motion->Trajectories 으로가서 Collapse 을 누릅니다. 유니티는 키 필터를 만드므로 내보내는 키의 수는 중요하지 않습니다.
5.
새로운 FBX 형식으로 "Export" 또는 "Export selected"를 누릅니다.
6.
보통처럼 FBX 파일을 에셋에 떨굽니다.
7.
유니티에서 근본 뼈대에 텍스쳐를 재료로 다시 할당 합니다.
메쉬와 3db Max 의 애니메이션과 뼈대 계층을 유니티로 내보낼 때, 생성된 GameObject 계층은 3dx Max 에서 보이는 "Schematic
view"의 계층과 일치 할 것입니다. 하나의 차이점은 유니티가 GameObject 를 애니메이션을 포함하는 새로운 루트로 위치시킬
것이며 메쉬와 재료 정보를 루트 뼈대에 위치 시킨 다는 것입니다.
애니메이션과 메쉬 정보를 같은 유니티 GameObject 에 가지고 싶다면 3dx Max 의 계층 뷰에 가서 뼈대 계층의 뼈대를 메쉬 노드에
종속시킵니다.
Lightmapping 을 위한 두개의 UV 집합 내보내기
3ds Max' Render To Texture 와 자동 언랩핑(unwrapping) 기능은 빛맵을 생성하는데 쓰일 수 있습니다. 유니티에 내장된
lightmapper 가 있다는 것에 주의 하십시오. 하지만 사용자 작업에 더 잘 맞다면 3dmax 를 사용할 수도 있습니다. 주로 하나의 UV
집합이 주 텍스쳐와 보통 맵으로 쓰이고, 또다른 UV 집합은 빛맵 텍스쳐로 쓰입니다. 두개의 UV 집합이 잘 작동하게 하기 위해서는
3ds Max 에서의 재료는 Standard 이어야 하며 Diffuse(메인 턱스쳐를 위해)와 Self_Illumination(빛맵을 위해) 맵 공간은 설정 되어야
합니다:
3ds Max 에서의 Lightmapping 를 위한 재료 설정. self-illumination 맵 사용하기
객체가 껍질 재료 타입을 사용한다면 현 Autodesk's FBX exporter 는 UV 정보를 정확히 내보내지 못할 것입니다.
또다른 방법으로 사용자는 Multi/Sub 객체 재료 타입을 사용하고 아래와 같이 확산 맵 공간의 주 텍스쳐와 빛맵을 이용하여 두 개의
부재료를 설정할 수 있습니다. 그러나 사용자 모델의 모양이 다른 부재료 ID 를 사용한다면 이것은 여러개의 재료가 불려오는 결과를
초래하고 이것은 최적의 성능에 좋지 않습니다.
3ds Max 에서의 멀티/부 객체 재료를 이용한 빛매핑의 또다른 재료 설정
문제해결
모델 불러오기에 문제가 있으면 최신 FBX플러그인이 설치되있는지 확인합니다. 이것은 Autodesk website에서 다운로드 받을 수
있습니다.
Cheetah3D 로 부터 객체 가져오기
유니티는 Cheetah3D 파일을 그대로 가져옵니다. 시작하기 위해서는 .jas 파일을 프로젝트의 에셋폴더에 가져다 놓습니다. 유니티로
다시 돌아 갔을때 씬은 자동으로 불려오고 프로젝트 뷰에 나타날 것입니다.
유니티에서 당신의 모델을 보기위해서는 씬뷰의 프로젝트뷰에서 드래그 합니다.
당신이 .jas 파일을 수정한다면 저장 될 때마다 유니티는 자동으로 업데이트 할 것입니다.
유니티는 현재 다음을 불러옵니다
1.
모든 노드의 위치, 회전, 크기. 피벗 위치와 이름도 불러옵니다.
2.
메쉬의 꼭지점, 다각형, 삼각형, UV, 법선.
3.
애니메이션.
4.
재료의 텍스쳐와 퍼지는 색.
요구사항
•
적어도 Cheetah3D 2.6 이상의 버전이 필요합니다.
Modo 로 부터 객체 가져오기
유니티는 Modo 파일을 그대로 가져옵니다. 이 작업은 Modo COLLADA 내보내기를 사용하여 이루어 집니다. Modo 버전 501
이상에서는 이 방법을 씁니다. 시작하기 위해서는 .lxo 파일을 프로젝트의 에셋폴더에 가져다 놓습니다. 유니티로 다시 돌아 갔을때
씬은 자동으로 불려오고 프로젝트 뷰에 나타날 것입니다.
501 이전의 Modo 버전들에서는 간다히 당신의 Modo 씬을 FBX 나 COLLADA 파일로 유니티 프로젝트 폴더에 저장하세요.
유니티에서는 그 씬은 자동적으로 임포트 되고 Project View 에 보여질 것입니다.
유니티에서 당신의 모델을 보기위해서는 Scene View 의 프로젝트뷰에서 드래그 합니다.
당신이 .lxo 파일을 수정한다면 저장 될 때마다 유니티는 자동으로 업데이트 할 것입니다.
유니티는 현재 다음을 불러옵니다
1.
모든 노드의 위치, 회전, 크기. 피벗 위치와 이름도 불러옵니다.
2.
메쉬의 꼭지점, 다각형, 삼각형, UV, 법선.
3.
재료의 텍스쳐와 퍼지는 색. 메쉬당 여러개의 재료.
4.
애니메이션
요구사항
•
*.lxo 파일을 그대로 가져오기 위해서는 modo 501 이상의 버전이 필요합니다.
Lightwave 에서의 객체 불러오기
Lightwave 에서 Ligthwave 를 위한 FBX 플러그인을 사용하여 메쉬와 애니메이션을 불러올 수 있습니다.
유니티는 현재 다음을 불러옵니다
1.
모든 노드와 그 위치, 방향, 크기. 피벗점과 이름들.
2.
메쉬와 그의 UV 와 법섭들 .
3.
재료와 그 텍스쳐와 분산 색상. 메쉬당 여러 재료들.
4.
애니메이션.
5.
뼈대 중심의 애니메이션 .
설치
최신 Lightwave FBX 내보내기를 다음에서 다운로드 합니다:
•
OS X lighwave 8.2 and 9.0 plugin
•
OS X Lighwave 8.0 plugin
•
Windows Lighwave 8.2 and 9.0 plugin
•
Windows Lighwave 8.0 plugin
이 플러그인을 다운로드 받으면 자동으로 this licence에 동의하게 됩니다.
두버전의 플로그인이 있는데 하나는 LightWave 8.0dmf 위한 것이고 하나는 LightWave 8.2 부터 9.0 까지를 위한 것입니다. 정확한
버전을 설치하였는지 확인하세요.
맥을 위한 플러그인은 OS X 패키지와 함께합니다. 패키지 설치를 위해 그것을 더블 클릭하면 인스톨러는 정확한 폴더에 그것을
위치시키도록 노력할 것입니다. 만약 그것이 사용자의 LightWave 플러그인 폴더를 찾을 수 없다면 자신만의 LightWave 폴더를
사용자 프로그램폴더에 만들고 그곳에 가져다 놓습니다. 만약 후자의 경우가 생긴다면 그것을 사용자 LightWave 플러그인
폴더(또는 다른 하위폴더)에 이동 시켜야 합니다. 그곳에 옮겨지면 "Edit Plugins" panel (옵션-F11) -을 통해 LightWave 에 그
플러그인을 추가합니다. 어떻게 플러그인을 추가하는 지에 대한 좀더 자세한 설명은 메뉴얼을 참조하세요.
일단 LightWave 에 추가되면 그 플러그인은 Utility 의 Generics 메뉴를 통해 접근 가능합니다 만약 Generic 메뉴가 존재하지 않으면
"Generic Plugins"라는 이름을 가지고 있습니다. 그것을 편안한 메뉴에 추가하십시오(어떻게 하는지에 대한 자세한 설명은
LightWave 메뉴얼을 참조하세요).
설치에 대한 좀더 자세한 정보는 인스톨러에서 다운로드 할 수 있는 릴리즈 노트에서 볼수 있습니다.
내보내기
모든 객체와 애니메이션은 레이아웃(Modeler FBX exporter 는 존재하지 않습니다)에서 내보내 져야합니다.
1. Generics 메뉴에서 Export to FBX 를 선택합니다
2. FBX export 대화 창에서 알맞은 설정을 선택합니다
•
fbx 파일 이름을 선택합니다. 현 유니티 프로젝트 안의 에셋 폴더에서 내보내진 fbx 파일을 저장하는 것을 잊지 마세요.
•
FBX 대화상자 에서 사용자는 Embed Textures 를 선택해야 합니다. 그렇지 않으면 내보내진 객체는 UV 를 가지지 않을 것입니다.
이것은 Lightwave fbx exporter 에 있는 버그이며 Autodesk 에 따라 미래 버전에서 고쳐질 것입니다.
•
사용자가 유니티에 애니메이션을 내보내고 싶으면 "Animations"이 체크되어 있어야 합니다. 또한 "Lights" 또는 "Cameras"가
체크되어 있어야 합니다.
•
유니티에서 내보내진 애니메이션 클립의 이름을 바꾸기 위해서는 "LW Take 001"에서 마음에 드는 이름으로 고치세요.
3. 유니티로 전환.
•
유니티는 자동으로 fbx 파일을 불러들이며 텍스쳐를 위해 재료를 만듭니다.
•
불러들인 fbx 파일을 프로젝트 뷰에서 씬뷰로 옮겨 놓습니다.
중요 사항
•
사용자는 내보낼 때 또는 UV 가 내보내어 지지 않을 때 FBX 패널에서 Embed Textures 를 선택하여야 합니다.
•
애니메이션을 내보내고 싶으면 Animations 과 Camera 또는 Lights 를 활성화 시켜야 합니다.
•
텍스쳐는 항상 fbx 파일 옆에 "Textures"라는 폴더에 위치시키기를 권합니다. 이것은 유니티가 항상 텍스쳐를 찾고 자동으로 재료와
연결 시켜주는 것을 보장합니다.
블렌더(blender)에서 객체 불러오기
유니티는 블렌더 파일을 있는 그대로 가져옵니다. 이 작업은 버전 2.45 에 추가된 블렌더 FBX 내보내기를 사용하여 이루어 집니다.
이 이유로 블렌더 2.45 또는 그 이상의 버전으로 업데이트 하여야 합니다.(그러나 아래 요구사항을 보십시오).
시작하기 위해 당신의 .blend 파일을 프로젝트의 에셋 폴더에 저장하세요. 유니티로 다시 돌아왔을때 그 파일은 자동으로 불려와
Project View 에 보일 것입니다.
유니티에서 당신의 모델을 보기위해서는 Scene View 에 있는 프로젝트 뷰에서 그것을 드래그 하십시오.
만약 당신의 .blend 파일을 수정한다면 당신이 저장할 때마다 유니티는 자동으로 업데이트 할 것입니다.
유니티는 현재 다음을 불러옵니다
1.
모든 노드의 위치, 회전, 크기. 피벗 위치와 이름도 불러옵니다.
2.
메쉬의 꼭지점, 다각형, 삼각형, UV, 법선.
3.
뼈대
4.
표면이 있는 메쉬
5.
애니매이션
요구사항
•
2.45-2.49 또는 2.56 이상의 블렌더 버전이 필요합니다. (버전 2.50-2.55 는 작동하지 않습니다. 왜냐하면 FBX 내보내기가
블렌더에서 수정되었거나 망가졌습니다).
•
텍스쳐와 퍼지는 색상은 자동으로 할당 됩니다. 텍스쳐를 유니티의 씬뷰에 있는 메쉬에 드래그해서 손수 할당하십시오.
작업과정 질문들
•
모노디벨롭
•
팩키지 익스포트
•
스탠다드 에셋 설치
Mono 개발 시작하기
Mono 개발은 Unity 3.x 에서 할 수 있고 이 IDE 는 게임의 스크립트와 디버깅을 다루는 것을 도와줍니다.
Mono 개발 설정하기.
Mono 개발을 유니티와 작동하도록 설정하기 위해서는 유니티 환경설정에 가서 그것을 기본 에디터로 설정하면 됩니다.
Mono Develop 을 기본 에디터로 설정하기
그런후 기존의 프로젝트를 열거나 생성하고 Assets -> Sync Mono Develop Project 를 선택하여 프로젝트가 Mono Develop 과
싱크되도록 합니다.
Mono Develop 싱크.
이것은 Mono 개발에서 사용자의 프로젝트(에셋이 아닌 스크립트 파일만)을 열것입니다. 이제 디버깅을 시작할 수
있습니다.debugging.
프로젝트를 설정하는데 문제가 있으면 troubleshooting page 을 방문하세요.
프로젝트 간에 어떻게 에셋을 재사용 하나요?
게임을 만들어 가면서 유니티는 사용자의 에셋에 관한 많은 메타데이타를 저장합니다.(불러오기 설정, 다른 에셋으로의 링크, 등)
만약 사용자의 에셋을 다른 프로젝트로 가져가고 싶으면, 특정 방법을 사용해야합니다. 아래에 어떻게 에셋을 변화없어 다른
프로젝트로 옮길 수 있는지 보여줍니다.
1.
Project View 에서 내보내기 위한 에셋파일을 선택합니다.
2.
메뉴 바에서 Assets->Export Package...를 선택합니다.
3.
패키지에 이름을 만들고 원하는 곳에 저장하십시오.
4.
에셋을 가져가고 싶은 프로젝트를 엽니다.
5.
메뉴 바에서 Assets->Import Package...를 선택합니다.
6.
세번째 스텝에서 저장한 패키지 파일을 선택합니다.
Hints
•
유니티는 내보내기를 할때 모든 종속성을 내보낼 수 있습니다. 예를들어 만약 한 Scene 을 모든 종속성과 함께 내보내면 모든 씬에
나타난 모델, 텍스쳐, 다른 에셋들도 같이 내보내 지게 됩니다. 이것은 많은 에셋들을 따로 지정없이 한번에 내보내기 할 수 있는 빠른
방법입니다.
•
유니티 프로그램 옆의 기준 패키지 폴더에 내보내진 패키지를 저장하면 Create New Project 대화상자에 나타날 것입니다.
표준(Standard) 에셋을 어떻게 설치하고 업그레이드 하나요?
유니티는 다수의 표준 에셋 패키지를 가지고 있습니다. 이것은 대부분의 유니티 고객들이 널리 사용하는 에셋들의 모임입니다.
프로젝트 위자드에서 프로젝트를 새로 만들때 사용자가 선택적으로 이 에셋 모임을 포함할 수 있습니다. 이것은 유니티 설치
폴더에서 사용자의 새로운 프로젝트로 복사 됩니다. 이것은 사용자가 유니티를 새버전으로 업그레이드 했을 경우 이 에셋들은
새로운 버전으로 바뀌지 않을 것을 말하므로 에셋의 업그레이드를 필요로 합니다. 또한 새로운 버전에서는성능이나 품질 면에서
다른 행동을 보일 수 있으므로 파라미터의 변화를 필요로 합니다. 만약 게임이 갑자기 다른 모양이나 행동을 보이는 것을 원치
않는다면 업그레이드 전에 이것을 염두해두어야 할 것입니다. 패키지 내용을 확인하고 유니티 배포 노트를 확인하세요.
표준 에셋은 일인칭 제어, lens flares, Water prefabs, Image Effects 등의 유용한 것을 포함합니다.
새로운 프로젝트 생성시 보여지는 표준 에셋 패키지
업그레이드
가끔 표준 에셋을 업그레이드 하고 싶을 것입니다. 예를 들어 새로운 유니티 버전이 새로운 표준 에셋을 포함할 때:
1.
프로젝트를 엽니다 .
2.
Assets->Import Package 부메뉴에서 업데이트하고 싶은 패키지를 선택합니다.
3.
새로운 또는 바뀐 에셋이 나열되면 Import 를 누르싶시오.
가장 깔끔한 업그레이드를 위해서는 오래된 패키지의 내용을 먼저 삭제 하세요. 왜냐하면 어떤 스크립트나 효과 또는 prefab 은
은퇴하거나 더이상 사용되지 않을 때 제거할 방법이 없기 때문입니다 (하지만 꼭 오래된 버전을 백업하도록 하세요).
에셋 번들 (Pro 만 지원)
에셋번들은 사용자가 원하는 에셋을 담아 모아 내보내기를 할 수 있는 파일들입니다. 이 파일들은 당사의 압축 포맷을 사용하였고
사용자 어플리케이션으로 요청에 따라 설치할 수 있습니다. 이 기능을 사용하면 사용자는 모델, 텍스처, 오디오클립 등 심지어는
장면(scene) 전체를 사용 될 해당 장면(scene)에서 분리하여 스트리밍 할 수 있습니다. 그 파일들은 사용자 어플리케이션으로
콘텐츠를 쉽게 다운로드 받을 수 있도록 설계하였습니다.
에셋 번들은 유니티가 인식할 수 있는 어떤 타입의 에셋이든 포함할 수 있으며, 타입은 파일이름 확장자에 따라 결정됩니다.
사용자가 바이너리 맞춤 정보가 있는 파일을 포함하고 싶다면, 사용자는 그 파일의 확장자를 ".bytes" 라고 하여야 합니다. 유니티는
해당 파일을 TextAssets 타입으로 들여오기를 실행 할 것입니다.
에셋 번들의 사용법을 보여주는 샘플 코드를 보려면 AssetBundles Example Project을 참조하십시오.
에셋 번들의 생성
사용자가 에셋 번들을 구성하려면 다음 3 가지 클래스 매소드를
사용합니다: BuildPipeline.BuildAssetBundle, BuildPipeline.BuildStreamedSceneAssetBundle
그리고BuildPipeline.BuildAssetBundleExplicitAssetNames..
•
BuildPipeline.BuildAssetBundle 는 어떠한 타입의 에셋이라도 AssetBundles 을 사용하여 만들 수 있습니다.
•
사용자가 장면(scene)만을 포함하여 데이터가 생기는 데로 스트리밍하고 로딩 하고 싶다면,
BuildPipeline.BuildStreamedSceneAssetBundle 을 사용하면 됩니다.
•
BuildPipeline.BuildAssetBundleExplicitAssetNames 은 BuildPipeline.BuildAssetBundle 과 같으나 해당 프로젝트의 맞춤 문자열
ID(이름)를 명시할 수 있는 매개변수가 추가되어 있습니다.
에셋 번들 다운로드
에셋버들을 다운 받으려면 WWW.LoadFromCacheOrDownload을 사용을 권합니다. 다운로드가 완료되면 assetBundle 속성을
사용하여 에셋번들을 추출 할 수 있습니다. 예를 들면:
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
}
사용자가 @@.assetBundle 성을 사용하면 다운로드 된 데이터가 추출되고 에셋번들이 생성됩니다. 이 시점에서 사용자는 번들에
포함된 오브젝트를 사용할 준비가 완료 됩니다. LoadFromCacheOrDownload 를 사용하면 에셋번들이 캐시에 존재하지 않거나 혹은
존재하지만 요청한 버전보다 하위 버전과 연결되어 있다면, 해당 에셋번들을 다운로드 받을 것 있습니다. 그렇지 않다면 에셋 번들은
캐시에서 로딩 될 것 입니다.
번들에서 오브젝트를 로딩 혹은 언로딩
다운로드 받은 데이터에서 에셋 번들을 생성하고 나면, 사용자는 다음 세가지 매소드을 사용하여 오브젝트들을 로딩할 수
있습니다: AssetBundle.Load, AssetBundle.LoadAsync 그리고AssetBundle.LoadAll.
•
AssetBundle.Load 은 이름 ID 을 매개변수로 사용하여 로딩할 것입니다. 해당 이름은 프로젝트 뷰에서 확인할 수 있습니다.
사용자는 선택적으로 오브젝트 타입을 Load 매소드의 매개변수로 전달하여 해당 오브젝트가 특정한 타입으로 로딩되게 할 수
있습니다.
•
AssetBundle.LoadAsync 는 위에 설명한 Load 매소드와 같이 동작하나 에셋이 로딩 되는 동안 주 스레드를 막지 않을 것 입니다.
이 매소드를 사용하면 대량의 에셋을 한꺼번에 받는 동안 사용자 어플리케이션이 일시 중지 되는 것을 방지할 수 있습니다
•
AssetBundle.LoadAll 는 사용자의 에셋번들에 담긴 모든 오브젝트를 로딩할 것 입니다. AssetBundle.Load 와 함께, 사용하자는
타입에 따자 특정 타입의 오브젝트를 걸러낼 수 있습니다.
에셋을 언로드 하려면 사용자는 AssetBundle.Unload을 사용하면 됩니다. 이 매소드는 Boolean 매개 변수를 받아 유니티에게 다운
받은 번들에서 모든 데이터(로딩된 에셋 오브젝트 포함)를 언로드 할지 아니면 압축된 데이터 만을 언로드 할지를 말해 줍니다.
사용자 어플리케이션이 에셋 번들에서 오브젝트 일부만을 사용하고 일부 메모리를 비워두고 싶다면, false 값을 전달하여
메모리로부터 압축데이터를 언로드 할 수 있습니다. 해당 에셋 번들에서 모든 것을 완전히 언로드하고 싶다면, true을 전달하여 에셋
번들에서 받은 에셋은 지워버릴 수 있습니다.
에셋 번들 내 오브젝트 리스트
사용자는 AssetBundle.LoadAll 을 사용하여 해당 에셋번들에 포함된 모든 오브젝트 리스트를 추출할 수 있습니다. ID 리스트를 바로
가져오는 것은 가능하지 않지만, 통상 사용하는 우회적인 방법은, TextAsset 알려진 이름을 부여하여 에셋번들 내에 있는 에셋의
이름들을 담도록 하는 것 입니다.
에셋번들에서 오브젝트의 인스턴스화
에셋번들에서 오브젝트를 다운받고 나면, 사용자는 Instantiate을 사용하여 오브젝트를 사용자 장면(scene)로 인스턴스화 할 수
있습니다.
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
// Load the GameObject
GameObject go = bundle.Load("myGameObject", typeof(GameObject)) as GameObject;
// Instantiate the GameObject
Instantiate(go);
}
다운 받은 에셋번들 관리
사용자가 다운받은 에셋번들 리스트를 자동으로 받을 수 있는 방법은 제공되지 않습니다. 사용자는 스크립트로 에셋번들
오브젝트와 해당 URL 에 대한 조회정보를 저장하여 추적할 수 있습니다.
에셋번들에 바이너리 데이터 저장 및 로딩
첫 번째 단계는 사용자의 바이너리 파일을 ".bytes" 확장자로 저장하는 것 입니다. 유니티에서 이 파일은 TextAsset 취급됩니다.
사용자가 에셋번들을 구축할 때 해당 파일은 TextAsset 파일로 포함 됩니다. 사용자가 에셋번들을 사용자 어플리케이션에 다운로드
하고 나면 TextAsset 오브젝트를 가져오면, TextAsset의 .bytes 속성을 사용하여 바이너리 데이터를 추출 할 수 있습니다.
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
// Load the TextAsset object
TextAsset txt = bundle.Load("myBinaryAsText", typeof(TextAsset)) as TextAsset;
// Retrieve the binary data as an array of bytes
byte[] bytes = txt.bytes;
}
에셋번들에 스크립트 포함하기
에셋 번들은 TextAssets 타입으로 스크립트를 포함 할 수는 있으나 실제로 실행 가능한 코드가 되는 것은 아닙니다. 사용자가
에셋번들에 사용자 어플리케이션에서 실행 가능한 코드를 포함하고 싶다면, 어셈블리 코드로 미리 컴파일 하여 Mono Reflection
클래스 (주: Reflection 은 iOS 에는 없음)를 사용하여 로딩하여야 합니다. 어셈블리 코드는 보통 타입이 C# IDE (예를 들면
Monodevelop, Visual Studio) 혹은 해당 mono/.net 컴파일러를 사용하는 아무 텍스트 편집기로 만들 수 있습니다.
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
// Load the TextAsset object
TextAsset txt = bundle.Load("myBinaryAsText", typeof(TextAsset)) as TextAsset;
// Load the assembly and get a type (class) from it
var assembly = System.Reflection.Assembly.Load(txt.bytes);
var type = assembly.GetType("MyClassDerivedFromMonoBehaviour");
// Instantiate a GameObject and add a component with the loaded class
GameObject go = new GameObject();
go.AddComponent(type);
}
에셋의 의존관계 관리
번들 내의 에셋은 다른 에셋과 의존관계에 있을 수 있습니다. 예를 들어, 모델은 물질(material)을 포함하고 그것은 다시 텍스처와
그림자를 활용할 수 있습니다. 번들에는 이러한 에셋의 의존성을 에셋과 함께 포함할 수 있습니다. 하지만, 각자 다른 번들의 여러
에셋이 다른 에셋의 공통 세트에 의존할 수 도 있습니다.(예를 들면, 다른 번들에 있는 빌딩들의 여러 다른 모델들이 같은 텍스처를
가질 경우) 만일 오브젝트가 공유 의존하는 것을 각 번들마다 복사본을 만들어 보관한다면, 해당 번들이 로딩 될 때마다 불필요한
에셋이 생성되고, 그것은 메모리의 낭비를 초래할 것 입니다.
이러한 낭비를 피하고자, 공유 의존사항을 분리하여 독립된 하나의 번들에 넣고, 그것이 필요한 번들의 에셋에서 필요할 때 단순히
조회할 수도 있습니다. 첫째, 조회 속성은 BuildPipeline.PushAssetDependencies을 실행하여 사용가능 하도록 설정해 두어야 합니다.
그 후에 해당 조회 의존사항을 포함하는 번들을 구축하여야 합니다. 다음은, 첫째 번들의 에셋을 조회하는 번들을 구축하기 전에
PushAssetDependencies 을 다시 실행하여야 합니다. PushAssetDependencies 을 추가로 실행하면 추가적인 단계의 의존사항을
도입할 수 있습니다. 해당 조회 레벨은 스택에 저장되어 그에 상응하는 BuildPipeline.PopAssetDependencies을 사용하여 해당
레벨로 돌아갈 수 있습니다. 구축 전에 사용하는 초기 push를 포함하여 push 와 pop 실행을 통해 균형을 맞추어야 합니다.
시 시에는 사용자는 해당 의존사항을 조회하는 다른 번들보다 먼저 의존사항을 포함하는 번들을 로딩해야 합니다. 예를 들면,
공유하는 텍스처를 포함하는 번들을 먼저 로딩하고 그 다음 해당 텍스처를 조회하는 물질(material) 번들을 로딩하여야 합니다.
다른 게임에 사용자 에셋번들 재 사용이 가능한가요?
에셋번들을 사용하면 다른 게임간에 콘텐츠를 공유할 수 있습니다. 다만 사용자 에셋번들 안에 GameObject가 조회하는 에셋은 모두
에셋번들에 포함하거나 사용자 어플리케이션에 존재하여야 합니다 (현재 장면(scene)에 이미 로딩되어야 함). 조회한 에셋이
사용자가 구축하는 에셋번들에 반드시 포함되게 하려면 BuildAssetBundleOptions.CollectDependencies옵션을 전달하면 됩니다.
에셋번들의 에셋을 어떻게 확인하나요?
사용자가 에셋번들을 구축할 때, 해당 에셋은 내부적으로는 확장자 없이 이름으로 식별됩니다. 예를 들어 사용자 프로젝트 폴더에
있는 "Assets/Textures/myTexture.jpg"는 디폴트 매소드를 사용하면 "myTexture" 확장자로 식별하고 로딩합니다. 사용자는
에셋번들을 구축할 때 BuildPipeline.BuildAssetBundleExplicitAssetNames을 사용하여 사용자의 ID (문자열) 리스트를 제공함으로써
더 많은 권한을 가지고 원하는 대로 구축할 수 있습니다.
에셋으로부터 오브젝트 비동기 로딩하기
사용자는 AssetBundle.LoadAsync을 사용하여 오브젝트를 비동기적으로 로딩하여 사용자 어플리케이션에 고장 상황을 줄일 수
있습니다.
using UnityEngine;
IEnumerator Start () {
// Start a download of the given URL
WWW www = WWW.LoadFromCacheOrDownload (url, 1);
// Wait for download to complete
yield return www;
// Load and retrieve the AssetBundle
AssetBundle bundle = www.assetBundle;
// Load the object asynchronously
AssetBundleRequest request = bundle.LoadAsync ("myObject", typeof(GameObject));
// Wait for completion
yield return request;
// Get the reference to the loaded object
GameObject obj = request.asset as GameObject;
}
에셋 번들은 다른 플랫폼에 호환 가능합니까?
에셋번들은 일부 플랫폼 간에 호환이 가능합니다. 다음 테이블을 가이드라인으로 사용하세요.
에셋번들의 플랫폼 간 호환성
독립형 웹재생기 iOS Android
편집기
Y
Y
독립형
Y
Y
웹 재생기
Y
Y
iOS
Y
Y
Y
Android
Y
에셋번들을 어떻게 캐시에 저장합니까?
사용자는 WWW.LoadFromCacheOrDownload을 사용하여 사용자 에셋 번들을 디스크에 자동저장 할 수 있습니다. 하지만
웹재생기는 총 50MB(모든 웹 재생기간에 공유)으로 제한 되어 있다는 것을 명심하십시오. 만일 사용자가 추가 저장 공간이
필요하다면, 사용자 게임을 위한 별도 캐싱 라이선스를 구매할 수 있습니다.
콘텐츠 보호
유니티에서 AssetBundle.CreateFromMemory을 사용하면 byte[] 열에서 에셋번들 오브젝트를 생성할 수 있습니다. 사용자는 이것을
이용하면 전송 전에 해당 에셋번들을 암호화하고 실행 시에 복호하여 보안을 증가할 수 있습니다.
string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d";
IEnumerator Start () {
// Start a download of the encrypted assetbundle
WWW www = new WWW (url);
// Wait for download to complete
yield return www;
// Get the byte data
byte[] encryptedData = www.bytes;
// Decrypt the AssetBundle data
byte[] decryptedData = YourDecryptionMethod(encryptedData);
// Create an AssetBundle from the bytes array
AssetBundle bundle = AssetBundle.CreateFromMemory(decryptedData);
// You can now use your AssetBundle
}
Asset Data base
AssetDatabase 는 사용자 프로젝트에 있는 에셋에 접근할 수있게하는 API 입니다. 무엇보다 이것은 에셋을 찾고, 로드, 생성, 제거
그리고 수정할 수 있습니다. 유니티 에디터는 내부적으로 에셋 파일을 추적하고 에셋과 그것을 참조하는 객체의 연결을 관리하는데
AssetDatabase 를 사용합니다. 유니티는 프로젝트 폴더의 모든 변경을 알고 있어야 하기 때문에 사용자가 에셋데이타에 접근 또는
수정을 원할 때는 파일 시스템보다 항상 AssetDatabase API 를 이용해야 합니다.
AssetDatabase 인터페이스는 에디터에서만 사용가능하며 빌드된 플레이어 에서는 기능이 없습니다. 다른 모든 에디터 클래스처럼
이것은 �Editor� 폴더에 위치한 스크립트에게만 사용가능 합니다(만약 프로젝트의 메인 에셋 폴더에 에디터라는 라는 폴더가
존재하지 않으면 생성하십시오).
에셋 불러오기
유니티는 보통 프로젝트에 드래그되어오면 자동으로 불려 지는데 스크립트 제어를 통해서도 불러 올수 있습니다. 이렇게하기
위해서는AssetDatabase.ImportAsset 를 아래의 예제처럼 사용합니다
using UnityEngine;
using UnityEditor;
public class ImportAsset {
[MenuItem ("AssetDatabase/ImportExample")]
static void ImportExample ()
{
AssetDatabase.ImportAsset("Assets/Textures/texture.jpg", ImportAssetOptions.Default);
}
}
또한 추가로 AssetDatabase.ImportAssetOptions 타입의 인자를AssetDatabase.ImportAsset 함수에 넘겨줄 수 있습니다. 스크립팅
참조 페이지 에서는 다른 옵션들과 함수에서 그 옵션들의 영향을 알수 있습니다
에셋 로딩
The editor loads assets only as needed, say if they are added to the scene or edited from the Inspector panel. However, you can
load and access assets from a script
using AssetDatabase.LoadAssetAtPath, AssetDatabase.LoadMainAssetAtPath, AssetDatabase.LoadAllAssetRepresentationsAtPa
th and AssetDatabase.LoadAllAssetsAtPath. See the scripting documentation for further details.
에디터는 에셋을 필요할 때만 로딩을 하는데 예를들어 씬에 에셋이 추가되었거나 Inspector창에서 수정되었을 때입니다.
그러나AssetDatabase.LoadAssetAtPath, AssetDatabase.LoadMainAssetAtPath, AssetDatabase.LoadAllAssetRepresentationsAtP
ath 와 AssetDatabase.LoadAllAssetsAtPath. 자세한 사항은 스크립팅 문서를 보세요.
using UnityEngine;
using UnityEditor;
public class ImportAsset {
[MenuItem ("AssetDatabase/LoadAssetExample")]
static void ImportExample ()
{
Texture2D t = AssetDatabase.LoadAssetAtPath("Assets/Textures/texture.jpg", typeof(Texture2D)) as
Texture2D;
}
}
AssetDatabase 를 이용한 파일 작업
Since Unity keeps metadata about asset files, you should never create, move or delete them using the filesystem. Instead, you can
use AssetDatabase.Contains, AssetDatabase.CreateAsset, AssetDatabase.CreateFolder, AssetDatabase.RenameAsset, AssetDat
abase.CopyAsset, AssetDatabase.MoveAsset, AssetDatabase.MoveAssetToTrash and AssetDatabase.DeleteAsset.
유니티는 에셋 파일에 대한 메타 데이터를 가지고 있기 때문에 파일 시스템을 이용하여 그 파일들을 생성, 이동, 제거 하여서는
않됩니다.
대신 AssetDatabase.Contains, AssetDatabase.CreateAsset, AssetDatabase.CreateFolder, AssetDatabase.RenameAsset, AssetDa
tabase.CopyAsset, AssetDatabase.MoveAsset, AssetDatabase.MoveAssetToTrash 와AssetDatabase.DeleteAsset를 사용할 수
있습니다
public class AssetDatabaseIOExample {
[MenuItem ("AssetDatabase/FileOperationsExample")]
static void Example ()
{
string ret;
// Create
Material material = new Material (Shader.Find("Specular"));
AssetDatabase.CreateAsset(material, "Assets/MyMaterial.mat");
if(AssetDatabase.Contains(material))
Debug.Log("Material asset created");
// Rename
ret = AssetDatabase.RenameAsset("Assets/MyMaterial.mat", "MyMaterialNew");
if(ret == "")
Debug.Log("Material asset renamed to MyMaterialNew");
else
Debug.Log(ret);
// Create a Folder
ret = AssetDatabase.CreateFolder("Assets", "NewFolder");
if(AssetDatabase.GUIDToAssetPath(ret) != "")
Debug.Log("Folder asset created");
else
Debug.Log("Couldn't find the GUID for the path");
// Move
ret = AssetDatabase.MoveAsset(AssetDatabase.GetAssetPath(material),
"Assets/NewFolder/MyMaterialNew.mat");
if(ret == "")
Debug.Log("Material asset moved to NewFolder/MyMaterialNew.mat");
else
Debug.Log(ret);
// Copy
if(AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(material), "Assets/MyMaterialNew.mat"))
Debug.Log("Material asset copied as Assets/MyMaterialNew.mat");
else
Debug.Log("Couldn't copy the material");
// Manually refresh the Database to inform of a change
AssetDatabase.Refresh();
Material MaterialCopy = AssetDatabase.LoadAssetAtPath("Assets/MyMaterialNew.mat", typeof(Material))
as Material;
// Move to Trash
if(AssetDatabase.MoveAssetToTrash(AssetDatabase.GetAssetPath(MaterialCopy)))
Debug.Log("MaterialCopy asset moved to trash");
// Delete
if(AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(material)))
Debug.Log("Material asset deleted");
if(AssetDatabase.DeleteAsset("Assets/NewFolder"))
Debug.Log("NewFolder deleted");
// Refresh the AssetDatabase after all the changes
AssetDatabase.Refresh();
}
}
AssetDatabase.Refresh 사용하기
에셋 변경을 끝마쳤을 때는 AssetDatabase.Refresh 를 불러서 변경 사항을 데이터 베이스에 저장(commit)하고 그 사항들을
프로젝트에 적용시킬 수 있습니다.
렌더링 경로
유니티는 다른 Rendering Paths 를 지원합니다. 사용자는 게임 내용, 타겟으로하는 플랫폼/하드웨어에 따라 어떤 경로를 선택할지
결정해야 합니다. 서로 다른 렌더링 경로는 다른 기능을 가지고 있고 대부분 빛과 그림자에 영향을 주는 다른 성능을 가지고
있습니다.
프로젝트의 렌더링 경로는 Player Settings 에서 선택되어 집니다. 추가로 각 Camera 다 오보라이드 할수 있습니다.
만약 그래픽 카드가 선택된 렌더링 경로를 다루지 못한다면 유니티는 자동으로 충실도가 낮은 것을 사용할 것입니다. 그래서
Deferred Lighting 을 다룰수 없는 GPU 에서는 Forward Rendering 이 쓰여질 것입니다. Forward Rendering 이 지원되지 않는다면
Vertex Lit 이 쓰여질 것입니다.
지연 빛(Deferred Lighting)
Deferred Lighting 가장 높은 빛과 그림자 충실도를 가진 렌더링 경로 입니다. 실시간 빛이 많을때 사용하면 좋습니다. 이것은 어느
정도의 하드웨어 지원을 필요로하는데 이것은 유니티 프로만을 위한 것이며 Mobile Devices 는 지원되지 않습니다.
좀더 많은 정보를 위해선 Deferred Lighting page 를 보세요.
Forward 렌더링
Forward 는 쉐이더에 기반을 둔 렌더링 경로입니다. 이것은 픽셀 빛(보통 맵과 가벼운 쿠키를 포함해서)와 하나의 방향 빛에서
나오는 실시간 그림자를 지원합니다. 기본 설정에서 적은 수의 가장 밝은 빛은 픽셀 빛 모드로 렌더 됩니다. 나머지 빛은 객체
꼭지점으로 계산 됩니다.
좀더 자세한 사항은 Forward Rendering page 을 보세요.
Vertex Lit
Vertex Lit 은 가장 낮은 빛 충실도를 가지고 실시간 그림자를 지원하지 않는 렌더링 경로 입니다. 이것은 오래된 컴퓨터나 제한 적인
모바일 플랫폼에 적합합니다.
좀더 자세한 사항은 Vertex Lit page 을 보세요.
렌더링 경로 비교
Deferred Lighting
Forward Rendering
Vertex Lit
Yes
Yes
-
Yes
1 Directional Light
-
Features
Per-pixel lighting (normal maps, light
cookies)
Realtime shadows
Dual Lightmaps
Yes
-
-
Depth&Normals Buffers
Yes
Additional render passes
-
Soft Particles
Yes
-
-
Semitransparent objects
-
Yes
Yes
Anti-Aliasing
-
Yes
Yes
Limited
Yes
Yes
All per-pixel
Some per-pixel
All per-vertex
Number of pixels it
Number of pixels * Number of objects it
illuminates
illuminates
Shader Model 3.0+
Shader Model 2.0+
-
OpenGL ES 2.0
360, PS3
360, PS3
Light Culling Masks
Lighting Fidelity
Performance
Cost of a per-pixel Light
-
Platform Support
PC (Windows/Mac)
Mobile (iOS/Android)
Consoles
Anything
OpenGL ES 2.0 &
1.1
프로파일러(프로용) (Profiler (Pro only))
유니티 프로파일러는 게임을 최적화 할 수 있도록 돕습니다. 게임의 다양한 영역에서 얼마나 많은 시간이 소모되었는지 알립니다.
예를 들어, 렌더링, 애니메이션, 게임로직에서 소모된 시간의 각 비율을 나타냅니다.
에디터에서 프로파일링을 켜고 게임을 할 수 있고, 이는 성능 데이터를 기록 할 것입니다. 프로파일러 창은 타임라인에 데이터를
표시하여서, 프레임들이나 영역에서 다른곳들에 비해서 더 뾰족하게 솟아오른 지점(더 많은 시간이 걸림)을 찾을 수 있습니다.
타임라인 주변을 클릭하면, 프로파일러 창의 바닥 부분에서 선택한 프레임의 세부 정보를 표시할 수 있습니다.
프로파일링은 코드를 instrument 해야 합니다. 인스트루먼트 하는 것은 게임의 성능에는 아주 작은 영향을 줍니다. 이 오버헤드는
게임의 프레임레이트(framerate)에 영향을 주지 않을 정도로 작습니다. 프로파일링을 사용할 때는, 특정 지역들에서 소모된 시간의
퍼센트 비율을 주료 고려합니다. 그리고, 성능 향상을 위해서 대부분의 시간을 소모하는 게임의 특정 부분에 집중합니다. 프로파일링
결과를 코드 변화 전과 후에 비교해서, 측정된 향상 등을 정합니다. 때로는, 성능 향상을 위해서 만든 변화들이 프레임 비율에
0 오히려 부정적인 영향을 보일 수 있습니다. 코드 최적화의 예상치 못한 결과들도 예견되어야 합니다.
프로파일러 창
유니티 플레이어들 부착
다른 디바이스에서 실행되는 게임 또는 다른 컴퓨터에서 실행중인 플레이어를 프로파일 하기 위해서는, 에디터를 해당 플레이어에
연결할 수 있습니다. 드롭다운 Active Profiler 메뉴는 지역 네트워크에서 실행중인 플레이어를 보입니다. 이들 플레이어들은
플레이어 종류와 "iPhonePlayer (Toms iPhone)" 플레이어를 실행중인 호스트(host) 이름으로 확인됩니다.플레이어에 접속할 수
있도록 하기 위해서는, 플레이어는 Build Settings 대화 창에 발견되는 Development Build 체크박스와 실행시켜야 합니다. 여기서,
에디터와 플레이어를 시작 시 자동연결(Autoconnect)하도록 만들기 위해, 체크박스를 표시한 것이 가능합니다.
Profiler Controls
프로파일러 컨트롤들은 창의 위쪽에 툴바에 있습니다. 이를 사용하여, 프로파일링을 켜거나 끄시고, 프로파일된 프레임등 들을
통하여 네비게이션(navigation)을 하시면 됩니다. 전송(transport) 컨트롤들은 툴바의 오른쪽 맨 끝에 있습니다. 게임이 실행되고,
프로파일러가 데이터를 모을 때, 이 전송 컨트롤 중 하나라도 클릭하면, 게임을 멈추게 됩니다. 컨트롤들은 처음의 저장된
프레임으로 가서, 한 프레임을 뒤로 물러나게 하고, 한 프레임을 앞으로 움직이게 하며, 마지막 프레임으로 이동합니다.
프로파일러는 모든 저장된 프레임들을 보유 하지 않습니다. 그래서 first 프레임의 개념은 메모리에 여전히 보유된 가장 오래된
프레임으로 생각될 수 있습니다. "current" 전송버튼은 프로파일 통계 창이 실시간으로 모은 데이터를 표시하게 합니다.
Deep Profiling
Deep Profile 을 켜게 되면, all 스크립트 코드가 프로파일 됩니다. 즉 모든 함수호출이 저장됩니다. 이는 게임코드에서 정확하게
어디서 시간이 소모되었는지 아는데 유용합니다.
딥 프로파일링은 매우 큰 오버헤드 를 야기하고, 많은 메모리를 사용하여, 게임이 프로파일 중 매우 늦게 실행됩니다. 만약, 복잡한
스크립트 코드를 사용하면, 딥 프로파일링은 전혀 가능하지 않을 수 있습니다. 딥 프로파일링은 간단한 스크립팅의 작은 게임을
위해서는 충분히 빨리 작동합니다. 만약 전체 게임을 위한 딥 프로파일링이 프레임 비율의 감소를 야기하여 게임이 간신히 실행되면,
이 접근법을 사용하지 않는 것을 고려하고, 아래의 접근법을 생각해봐야 합니다. 게임을 디자인하고 주요 기능들을 가장 잘 구현하는
방법을 선택할 때, 딥 프로파일링이 더 유용할 수 있습니다. 큰 게임들에겐, 딥 프로파일링이 유니티로 하여금 메모리를 소진하게
하므로, 이런 이유로, 딥 프로파일링이 가능하지 않을 수 있습니다.
스크립트 코드 블록들의 수동 프로파일링은 딥 프로파일링 보다 더 작은 오버헤드를 나타낼 것입니다. 코드 섹션들 주위의
프로파일링을 가능하게 하거나 불가능하게 하기 위해서 Profiler.BeginSample나 Profiler.EndSample 스크립트 함수 등을
사용하십시오.
싱크 타임 보기(View SyncTime)
고정된 프레임 비율이나 수직 공백(vertical blank)과 싱크(sync)를 맞춰 실행할 때, 유니티는 "Wait For Target FPS"에서의 대기
시간(waiting time)을 기록합니다. 디폴트로 이 시간은 프로파일러에는 보여지지 않습니다. 얼마나 많은 대기 시간이 소모되었는지
보기 위해서는, "View SyncTime"를 토글(toggle) 할 수 있습니다. 프레임들을 이완(loose)시키기 전에 얼마나 많은
헤드룸(headroom)을 가지고 있는지의 측정이기도 합니.
Profiler Timeline
프로파일러 창의 윗부분은 시간에 따른 성능데이터를 표시합니다. 게임을 실행할때, 데이터는 프레임 별로 저장되고, 지난 몇 백
프레임들의 히스토리(history)가 표시됩니다. 특정 프레임을 클릭하면, 창의 아래 부분에 세부사항들이 표시됩니다. 어떤 타임라인
지역이 현재 선택되었는지에 따라 다른 세부사항들이 표시됩니다. 타임라인의 수직 스케일은 자동으로 관리되고, 창의 수직
스페이스를 채우려고 할 것입니다. CPU 사용 영역 등의 세부사항을 얻으려면, 메모리와 렌더링 지역들을 제거할 수 있습니다.
그리고, 타임라인과 통계 영역 사이의 분할자(splitter)는 타임라인 차트로 사용되는 스크린 영역을 증가시키기 위해서, 선택되고,
아래로 드래그 될 수 있습니다.
타임라인은 몇몇 영역으로 구성됩니다: CPU 사용(CPU Usage), 렌더링(Rendering) 그리고 메모리(Memory) 영역입니다. 이들
영역은 패널(panel)에서 “close” 버튼을 클릭해 제거 되며, 프로파일 컨트롤 바의 Add Area 드롭 다운으로 재 추가 될 수 있습니다.
CPU 사용 영역
CPU 사용 영역은 게임에서 경과된 시간을 표시합니다. 선택되면, 아래쪽 페인(pane)에서 선택된 프레임의 계층 시간 데이터를
표시합니다.
•
계층 구조 모드 (Hierarchy mode): 계층 구조의 시간 데이터를 표시합니다.
•
그룹 계층 구조 모드 (Group Hierarchy mode): 시간 데이터를 논리적 그룹(렌더링, 물리, 스크립트들 등)으로 나눕니다. 어떠한
그룹의 자식들은 다른 그룹에 있을 수 있으므로(예: 몇몇 스크립트는 렌더링 함수를 호출 가능), 그룹들의 시간 비율은 종종 합계가
100%를 넘어 갑니다. (이는 소프트웨어 오류/버그 가 아닙니다.)
CPU 차트가 쌓이는 식은 단순히 차트 라벨을 위 아래로 드래그 해서 재 배치가 가능합니다.
아이템이 아래쪽 페인(pane)에서 선택되면, CPU 차트에서의 기여도는 하이라이트 처리됩니다 (나머지는 희미하게 처리). 아이템을
다시 클릭하고, 선택을 해제하십시오.
Shader.SetPass 는 선택되었고, 기여도는 차트에서 하이라이트 처리되었습니다
계층 구조 시간 데이터에는 셀프 타임(self time)은 특정함수에서의 소모된 시간을 의미하며, 서브함수들을 부르는 시간은 포함 하지
않습니다. 위의 스크린샷에서, 51.2%의 시간이 Camera.Render 함수에서 소모되었습니다. 이 함수는 많은 일을 하고, 다양한
드로잉과 컬링(culling) 함수들을 호출 하였습니다. 이들 함수를 제외하면, 0.8%의 시간이 Camera.Render 함수에서 실제로
소모되어졌습니다.
렌더링 영역(Rendering Area)
렌더링 영역은 렌더링 통계를 표시합니다. 그리기 호출과 삼각형들, 그리고 렌더된 꼭지점들의 개수들이 타임라인에서 그래픽으로
처리되어 표시됩니다. 아래쪽 패인(pane)은 더 많은 렌더링 통계를 표시하고, 이들은 게임보기의 Rendering Statistics 창에서 보여진
것들과 가깝게 매치(match)됩니다.
메모리 영역(Memory Area)
메모리 영역은 몇몇 메모리 사용 데이터를 표시합니다:
•
Total Allocated 전체 할당량(Total Allocated)은 어플리케이션에 의해 사용된 전체 RAM 양입니다. 유니티 에디터에서는 이는
에디터에서의 모든 것들에 의해 사용되는 메모리라는 점에 유의하십시오.
•
Texture Memory 질감 메모리는 현재 프레임에서의 질감들에 의해 사용되는 비디오 메모리들의 양입니다.
•
Object Count 오브젝트 카운트는 생성된 오브젝트들의 총 개수 입니다. 이 수가 시간에 따라 증가되면, 이는 게임 내에서 파괴되지
않는 몇몇 오브젝트들이 생성됨을 의미합니다.
오디오 영역(Audio Area)
오디오 영역은 오디오 통계를 표시합니다:
•
Playing Sources 은 특정 프레임 내 장면에서의 총 재생 소스입니다. 오디어가 과부하(overload)가 걸리면, 이를 주시하십시오.
•
Paused Sources 은 특정 프레임 내 장면에서 총 멈춘 소스들입니다.
•
Audio Voice 는 실제 사용된 오디오 (FMOD channels) 보이스 들의 개수입니다. “PlayOneShot”는 소스 재생들에서 보여지지 않은
보이스들을 사용합니다.
•
Audio Memory 는 오디오 엔진에 의해 사용되는 총 RAM 양입니다.
CPU 사용은 아래 부분에서 살펴보실 수 있습니다. 오디오만으로도 너무 많은 CPU 를 차지 한다면 이를 주시하시길 바랍니다.
아래 참조
•
Optimizing Graphics Performance 페이지.
iOS
리모트 프로파일링(Remote profiling)은 다음의 스텝들에 의해서 iOS 에 가능화 됩니다:
1.
iOS 디바이스를 WiFi 네트워크에 연결하십시오. (로컬/임시(adhoc) WiFi 네트워크는 디바이스로부터의 프로파일링
데이터를 유니티 에디터로 보내기 위해서 프로파일에 의해 사용됩니다.)
2.
유니티의 빌드 설정(build setting) 대화창의 "Autoconnect Profiler" 체크박스를 표시하십시오.
3.
디바이스를 맥에 케이블로 부착하여 유니티 에디터의 "Build & Run"를 클릭하세요.
4.
어플리케이션이 디바이스에서 실행할 때, 유니티 에디터의 프로파일러 창을 여십시오.(Window->Profiler)
_주의:__ 가끔 유니티 에디터는 디바이스로 자동 커넥트(autoconnect) 못할 수도 있습니다. 그런 경우는, 해당 디바이스를 선택하고
프로파일러 창에서 Active Profiler 드롭 다운 메뉴로부터 프로파일러 접속이 시작될 수 있습니다.
Lightmapping Quickstart
이것은 Unity 에서 lightmapping 의 도입적인 설명입니다. 더 자세한 주제를 위해서는 in-depth description of lightmapping in Unity 를
살펴보시기 바랍니다.
Unity는 내장lightmapper를 가집니다: 그것은Illuminate Labs에 의한 Beast 입니다. Lightmapping은 Unity안에서 완전히 통합됩니다.
이것은 계정 메쉬, 재질, 텍스쳐 그리고 조명을 고려해서 Beast가 사용자의 씬이 Unity 안에서 어떻게 셋업되는지에 기반해서
사용자의 씬을 위해lightmaps을 만든다는 것을 의미합니다. 그것은 또한lightmapping이 렌더링 엔진의 완전한 부분이라는 것을
의미합니다 – 사용자의lightmaps이 일단 생성되면 사용자가 어떤 것을 할 필요가 없고 그들은 오브젝트에 의해 자동적으로 선택될
것입니다.
Preparing the scene and baking the lightmaps
메뉴로 부터 Window – Lightmapping 을 선택하는 것은 Lightmapping window 를 열 것입니다:
1.
사용자가 lightmap 되어지기를 원하는 모든 메쉬는 lightmapping 를 위해서 적절한 UVs 를 가져야 한다는 것을 확실시
합니다. 가장 쉬운 방법은 mesh import settings 에서 Generate Lightmap UVs 옵션을 선택하는 것입니다.
2.
Object 에서 Mesh Renderer 또는 Terrain 을 static 으로 마크합니다 – 이것은 Unity 에게 그러한 오브젝트들이 움직이거나
변하지 않을 것이라고 말할 것이고 그들은 lightmap 되어질 수 있습니다.
3.
Lightmaps 의 화상도를 컨트롤하기 위해서 Bake 으로 가서 Resolution 값을 조정합니다. (사용자가 사용자의 lightmap
texels 을 어떻게 사용하는지에 대한 더 좋은 이해을 가지기 위해 Scene View 내에서 Lightmap Display 윈도우를 보고
Show Resolution 를 선택합니다).
4.
Bake 를 누릅니다.
5.
오른쪽 아래 코너에서 Unity 편집기의 상태 바에서 진행바가 나타납니다.
6.
베이킹이 끝날 때 사용자는 Lightmap 편집 윈도우의 아래에서 bake 된 모든 lightmaps 을 볼 수 있습니다.
씬과 게임 뷰는 업데이트할 것입니다 – 사용자의 씬은 lightmap 되어집니다!
Tweaking Bake Settings
사용자 씬의 마지막 모습은 사용자의 조명 셋업과 bake 세팅에 많이 의존합니다. 조명 퀄리티를 향상할 수 있는 몇몇 기본 세팅의
예제를 봅니다.
두어개의 직육면체와 가운데에 하나의 정점 조명이 있는 함께 있는 하나의 씬입니다. 조명은 단단한 그림자를 캐스트하고 효과를 꽤
지루하고 인공적입니다.
조명을 선택하고 Lightmapping 윈도우의 Object 를 오픈하는 것은 Shadow Radius 과 Shadow Samples 속성을 보여줍니다. 그림자
반지름을 1.2 로 그림자 샘플을 100 으로 세팅하는 것 그리고 다시 베이킹하는 것은 넓은 penumbra 와 함께 부드러운 그림자를
생산합니다 – 우리의 이미지는 벌써 훨씬 좋아 보입니다.
Unity Pro 와 함께 우리는 글로벌 Illumination 을 활성화하고 Sky Light 을 추가하는 것에 의해 한 스텝 더 나아가서 씬을 취할 수
있습니다. Bake pane 에서 우리는 Bounces 의 숫자를 1 로 세팅하고 Sky Light Intensity 를 0.5 로 세팅합니다. 결과는 미묘한
확산 반사적인 효과(녹색과 파랑색 직육면체로 부터 색상 출혈)와 함께 더욱더 부드러운 조명 입니다 – 훨씬 더 훌륭하고 그것은
여전히 3 개의 직육면체와 하나의 조명입니다!
Lightmapping In-Depth
Lightmapping 과 관련 세팅에 대한 더 많은 정보를 위해 in-depth description of lightmapping in Unity 를 참고해 보시기 바랍니다.
Lightmapping In-Depth
유니티에서 첫 번째 장면을 라이트맵 하려면 Quickstart Guide 를 참조 하십시오.
라이트매핑은 유니티에 완전히 통합되어 있습니다. 그러므로, 에디터 안에서 전체의 레벨을 빌드하고, 모든 재료들이 라이트맵 들을
자동으로 고르게 하여 걱정할 필요가 없습니다. 유니티에서 라이트매핑은 모든 빛들의 속성들이 직접 비스트(Beast) 라이트매퍼로
매핑이 됨을 의미하며, 좋은 성능으로 베이크(bake) 됨을 의미합니다. 유니티 프로(Unity Pro)는 이 기능을 글로벌 조명(Global
Illumination)까지 확장하여, (이 기능을 쓰지 않으면 실시간으로는 불가능한) 현실적이고 아름다운 라이팅으로 베이크 되도록 합니다.
추가로, 유니티 프로는 더욱 흥미있는 장면 라이팅을 위해서 하늘의 빛들과 빛을 방출하는 물질들을 가지고 옵니다.
이 페이지는 라이트매핑 창에서 구할 수 있는 모든 속성들의 심도 있는 기술을 찾게 될 것입니다. 라이트매핑 창을 열려면 Window –
Lightmapping 를 선택하세요.
Object
현재의 선택에 기반하여, 오브젝트당 빛, 메쉬 렌더러, 지형을 위한 베이크 세팅들.
메쉬 렌더러들과 지형들:
Property:
Function:
메쉬 렌더러 들과 지형들이 “정적(static)”으로 라이트맵 되도록 표시.
Static
메쉬 렌더러들을 위한 사항) 메쉬 렌더러에게 귀속되는 더 큰 값은 더 높은 해상도를 야기 할 것입니다. 마지막
Scale In
해상도는 비율적일 것입니다 (라이트 맵에서의 스케일)*(Object's word-space 표면지역)*( 글로벌 베이크 설정 해상도
Lightmap
값). 0 의 값은 오브젝트가 라이트맵 되지 않음을 야기 할 것입니다(그러나 다른 라이트맵 된 오브젝트들에게는
영향을 줄 것입니다).
Lightmap
(지형만 해당) 지형 인스턴스를 위한 라이트맵 크기. 지형들은 다른 오브젝트들처럼 아틀라스(atlas) 되지 않습니다 –
Size
그들은 개개의 라이트맵 들을 얻습니다.
Lock Atlas 가 “disable”이면, 아틀라싱 정보(Atlasing information)는 자동으로 업데이트 될 것입니다. Lock Atlas 가
Atlas
Lightmap
Index
“enable”이면, 변수들이 자동으로 수정되지 않을 것이며, 수동으로 편집이 가능할 것입니다.
라이트맵 배열에서의 인덱스.
Tiling
(메쉬 렌더러들만 해당) 오브젝트의 라이트맵 UV 들의 타일링.
Offset
(메쉬 렌더러들만 해당) 오브젝트의 라이트맵 UV 들의 오프셋.
Lights:
Property:
Lightmapping
Function:
라이트매핑 모드: 실시간만 해당, 자동 또는 baked. 아래의 이중 라이트맵들 Dual Lightmaps 기술 참조하십시오.
Color
빛의 색상. 실시간 렌더링을 위해 사용되는 것과 같은 속성.
Intensity
빛의 광도. 실시간 렌더링을 위해 사용되는 것과 같은 속성.
Bounce
특정 광원으로부터 나오는 간접 빛의 광도 승수(multiplier).
Intensity
이 라이트에 의해 비춰진 오브젝트들의 드리워진 그림자를 컨트롤(“Auto” 라이트인 경우 실시간 그림자들 동시에
Baked Shadows
콘트롤).
(점과 스포트 라이트만 해당) 소프트 직접 그림자들(soft direct shadows)을 위해 이 값 증가 – 그림자들(빛이 아닌)
Shadow Radius
연산을 위한 라이트의 크기를 증가.
(방향성 라이트 들만 해당) 소프트 직접 그림자들을 위해 이 값 증가 – 그림자들(빛이 아닌) 연산을 위한 라이트의
Shadow Angle
각진 범위를 증가.
그림자 반경이나 각도를 0 이상으로 설정하였으면, 그림자 샘플들의 개수 또한 증가 시킵니다. 더 높은 샘플 수들은
Shadow
반그림자(shadow penumbra) 로부터의 노이즈를 삭제 할 것입니다. 그러나 이는 렌더링 타임의 증가를 야기 시킬
Samples
수 있습니다.
Bake
글로벌 베이크 설정들.
Property:
Function:
오프라인 라이트맵 베이킹(baking)과 실행 시 라이트맵의 렌더링 모드를 설정합니다. 이중 라이트맵 모드인 경우,
가까운 라이트맵과 먼 라이트 맵이 베이크 됩니다. 오직 늦춰진(deferred) 렌더링 경로만이 렌더링 듀얼
Mode
라이트맵을 지원합니다. 싱글 라이트맵 모드는 먼 라이트 맵이 베이크 되는 것을 야기 합니다. Deferred 랜더링
경로를 위해서 싱글 라이트맵 모드의 사용을 강제하기 위해 사용될 수 있습니다.
높은 퀄리티(좋은 외관)와 낮은(빠른) 퀄리티의 베이크를 미리 조정합니다. 그들은 파이널 개더(final gather)의
Quality
광선들의 개수 및 명암 스레쉬홀드(contrast threshold), 그리고 몇몇 다른 파이널 개더와 anti-aliasing 설정에
영향을 줍니다.
Global Illumination 시뮬레이션에서의 라이트 바운스들의 개수입니다. 부드럽고 현실적인 간접 라이팅을
Bounces
제공하기 위해서는 최소한 하나의 바운스는 필요합니다. 0 은 오직 직접 라이트(direct light)만이 계산 될 것임을
의미합니다.
Sky Light
스카이라이트(Sky light)는 모든 방향에서의 하늘에서 나오는 빛을 시뮬레이션 합니다. 바깥 장면을 위해서
좋습니다.
Color
Sky Light
스카이라이트의 광도(intensity) - 0 값은 스카이라이트를 불가능(disable)으로 만듭니다.
Intensity
간접 라이팅을 부스트(Boost) 시킵니다. 렌더를 빨리 버닝아웃(burning out)시키지 않고, 장면 내에서 바운스된
Bounce Boost
라이트의 양을 증가시키기 위해 사용합니다.
Bounce
간접 라이트의 광도의 승수(multiplier).
Intensity
Final Gather
모든 파이널 개더점 들로부터 쏘여진 광선들의 개수-더 높은 값이 더 좋은 값을 줍니다.
Rays
색상 명암 스레쉬홀드(Color contrast threshold). 스레쉬홀드 위로는 새로운 파이널 개더 점들이
적응성의(adaptive) 샘플링 알고리즘에 의해 생성될 것입니다. 더 높은 값들은 비스트를 표면에서의 조명변화에
Contrast
Threshold
더 견딜 수 있게 만듭니다. 그러므로, 더 부드럽지만, 덜 자세한 라이트맵 들을 생성합니다. 더 낮은 개수의 파이널
개더 광선들은 추가의 파이널 개더점들의 생성을 강요하지 않게 하기 위해 더 높은 명암 스레쉬홀드 값들이
필요할지 모릅니다.
파이널 개더점들의 보간 될 색상을 컨트롤 합니다. 0 은 선형 보간(linear interpolation) 이고, 1 은 고급 그레디언트
Interpolation
Interpolation
기반의 보간입니다. 몇몇 경우, 후자는 artifact 가 나타날 수 있습니다.
보간 될 파이널 개더점들의 개수입니다. 더 높은 값들은 더 부드러운 결과를 낳습니다. 그러나 라이팅의 세부를
부드럽게 처리해버릴 수도 있습니다.
Points
Ambient
Occlusion
Max Distance
라이트맵으로 베이크될 잔잔한 폐색 (ambient occlusion)의 양입니다. Ambient occlusion 은 Max Distance 크기의
로컬 반구 위에 통합된 가시함수(visibility function)입니다. 그러므로, 라이팅 정보를 고려 하지 않습니다.
이 거리를 넘어가면, 광선은 폐색(unocclude)되지 않습니다. 0 는 무한대로 긴 광선을 의미합니다.
완전 폐색에서 폐색되지 않음 사이의 전이를 컨트롤합니다.
Contrast
“아틀라스 잠금(Lock Atlas)”가 사용 가능이면, 자동 지도기능은 작동하지 않으며, 라이트맵 인덱스, 오브젝트들의
Lock Atlas
타일링과 오프셋은 변하지 않을 것입니다.
월드 유닛당 라이트맵의 해상도(texel 단위). 50 의 값과 10 유닛 X 10 유닛 평면은 라이트맵에서 500x500 픽셀을
Resolution
Maps
차지하는 평면을 나오게 할 것입니다.
모든 라이트맵 들의 편집가능배열.
Property:
Function:
Compressed
장면을 위해 모든 라이트맵 asset 을 토글(Toggle) 압축합니다.
Array Size
라이트맵 배열의 사이즈 (0 - 254).
현재 장면의 모든 라이트맵 들의 편집 가능한 배열. 비 할당 슬롯들은 검정 라이트맵들로 간주됩니다. 메쉬
Lightmaps
Array
렌더러들과 지형(Terrain)들에서의 라이트맵 인덱스값에 상응하는 색인들(Indices). “Lock Atlas” 가 가능으로
설정되어 있지 않으면, 이 배열은 자동으로 조절 될 것이며 라이트맵을 베이크할 때마다 populate 될 것입니다.
라이트맵 표시
라이트맵들이 어떤식으로 에디터에서 표시될지를 컨트롤하는 유틸리티들입니다. 라이트맵 디스플레이는 장면 보기의 서브창이며,
라이트매핑 창이 보이는 곳에서 보입니다.
Property:
Function:
Use
렌더링 시 또는 렌더링 하지 않는 동안 라이트맵 들을 사용할지 설정합니다.
Lightmaps
자동 라이트(Auto light)와 희미해진 멀리 있는 라이트 맵들 Close 사이의 거리. 이
Shadow
설정은 QualitySettings.shadowDistance 를 해당 설정으로 적용시키지만 덮어쓰지는 않습니다.
Distance
Show
장면 보기 라이트맵 해상도를 토글합니다. 이는 정적으로 표시된 오브젝트들의 라이트맵 텍셀들을 어떤식으로
Resolution
소모되었는지 미리 보기 할 수 있습니다.
세부 사항들
이중 라이트 맵들
이중 라이트맵 들은 라이트매핑이 반사(specular), 직각 매핑(normal mapping) 에서 작용하도록 하고 베이크와 실시간 그림자의
적절한 혼합을 작동하게 하는 유니티의 접근법입니다. 또, 라이트맵의 해상도가 낮아도, 라이트맵이 좋게 보이도록 하는 방법입니다.
이중 라이트 맵들은 기본적으로 늦춰진 라이팅 렌더링 경로 (Deferred Lighting rendering path)에 사용될 수 있습니다. 전면 렌더링
경로에는, 사용자 쉐이더를 작성해서 이중 라이트맵들을 가능하게 할 수 있습니다. (dualforward 표면 쉐이더 지시어).
이중 라이트맵들은 두 개의 라이트맵들 집합을 사용합니다:
•
Far: 전체 조명을 포함합니다
•
Near: Auto 로 표시된 라이트들로 부터의 간접 조명을 포함합니다. Bake Only 로 표시된 라이트들로 부터의 완전 조명(full
illumination)을 포함합니다. 발광성 물질과 스카이 라이트들을 포함합니다.
Realtime Only 라이트들은 베이크되지 않습니다. Near lightmap 설정이 그림자 거리의 퀄리티 설정 보다 더 작은 카메라 거리
안에서 사용됩니다.
이 거리 안에서는 Auto 라이트들이 반사 범프(bump)와 실시간 그림자들을 가진 빛들(이는 그림자들이 실시간에만 해당 하는
빛들로부터의 그림자들로 정확하게 섞이게 만듭니다)로 렌더되고, 간접 라이트는 라이트맵 으로부터 취합니다. 그림자 거리의
바깥쪽은 Auto 라이트들은 더 이상 실시간으로 렌더하지 않고, 완전 조명은 Far 라이트맵으로부터 취합니다(Realtime Only
라이트만 해당. 라이트들은 disabled 그림자들과 여전히 그곳에 있음.
아래의 장면은 라이트매핑 모드가 기본인 “Auto”로 설정된 하나의 방향성 빛을 포함합니다. 그리고, 정적 라이트맵된 몇몇
오브젝트들(빌딩, 장애물, 움직이지 않는 세부요소들)과 몇 동적 움직이는 움직일 수 있는 오브젝트들(총들을 가진 모조품, 베럴들)을
포함합니다. 그 장면은 베이크 처리되었고, 이중 라이트맵 모드를 렌더합니다: 그림자 거리 뒤에는 빌딩들은 라이트맵들에 의해서만
빛이 비춰집니다. 반면에, 두 모조품들은 동적으로 비춰지며, 그림자를 뿌리지는 않습니다. 그림자 거리 앞에는, 모조품과 정적으로
라이트맵 처리된 빌딩이 있습니다. 땅은 실시간으로 비춰지며, 그림자도 실시간으로 뿌려집니다. 그러나, 소프트 간접 라이트는
라이트맵 주위로부터 나옵니다.
Single Lightmaps
싱글 라이트맵들은 훨씬 더 간단한 기술이지만, 어떤 rendering path 에도 사용할 수 있습니다. 모든 정적 정보 (즉, 베이크해당, 자동
라이트, 스카이라이트, 발광성물질들)는 라이트맵들의 하나의 셋으로 베이크 처리됩니다. 이러한 라이트맵 들은 그림자 거리에
관계없이 모든 라이트맵 처리된 오브젝트들에게 사용됩니다.
동적 그림자의 강도를 베이크된 그림자에 매치(match)시키려면, 라이트의 Shadow Strength 속성을 수동으로 조정할 필요가
있습니다.
원래값인 1.0 으로부터 라이트의 그림자 강도를 0.7 로 조정.
라이트맵 처리된 재료들(Lightmapped Materials)
유니티는 라이트맵을 사용하기 위해서 특별한 재료를 선택하는 것을 요구하지 않습니다. 내부 탑재 쉐이더들(그리고 작성하는 표면
쉐이더(Surface Shader))로부터 어떤 쉐이더도 박스 바깥쪽의 라이트맵을 지원합니다. (특별히 신경을 쓰지 않아도 작동하게
됩니다.)
라이트맵 해상도(Lightmap Resolution)
Resolution 베이크 설정을 사용하여, 유닛당 얼마나 많은 texel 이 화면을 좋게 보이는데 필요한지 컨트롤합니다. 화면에 1x1 유닛
평면이 있고, 해상도는 유닛당 10 texel 들로 설정된다면, 평면은 라이트맵에서 10x10 texels 을 차지합니다. 해상도 베이크 설정은
글로벌 설정입니다. 이를 특별한 오브젝트를 위해서 변경하면(라이트맵에서 아주 작게 또는 아주 크게), 메쉬 렌더러의 Scale in
Lightmap 속성을 사용할 수 있습니다. 라이트맵에서 “Scale”을 0 으로 설정하면, 오브젝트는 라이트맵 처리 되지 않습니다. (다른
오브젝트들에게는 여전히 라이트맵의 영향을 끼칩니다.) 라이트맵 텍셀이 어떤식으로 처리되는지 미리 보기 하시려면 라이트맵
해상도 장면 보기 렌더 모드를 사용하십시오.
라이트맵 텍셀이 어떤식으로 처리되는지 보기위한 라이트맵 해상도 장면 보기 모드(각 정사각형은 하나의 텍셀입니다.)
UVs
라이트맵 처리하려는 메쉬는 라이트매핑에 적합한 UVs 를 가지는 것을 필요로 합니다. 이를 위한 가장 쉬운 방법은 주어진 메쉬의
“Mesh Import Setting” 에 있는 “Generate Lightmap UVs option”을 “enable”로 만드는 것입니다.
더 많은 정보를 위해서는 Lightmap UVs 페이지를 참조하세요.
재료 속성들
아래의 재료 속성들은 비스트의 내부 장면 표현에 매핑됩니다:
•
색상(Color)
•
메인 질감(Main Texture)
•
반사색상(Specular Color)
•
빛남(Shininess)
•
투명도(Transparency)
o
Alpha-based: 투명 쉐이더를 사용할때, 메인 질감의 알파 채널은 투명도를 컨트롤 할 것입니다.
o
Color-based: 비스트의 RGB 투명도는 질감 속성_TransparencyLM 을 쉐이더에 추가하여 가능하게 할 것입니다. 이 투명도는 알파
기반의 투명도와 비교해서는 반대로 정의되어 있음을 명심해야 합니다: (1, 0, 0)을 가지는 픽셀은 빨강 라이트 컴포넌트에는 완전히
투명할 것이며, 초록과 파랑 컴포넌트에는 불투명할 것입니다. 이는 빨강 그림자를 야기 합니다. 같은 이유로, 하얀 질감은 완전히
투명할 것이며, 반면 검정 질감은 완전 불투명 할 것입니다.
•
발광(Emission)
o
자체 조명 재료들은 색상과 메인 질감, 그리고 Illum 질감에 매스크된 색조를 띈 빛을 내게 됩니다. 발광된 빛의 광도는 발광속성에
비례합니다 (0 은 발광이 불가능합니다).
o
일반적으로, 크고 흐린 광원들은 발광재료와의 오브젝트들로 모델링 됩니다. 작고, 광도가 센 빛들은 노멀(normal_ 라이트 타입이
사용되어야 합니다. 이는 발광 물질이 렌더링 하는 동안 노이즈(noise) 현상이 일어날 수 있어서 입니다.
주의: 재료들을 비스트로 매핑시에는, 유니티는 쉐이더의 속성들과 패스/이름 키워드들(Spectacular, Transparent, Self-Illumin, 등)에
의해서 쉐이더의 종류를 감지합니다.
고급
Automatic Atlasing
아틀라싱(Atlasing) (UV-패키징)은 베이크를 수행할 때마다 자동으로 수행됩니다. 그리고, 특별히 신경 쓰지 않아도 작동합니다.
오브젝트의 월드스페이스(world-space) 표면 지역은 라이트맵의 오브젝트당 스케일값과 전체 해상도를 곱한 값입니다. 결과는
라이트맵 에서의 오브젝트 UV 셋의 크기를 결정합니다. (더 정확히: [0,1]x[0,1] UV 사각형). 다음, 모든 오브젝트들은 가능한한 작은
라이트맵들로 싸여집니다. 반면, 각 오브젝트는 이전의 단계에서 계산된 공간을 차지합니다. 주어진 오브젝트의 UV 집합이[0,1]x[0,1]
부분만 차지하면, 많은 경우 아틀라싱 은 이웃 UV 집합들에 더 가까이 움직여 빈 공간을 활용합니다.
그 결과, 각 라이트맵 될 오브젝트는 라이트맵들중 하나의 위치를 가질것이며, 그 공간은 다른 오브젝트의 공간과 겹치지 않을
것입니다. 아틀라싱 정보는 세 개의 값으로 저장되며 (라이트맵 인덱스, Tiling(scale) 과 메쉬 렌더러의 오프셋입니다) 또한
지형(Terrains) 의 라이트맵 인덱스로 저장됩니다. 그리고, 라이트매핑 창의 오브젝트 pane 을 통하여 볼 수 있으며 수정될 수
있습니다.
라이트맵을 오른쪽 클릭하는 것은 선택된 라이트맵을 사용하는 모든 게임 오브젝트들을 선택 가능하게 합니다. 현재의 선택의
활성화된 오브젝트의 라이트맵들은 노란색으로 하이라이트 처리 되었습니다.
아틀라싱(Atlasing)은 오브젝트당 데이터(라이트맵 인덱스, 타일링, 오프셋) 만 변경 가능 하고, 오브젝트의 UV 집합은 변경 불가능
합니다. 이는 UV 집합이 공용 메쉬의 부분으로 저장되기 때문입니다. 메쉬를 위한 라이트맵 UV 들은 유니티의 내장된 autounwrapper 또는 유니티를 부르기전의 외부 3D 패키지를 사용하여 가져오기 시간에 생성됩니다.
아틀라스 잠그기 (Lock Atlas)
아틀라스 잠그기(Lock Atlas) 가 사용이 가능하면, 자동 아틀라싱은 실행되지 않을 것이며 오브젝트들의 라이트맵 인덱스(Lightmap
Index), Tiling 와 Offset 는 변경되지 않을 것입니다. 비스트는 현재의아틀라싱에 의존하고, 정확한 아틀라싱을 유지하는 것은
사용자의 책임입니다(예:라이트맵들 안에서는 겹치는 오브젝트가 없음, 라이트맵 슬롯을 참조하는 오브젝트는 라이트맵 배열 끝을
지나지 않음, 등등)
아틀라스 잠금(Lock Atlas)은 라이트매핑을 위한 오브젝트를 보낼 때 다른 워크플로우에 대한 가능성도 열고 있습니다. 그 다음은,
특별한 목적에 맞게, 스크립팅을 통해서나 수동으로 아틀라싱을 수행할 수 있습니다; 만약 현재의 아틀라싱에 만족하고 장면을 위한
라이트맵들의 셋을 더 많이 베이크하면, 자동으로 생성된 아틀라싱을 잠글 수 있습니다. 그리고, 하나 또는 추가의 오브젝트를
장면에 추가한 후, 아틀라싱이 다른 라이트맵 셋들과 호환되지 않는 변화를 만들지 않는 것을 확인하기 위해서 잠글 수도 있습니다.
아틀라스 잠금은 오직 아틀라싱을 잠그고, 메쉬 UV 등을 잠그지 않습니다. 만약, 소스 메쉬를 바꾸고, 메쉬의 불러오기(importer)를
“generate lightmap UVs”로 설정했다면, UV 들은 다르게 생성되었을 수도 있고, 현재의 라이트맵은 오브젝트에 정확하게 보이지
않을 것입니다. 이를 고치기 위해서는 라이트맵을 다시 베이크 하는 것이 필요합니다.
사용자 비스트베이크 설정들(Custom Beast bake settings)
베이크 프로세스에 더욱 컨트롤이 필요하면 custom Beast settings 을 참조하세요.
사용자 Beast 설정
유니티가 기본적으로 사용하는 다른 종류의 baking 설정이 필요하면, 이른 사용자 Beast 설정에 명시할 수 있습니다.
Beast 는 xml 포맷으로 정의된 bake 설정을 읽습니다. 보통, 유니티는 Lightmap 에디터 윈도우의 Bake 창에서 선택된 설정과 다른
내부 설정들을 기반으로 xml 파일을 생성합니다. Beast 의 xml 포맷의 설정을 명시하므로, 그러한 설정들을 덮어쓸 수 있습니다.
유니티가 자동으로 xml 파일을 생성하게 하기 위해서는, Lightmap 에디터 윈도우의 오른쪽 위에 있는 탭 메뉴를 클릭하세요. 그리고
Generate Beast settings file 을 선택합니다. lightmaps 옆에 BeastSettings.xml 파일이 프로젝트에 보이시는 것을 알 수
있습니다.그리고, Lightmap 에디터가 xml 설정파일들이 다음의 bake 동안 유니티의 설정을 덮어쓴다는 것을 알려줍니다 open
버튼을 클릭하여, 사용자 설정을 편집합니다.
조정 샘플링
Beast 는 라이트 맵을 샘플링할 때 조정 샘플링 방식을 사용합니다. 조명은 한 지역에서 추가 샘플들을 위치 시키기 위한 Beast 를
위한 사용자 정의 명암의 threshold 와는 달라야 합니다. 샘플 지역은 Min 과 Max 의 샘플 비율에 의해 정의됩니다. 사용자는 비율을 4..4 범위에서 지정합니다. 이는 Beast 샘플들이 픽셀당 1/256 샘플에서 256 샘플임을 의미합니다(공식은 4^샘플비율). 상품
목적(Min 샘플 비율=0) 을 위해서는 픽셀당 적어도 하나의 샘플을 사용할 것을 권유합니다. 낮은 샘플링(Undersampling)은 카메라가
큰 UV 패치를 사용하여 표현(render)하거나 질감을 baking 할 때 유용합니다. Beast 가 모든 필요한 샘플을 한 지역에서 끄집어내면,
마지막 픽셀값은 필터와 함께 사용되어 가중치가 부여됩니다. 필터가 생산하는 보기는 필터 커널의 사이즈와 사용하는 필터 타입에
의존합니다. 사용 가능한 필터들은 다음과 같습니다:
•
Box: 각 샘플은 균등하게 중요합니다. 실행 시 가장 빠른 필터이나, 흐린 결과를 줍니다.
•
삼각형 (Triangle): 필터 커널은 tent 이며, 이는 원거리 샘플들은 중요하게 간주되지 않음을 말합니다.
•
가우스(Gauss): 필터 커널로 가우스 함수를 사용합니다. 가장 좋은 결과를 줍니다. (소음을 제거하며, 세부사항들을 보존합니다).
더 많은 필터들이 사용 가능하며, 위의 세 개가 가장 유용합니다. 커널(필터) 크기는 1..3 영역의 픽셀들로 주어집니다. Beast 는
사실상 필터링 시 모든 서브 픽셀들을 사용합니다. 이는 Photoshop 에서 필터링 후에 작업하는 것 보다 더 좋은 결과를 보입니다.
Property:
Function:
AASettings
사용할 샘플링 방식/계획. 디폴트는 Adaptive.Adaptive: under/over 샘플링을 위한 어뎁티브 anti-aliasing 방식
samplingMode
(픽셀당 1/256 부터 256 샘플들까지). SuperSampling: super sampling 을 위한 Anti-aliasing 방식 (픽셀당 1-128
샘플들).
minSampleRate
최소 샘플 비율 설정, 기본값은 0 (즉 픽셀당 하나의 샘플).
maxSampleRate
최대 샘플 비율 설정, 사용되는 식은 4^최대 샘플비율(픽셀당 1, 4, 16, 64, 256 샘플들)
contrast
더 많은 샘플이 필요하면 컨트롤을 위한 명암 값. 더 낮은 값이 더 많은 샘플을 강제함.
filter
어떤 필터 타입이 사용할지 설정. Baking 을 위한 가장 유용한 것들은 박스, 삼각형, 가우스(Gauss)임.
픽셀에서의 필터사이즈 설정(1 에서 3).
filterSize
질감 Bake
이 설정들은 어떤 식으로 lightmaps 이 rasterize 화 되고, 질감으로 읽혀지는 등의 인공적인 부속물들을 제거하는데 도움을 줍니다.
Property:
Function:
TextureBakeSettings
렌더된 지역을 지정한 픽셀들의 수로 확장합니다. 이는 인위적 산물이 렌더된 지역 주위에서부터
edgeDilation
GPU 가 빈 픽셀들을 필터하는 것이 일어나지 않도록 하는 그런 인공적 산물(artifact)을 막는데
필요합니다.
bilinearFilter 는 GPU 가 bilinear 필터링을 적용했을 때 lightmap 에서의 데이터가 정확한지 확인하기
위해서 사용됩니다. 이는 아틀라스(atlas)가 촘촘히 묶여졌을 때, 가장 주목할 만합니다. 두 개의 다른
bilinearFilter
UV 패치들 사이에서 오직 하나의 픽셀만 있다면, Beast 의 bilinear 기능은 그 픽셀이 정확한
패치로부터 색이 채워져 있는지 확인합니다. 이는 빛의 솔기(seam)들을 최소화 합니다.
conservativeRasterization 는 UV 차트가 전체 픽셀을 덮지 않을 때 사용합니다. 만약 그런 레이아웃이
사용되면, Beast 는 실수로 texel 을 놓일 수 있습니다. 만약 conservative rasterization 이 사용되면,
conservativeRasterization Beast 는 UV 레이아웃 이 존재하면 이를 찾도록 보장할 것입니다. Beast 는 픽셀에서 어떤 UV
레이아웃이든 선택할 것입니다. Conservative Rasterization 는 종종 UV 아틀라스가 낮은 해상도로
촘촘히 싸여져 있거나 많은 얇은 오브젝트들이 존재하면 필요합니다.
bgColor
환경
Lightmap 의 배경 색상.
Beast 에서 환경 설정은 광선이 장면에서 모든 기하를 잃게 되었을 때 어떤 일이 일어나는 지를 제어 합니다. 환경은 이미지 기반의
라이팅(IBL)을 위한 lat-long 포맷의 HDR 이미지 혹은 constant 색상일 수 있습니다. 환경들은 오직 아주 멀리 떨어진 효과들, 즉
방향성 컴포넌트들만이 중요한 경우를 위해 사용된다는 점을 주목 해야 합니다.
환경을 정의하는 것은 바깥의 기분 좋은 조명의 결과를 얻기 위한 좋은 방법이지만, bake 시간을 증가 시킬 수 있습니다.
Property:
Function:
EnvironmentSettings
환경의 종류: None, Skylight 또는 IBL.
giEnvironment
광도를 위한 스케일 팩터, 화면에 맞는 HDR 질감을 스케일 하거나 감마 수정(correction) 에러들을
giEnvironmentIntensity
피하기 위해 사용. (Unity: Sky Light Intensity)
Constant 환경 색상. 타입이 Skylight 일 때 사용. 감마 수정(correction)에 의한 과급(boosting)을 피하기
위해서 색상을 광도 1.0 이하로 유지하는 것이 종종 좋은 생각입니다. 광도를 giEnvironmentIntensity
skyLightColor
설정을 사용하여 boost 하십시오. (Unity: Sky Light Color)
High-dynamic 영역의 Long-Lat 포맷의 IBL 배경 이미지, HDR .EXR, 또는 absolute path.
iblImageFile
그림자들
광선 자취 그림자들을 위한 설정들.
Property:
Function:
RenderSettings
그림자 광선들의 이중 교차를 피하기 위한 에러 시작점(threshold). 예를 들어, 그림자 광선은 일차 광선처럼 같은
bias
삼각형을 교차해서는 안됩니다. 그러나 제한된 산술적 정확도 때문에 이런 일이 발생할 수 있습니다. 편향(bias)
값이 이 문제를 제거하기 위해서 움직입니다. 0 으로 설정되면 이 값은 장면의 크기에 따라 자동으로 계산됩니다.
포인트당 그림자 광선들의 최고 개수 입니다. 이는 광원을 위한 소프트 그림자를 생성하는데 사용합니다. 소프트
그림자의 질의 대가로 렌더링 시간을 줄입니다. 이는 shadowSamples 설정이 이 값보다 높은 광원들로 보내어진
maxShadowRays
광선들의 최대 개수를 줄입니다. 그러나, shadowSamples 들이 더 낮은 값으로 설정되면, 이 수를 올리지는 않을
것입니다.
완료되기 전에 하나의 광선이 가질 수 있는 bounce 들의 개수. Bounce 는 반사되거나 굴절됩니다. 광선이 불투명한
maxRayDepth
오브젝트에 닿고 그림자에 빛이 들어오기 전에 더 많은 투명한 삼각형을 거치게 되면 이 값을 올립니다. 일반적인
실패 경우: 산의 그림자에 위치한 알파테스트 된 잎들을 가진 나무들.
전체 조명
Global Illumination 시스템은 간접적인 조명을 계산하기 위하여 두 개의 분리된 알고리즘들을 사용할 수 있습니다. Path Tracer 와
같은 빠른 알고리즘을 사용하여, 빛의 bounce 들의 다중 레벨들을 계산할 수 있습니다. 더 빠른 높은 성능의 global illumination
렌더러를 얻기 위해 Final Gather 를 사용해서 마지막 bounce 를 여전히 계산 할 수 있습니다. 두 서브시스템 모두 필요하면 효과를
증가시키기 위해서 광도와 포화(Saturation)의 개별적 컨트롤을 가집니다.
FinalGather 를 주요 통합자(integrator)로 사용하고, None 이나 PathTracer 를 두 번째 integrator 로 사용하길 권합니다. 유니티는
기본으로 첫 번째 옵션(final gather only)을 사용합니다. 그러므로, 대부분의 경우 가장 좋은 질의 렌더를 양산합니다. Path Tracer 는
많은 비 간접적 bounce 들이 필요할 때 사용하여야 합니다. 그리고, 좋은 질의 Final Gather-only 솔루션은 렌더하는데 많은 시간이
걸립니다.
Property:
Function:
GISettings
True 로 설정하는 것은 Global Illumination 을 가능하게 합니다.
enableGI
간접 빛의 최종 계산을 위해 사용되는 integrator. FinalGather 가 기본 설정.
primaryIntegrator
간접빛의 최초 바운스들을 위해 사용되는 integrator. 기본은 None, PathTracer 는 선택.
secondaryIntegrator
포스트 프로세스로서, RGB 의 결과로부터의 첫 번째 integrator 의 색상을 HSV 로 전환하며, V 값으로 비율
primaryIntensity
조정합니다. (Unity: Bounce Intensity)
포스트 프로세스로서, RGB 의 결과로부터의 첫 번째 integrator 의 색상을 HSV 로 전환하며, V 값으로 비율
primarySaturation
조정합니다.
포스트 프로세스로서, RGB 의 결과로부터의 두 번째 integrator 의 색상을 HSV 로 전환하며, S 값으로 비율
secondaryIntensity
조정합니다.
포스트 프로세스로서, RGB 의 결과로부터의 두 번째 integrator 의 색상을 HSV 로 전환하며, S 값으로 비율
secondarySaturation
조정합니다.
이 설정은 어두운 장면에서 빛의 바운싱을 과장하기 위해서 사용됩니다. 1 보다 큰 값으로 설정하는 것은 GI
연산을 위해 재료의 색상을 1 로 분산 시킵니다. 전형적인 사용 경우는 암흑 물질들이 사용되는
장면들입니다. 강력한 광원을 사용한 암흑 물질을 보강하는데 쉽기 때문에 방향성 라이팅 에서 쉽게
diffuseBoost
일어납니다. 간접 라이트는 바운스된 빛이 빨리 희미해지므로 이 장면들에서 매우 미묘합니다. 발산 boost 를
설정하는 것은 이를 보강할 것입니다. 0 에서 1 사이의 값은 diffuse 설정 값을 비슷하게 감소 시킬 것이며,
빛의 바운스를 재료값 0 이라로는 유효하지 않게 할 것입니다. 실제 일어나는 연산은 컴포넌트당
pow(colorComponent, (1.0 / diffuseBoost))입니다. (Unity: Bounce Boost)
Final Gather
아래의 설정들은 Final Gather 솔루션의 질이나 정확성을 컨트롤 할 것입니다. 일반적인 사용 시나리오는 다음과 같습니다:
1.
각각의 baking 설정 시, Contrast Threshold 와 Rays 들의 개수가 조정됩니다. 기하의 복잡도와 빛의 설정에 의존하므로
완벽한 설정들은 없습니다.
2.
Visibility 와 Light Leakage 감소는 비싼 연산이므로 실제적인 빛의 누출 문제를 고치는데 사용해야 합니다. 이러한 설정들은
빛의 누출 문제가 Global Illumination 연산들에 의해 발생하였을 때 도움이 됩니다. 매우 보편적인 빛의 누출 현상은 하나의
평면을 갖고 두께가 없는 벽에서 일어납니다. 그 상황에서 누출 된 빛은 GI 에서 나온 것이 아닙니다.
3.
그래디언트 시작점(Gradient threshold)은 코너주위에 하얀 후광들이 있으면 변화되어야 합니다.
2 와 3 단계는 대부분의 경우 많은 변화를 필요로 하지 않습니다.
Property:
Function:
GISettings
precalculation 동안 점들 사이에 명암의 차이들을 위하여 final gather 가 얼마나 sensitive 한지를
컨트롤합니다. 만약, 명암의 차이가 주변 점들을 위한 시작점보다 높으면, 더 많은 점들이 그 지역에
생성될 것입니다. 그들이 정말로 필요한 곳(예: 그림자 경계선 또는 간접 빛이 빠르게 변하는 지역)의
fgContrastThreshold
점들을 위치시키는 알고리즘을 설명합니다. 그러므로, 이 시작점은 장면에 생성될 점들의 개수를
조정해서 컨트롤합니다. Final gather 광선들의 낮은 숫자들이 사용되면, 점들은 더 높은 편차를 가지고,
더 높은 명암 차이를 보임을 명심하십시오. 그 경우는 명암의 시작점은 점들이 뭉치거나 샘플당 많은
광선이 사용되는 것을 막도록 올려져야 합니다. (Unity: Contrast Threshold)
각 Final Gather 샘플이 취한 광선의 최대값. 더 많은 광선들은 더 좋은 결과를 내지만, 평가하는데 더
fgRays
시간이 걸립니다. (Unity: Final Gather Rays)
벽들을 통과하는 빛의 누출을 줄이기 위해서 이를 켜십시오. 점들이 보간(interpolate) 하기 위해서 모였을
fgCheckVisibility
때, 점들 중 몇몇은 다른 쪽의 기하에 위치할 수 있습니다. 그러므로, 빛들은 기하/형상(geometry)을
통과할 때 흐트러집니다. 이를 방지하기 위해서 Beast 는 보이지 않는 점들을 거절 할 수 있습니다.
얼마나 많은 bounce 를 할지를 컨트롤 합니다. 가시(visibility) 검사가 수행되어야 합니다. multi bounce
fgCheckVisibilityDepth
Final Gather 를 사용할 때, 빛의 누출 현상을 경험하실 때에만 이를 조정해주세요.
이 설정은 final gather 를 첫 번째 GI 로 사용하고, path tracing 을 두 번째 GI 로 사용하였을 때 벽들을
통과하는 빛의 누출 현상을 줄이기 위해서 사용할 수 있습니다. 빛의 누출은 path tracer 가 벽의 다른 쪽
면의 값들을 필터 할 때 일어날 수 있으며, 두번째 GI fallback 으로 final gather 를 사용해서 벽들이나
fgLightLeakReduction
코너들에 가깝게 샘플 할 때 줄여집니다. 이를 가능하게 하면, final gather 의 깊이 3 이 자동으로 사용될
것이지만, 더 높은 깊이들은 벽들이나 코너에서만 사용될 것입니다. 이는 path tracing 이 두 번째 GI 로
사용했을 때에만 사용가능 합니다.
두 번째 GI 대신에, 벽들로부터 얼마나 더 멀리 final gather 가 다시 호출 되여 지는 지를 제어합니다.
fgLightLeakRadius
0.0 이 사용되면, Beast 는 좋은 값을 추정 하려고 시도 할 것입니다. 빛의 누출이 제거되지 않는다면, 더
높은 값으로 수동으로 설정할 수 있습니다.
interpolation 시에 어떻게 조도 증감(irradiance gradient)이 사용될지를 컨트롤합니다. 각 점은 각각의
조도 증감을 저장하여 보간(interpolation)을 증가하기 위해서 사용할 것입니다. 몇몇 경우에는
fgGradientThreshold
그래디언트의 사용이 하얀 후광과 다른 인공물(artifact)을 초래할 수 있습니다. 이 경우 시작점은 그러한
인공물을 줄이기 위해서 사용될 수 있을 것입니다. (low 또는 0 으로 설정). (Unity: Interpolation)
보간을 위한 final gather 점들의 개수를 설정합니다. 더 높은 값이 더 부드러운 결과를 줍니다. 그러나,
fgInterpolationPoints
세부적인 것 또한 부드럽게 처리합니다. 이 값을 증가했을 때 빛의 누출이 벽들을 통과할 때 나타나면,
샘플 가시(visibility)를 체크 하는 것이 문제를 해결 합니다. (Unity: Interpolation Points)
얼마나 final gather 가 법선들(normals)에서의 점들의 차이에 민감해야 하는지를 컨트롤 합니다. 작은
fgNormalThreshold
값은 높은 곡률의 지역에서 더 많은 점들을 줄 것입니다.
간접 빛의 바운스들의 개수를 컨트롤합니다. 더 높은 값은 더 정확한 결과를 주지만, 렌더링 시간의 증가
fgDepth
비용이 생깁니다. 더 저렴한 멀티 바운스 GI 를 위해서는, 깊이를 증가하는 대신에 Path Tracer 를 두
번째 integrator 로 사용합니다. (Unity: Bounces)
감쇠(attenuation)가 시작되는 거리입니다. 이 거리 이전에는 감쇠가 없습니다. Final gather 라이팅에
fgAttenuationStart
감소 효과를 주기 위해서 사용됩니다. fgAttenuationStop 이 0.0 보다 높게 설정했을 때 “enable” 됩니다.
감쇠(attenuation)가 멈추는 거리(0 으로 희석)를 설정합니다. 이 거리를 넘어서면 0 의 광도입니다.
fgAttenuationStop
감쇠설정을 가능으로 하려면, 이 값을 0.0 보다 높게 설정하십시오. 기본값은 0.0 입니다.
라이팅(lighting)이 거리에 의해 저하되는 비율을 조정하기 위해서 사용됩니다. 더 높은 지수는 더 빠른
fgFalloffExponent
저하를 주게 됩니다.
Final Gather 를 잔잔한 폐색(Ambient Occlusion)과 혼합하기 위해서 사용합니다. 0..1. 0 의 범위는
폐색(occlusion)이 없음을 의미하며, 1 은 전체 폐색을 의미합니다. 만약 Final Gather 가 multiple depth 를
사용하고, Path Tracing 을 두 번째 GI 로 사용한다면, 결과는 밋밋(flat)해 집니다. 더 높은 명암을 얻을 수
fgAOInfluence
있는 좋은 방법은 계산시 ambient occlusion 을 인자로 사용하는 것 입니다. 이러한 Ambient Occlusion
알고리즘은 오직 final gather 의 연산에만 영향을 미칩니다. Lightmapping 창에 드러나지는 Ambient
Occlusion 은 분리된, 기하/형상 통과(geometry-only pass)에 의해 다르게 연산 됩니다.
폐색 광선들을 위한 최대 거리입니다. 이 거리를 넘어서면, 광선은 폐색되지 않는 것으로 간주합니다.
fgAOMaxDistance
닫혀진 방과 같은 닫혀진 장면들의 전체 폐색(full occlusion )을 피하기 위하여 또는 AO contribution 을
접게(creases)하기 위해 사용 가능합니다.
Ambient occlusion 을 위한 명암을 조정하기 위해 사용 가능합니다.
fgAOContrast
폐색 값을 위한 비율 조정. 그림자 효과를 늘이거나 줄이기 위해서 사용합니다.
fgAOScale
경로 추적기
빠른 다중 바운스 global illumination 을 위해서 패스 트레이싱(path tracing)을 사용합니다. Baking 을 위한 첫 번째 integrator 로
사용되어서는 안됩니다. 왜냐하면, 결과는 깔끔하지 않기 때문에 light map 에서 좋지 않습니다. 첫 번째 integrator 로 설정 등을
조정하고 캐쉬 공간을 확보하고, 정확도가 좋은 지를 확인하는데 사용 할 수 있습니다. 의도 되는 사용법은 이를 두 번째 integrator 로
설정하고, 첫 번째 integrator 로는 하나의 바운스 final gather 를 가지는 것입니다. 정확성과 점의 크기는 캐쉬(cache)가 충분히
미세(fine grained)한지 확보하기 위해 조정될 수 있습니다.
Property:
Function:
GISettings
각각의 샘플 요소(pixel, texel or vertex)를 위해서 추적될 경로의 개수를 설정합니다. 미리 보기 렌더링을
위해서는 0.5 나 0.1 과 같은 낮은 값들이 사용될 수 있습니다. 이는 픽셀들의 1/2 에서 1/10 이 경로를
ptAccuracy
생성하게 되는 것을 의미합니다. 좋은 퀄리티를 위해서는 필요하면 프로덕션 렌더링 값이 1.0 이상이 사용될
수 있습니다.
ptPointSize
경로 추적기 캐쉬에 있는 점들 사이의 최고 거리를 정합니다. 0 으로 설정되면, 장면의 사이즈에 기반해서
값이 자동으로 계산될 것입니다. 자동 값은 렌더링시에 프린트 될 것이며, 이는 점의 사이즈가 조정이 필요할
때 좋은 시작 값이 됩니다.
가능으로 설정되면, 경로 추적기는 광원으로부터 디렉트 라이팅을 캐쉬 할 것입니다. 더 적은 디렉트 라이트의
ptCacheDirectLight 계산이 필요하므로, 성능을 향상 시킬 것입니다. 그리고, 근접된 결과를 주는데, 라이팅의 퀄리티에 영향을 줄
수 있습니다. 가령, 특정한 하이라이트로부터의 간접 라이트는 유실되게 됩니다.
벽들을 통과하는 빛의 누출을 줄이기 위해서는 이 설정을 켜야 합니다. 점들이 보간 되기 위해 모였을 때, 몇몇
점들은 다른 쪽 기하/형상에 위치 할 수 있습니다. 그 결과로, 빛은 형상을 통과할 때 흐트러지게 됩니다. 이를
ptCheckVisibility
막기 위해서는, Beast 가 보이지 않는 점들을 거절 할 수 있습니다. 주의: 이 설정을 사용할 때는 Final
Gather 를 위해 빛 누출 감소(light leakage reduction)를 꺼야 합니다.
UV 빛매핑
채널이 존재하면 유니티는 빛맵을 위해 UV2 를 사용합니다. 그렇지 않으면 주요한 UV 가 사용될 것입니다.
유니티는 빛맵 UV 를 만들기위해 메쉬를 풀수 있습니다. Mesh Import Settings 에서 Generate Lightmap UVs 를 이용하세요.
Generate Lightmap UVs 의 고급 옵션:
Property:
Function:
메쉬가 전체 1024x1024 빛맵을 차지 한다고 가정한 패치들 간의 여백. 이것은 큰 효과가 있는데 필터링을 가능하게
Pack
Margin
하기위해 빛 맵은 패치 경계 근처 texel 의 빛 정보를 포함합니다. 그래서 빛맵을 적용할때 빛이 새어나가는 것을
막기위해 패치간에 여백이 있어야 합니다.
근접한 삼각형들 간의 각도인데 삼각형 간의 변은 단단한 변으로 간주되며 이음새가 생길 것입니다. 그것을 180 도로
Hard Angle 설정하면 모든 변이 부드럽게 여겨질 것이고 이것은 유기체 모델에 유용합니다. 기본 각도는 88 도이며 이것은 기계적
모델에 유용합니다
소스 기하 각도의 UV 각도 최대 가능한 편차 퍼센티지. 기본적으로 이것은 uv 공간에 있는 삼각형들이 원래 기하에 있는
Angle
Error
삼각형들과 얼마나 유사한지를 제어합니다(값이 클수록 삼각형들은 더 유사합니다). 사용자는 보통 빛맵이 적용되었을
때 인공물을 피하기위해 이 값은 아주 낮게 합니다. 기본은 8 퍼센트입니다(값은 0 부터 100 까지)
소스 기하 영역의 최대 가능한 편차 페센티지. 기본적으로 이것은 상대적 삼각형 영역이 얼마나 잘 보존되는 지를
제어합니다. 그런 식으론 삼각형들이 다른 해상도를 가질 수 있으므로 왜곡이 빛맵 퀄리티를 떨어뜨리는 것이 아닌지
Area Error
재확인 해야하지만 보통 이것은 중요하지 않고 그것을 위로 옮기는 것은 패치가 적게 생성되게 합니다. 기본값은
15 퍼센트입니다(값은 0 부터 100 까지 입니다)
빛맵핑을 위한 사용자 자신의 UV 를 원한다면 빛맵핑을 위한 좋은 UV 셋을 기억하세요:
•
[0,1]x[0,1]공간 안에 속해 있는지.
•
겹치는 면이 없는지 .
•
UV 에서 각도의 그리고 소스 기하의 편차인 낮은 각도 왜곡이 있는지.
•
낮은 영역 왜곡을 가지고 있는지. 즉 삼각형의 상대적 크기는 사용자가 어떤 영역에서는 더 큰 빛맵 해상도를 원하지 않으면 거의
보존 됩니다.
•
각 패치사이의 충분한 여백이 있는지 .
위에서 주어진 힌트의 예제들:
각도 왜곡
이 스크린샷은 동일한 해상도와 다른 uvs 에서 만들어 졌습니다. 인공물들을 보고 어떻게 빛의 모양이 약간씩 바귀는지를 보싶시오.
사실 4 개의 삼각형만 있으므로 모양 왜곡은 더 심할 수 있습니다.
영역 왜곡
같은 파라미터의 두개의 스포트라이트가 있습니다. 다른 점은 상대적 삼각형 크기가 유지되지 않기 때문에 단순히 다른 빛맵
해상도로 영역을 비추는 것입니다.
오클루전 컬링(Occlusion Culling, 물질제거기법)
오클루전 컬링 오브젝트가 다른 오브젝트에 의해 가려져서 현재 카메라에 보이지 않을 때 해당 오브젝트의 랜더링을 차단하는
기능입니다. 3D 컴퓨터에서는 이것은 자동적으로 발생하지 않는데 그것은 대부분 멀리 있는 오브젝트가 먼저 그려지고 그 다음
가까운 오브젝트가 그 위에 차례로 그려지기 때문입니다(이것을 "overdraw"라 부릅니다). 오클루전 컬링은 프러스텀 컬링(Frustum
Culling)과는 다릅니다. 프러스텀 컬링은 카메라의 시야 밖에 있는 오브젝트의 랜더링을 차단하지만 overdraw 에 의해 숨은
오브젝트는 차단하지 않습니다. 사용자가 오클루전 컬링을 사용할 때에도 사용자는 여전히 프러스텀 컬링의 혜택을 유지함을
유의하십시오.
오클루젼 컬링을 사용하는 장면(scene), 오른쪽은 오클루전 컬링을 사용하지 않는 같은 장면
오클루전 컬링 과정은 가상 카메라로 장면(scene)을 검색하여 잠재적으로 가시적인 오브젝트의 세트의 계층을 구축합니다. 이
데이터는 실행 시에 카메라가 어떤 것이 가시적이고 어떤 것이 아닌지를 확인하는 데 쓰입니다. 이 정보를 갖추고, 유니티는 오직
가시적인 오브젝트만 랜더링이 될 수 있도록 합니다. 이렇게 하면 draw 콜을 호출하는 수가 줄어들고 게임의 성능이 향상 됩니다.
오클루전 컬링을 위한 데이터는 셀(cell)로 이루어져 있습니다. 각 셀은 해당 장면의 전체 결합 볼륨은 세분화된 부분입니다. 좀 더
구체적으로 말하면 셀은 2 진 트리를 형성합니다. 오클루전 컬링은 2 개의 트리를 사용하는데 하나는 View Cells(정적 오브젝트)이고
다른 하나는 Target Cells(움직이는 오브젝트)입니다. View Cell 은 인덱스 리스트와 연결 되는데 이것은 가시적인 정적 오브젝트를
설정하며 이렇게 하면 정적 오브젝트에 대해 좀 더 정확한 컬링 결과를 가져다 줍니다.
사용자가 오브젝트를 생성할 때 이상의 사항을 기억하는 것은 사용자의 오브젝트의 크기와 셀 크기 사이에 적당한 균형을 유지하기
위하여 매우 중요합니다. 이상적으로는, 사용자의 오브젝트에 비하여 너무 작은 셀을 가지지 않는 것이 좋으며 마찬가지로 너무 많은
셀을 차지하는 오브젝트를 가지는 것도 바람직하지 않습니다. 종종 사용자는 큰 오브젝트를 작은 조각으로 나누어 컬링을 개선할 수
있습니다. 하지만, 만일 모두 같은 셀에 속하기만 한다면, 여전히 같은 오브젝트는 합쳐서 draw 콜의 횟수를 줄일 수 있고 이 경우
오클루전 컬링은 영향을 받지 않습니다. 셀의 모음과 어떤 셀이 다른 셀로부터 가시적인지를 결정하는 시각적 정보를 PVS
(Potentially Visible Set).
오클루전 컬링(Occlusion Culling) 설정하기
오클루전 컬링을 사용하려면, 수동적인 설정이 필요합니다. 우선, 사용자 레벨 geometry 가 분별할 수 있는 크기의 조각으로
나누어져야 합니다. 사용자 레벨을 작고 벽이나 빌딩처럼 큰 오브젝트에 의해 가려져 잘 설정된 영역으로 배열하는 것 역시 도움이
됩니다. 여기에서의 아이디어는 각 개별 메쉬가 해당 오클루전 데이터를 기반으로 켜지거나 꺼지게 될 것이라는 겁니다. 그러므로,
만일 사용자가 사용자의 방에 있는 모든 가구를 담고 있는 하나의 오브젝트가 있다면, 그 가구는 모두 혹은 전형 선별이 되지 않을 것
입니다. 이것은 각각의 가구에 별도의 메쉬를 두어 각자 카메라의 시각 점에 따라 개별적으로 선별되는 것 만큼이나 말이 되지
않습니다.
사용자는 Inspector 에서 사용자가 오클루전의 일부가 되기를 원하는 모든 장면 오브젝트를 Static 로 태그를 달아야 합니다. 이를
행하는 가장 빠른 방법은 사용자가 Static 로 두고 싶은 오브젝트들을 빈 GameObject 의 자식으로 두고 해당 부모를 Static 로
설정하는 것이고, 스크린에서 옵션 대화 창이 나타날 때 자식들을 변경할 수도 있습니다. 그들이 Static 로 태그가 달리면 그들을 빈
GameObject 오브젝트로부터 탈-부모화 할 수 있습니다.
인스펙터의 Static 체크박스
다음 Tools->Occlusion Culling 을 클릭하여 오클루전 컬링 인스펙터를 엽니다.
해당 인스펙터에서, 사용자는 몇 가지 변경할 수 있는 값을 찾을 수 있습니다. 그러한 값들은 아래와 같습니다:-
오클루전 컬링(Occlusion Culling) – 오브젝트
오클루전 컬링 인스펙터 오브젝트 탭
사용자는 오브젝트 탭을 이용하여 Occlusion Areas GameObjects 을 생성할 수 있습니다. 이 영역은 사용자가 어디에 오클루전
컬링을 사용하고 싶은지를 명시합니다.
주의: 디폴트로 사용자가 만일 오클루전 영역을 생성하지 않으면, 오클루전 컬링은 장면(scene) 전체에 적용됩니다.
Properties
Property:
Quick Select
None
Create New
Function:
오클루전 영역을 선택/생성 하고 신속히 변경할 수 있게 해 줍니다.
이것이 디폴트 값입니다.
새로운 오클루전 영역 GameObject 을 생성합니다.
사용자가 Quick Select 드롭 다운 메뉴에서 Create New 을 클릭하면, 유니티는 자동적으로 오클루전 영역을 생성하고
디폴트영역(장면전체)를 제거할 것 입니다. 이제 사용자는 자신의 오클루전 영역(들)을 필요에 따라 변경할 수 있습니다.
오클루전 영역 인스펙터
Properties
Property:
Size
Center
Function:
오클루전 영역의 크기를 설정합니다.
오클루전 영역의 중앙을 설정합니다. 디폴트는 0,0,0 로 박스의 중앙에 위치합니다.
카메라가 있을 수 있는 곳을 설정합니다. Occlusion Area 내에 있는 정적 오브젝트를 가리려면 여기를
Is View Volume
Is Target
체크하십시오.
움직이는 오브젝트를 가리려면 선택하십시오.
Volume
Target
Resolution
Low
Medium
High
해당 영역 내에서 오클루전 컬링이 얼마나 정확해야 할 지를 결정합니다. 이는 오클루전 영역 안에 셀의 크기에
영향을 줍니다. 주의: 이것을 Target Areas 만 영향을 줍니다.
이 속성을 사용하면 처리 시간은 줄어들지만 덜 정확합니다.
오클루전 컬링 데이터를 처리하는데 있어 정확성과 걸리는 시간 사이에 균형을 맞춰 줍니다.
처리에 필요한 시간은 늘어나지만 정확도는 증가합니다.
사용자가 높은 해상도 보다는 정확도를 원할 때 이 값을 사용하십시오. 하지만 더 많은 시간이 걸린다는 것을
Very High
기억하십시오.
사용자의 움직일 수 있는 오브젝트에 거의 정확한 오클루전 컬링을 원하면 이 값을 사용하십시오. 주: 이 설정은
Extremely High
처리에 많은 시간을 소요합니다.
만일 카메라가 주어진 오클루전 컬링 영역 밖에 있거나 오브젝트가 해당 영역 밖에 있다면, 해당 오브젝트들을 가려지지 않습니다.
Occlusion Culling - Bake
오클루전 컬링 인스펙터의 bake 탭''
Properties
Property:
View Cell
Size
Near Clip
Plane
Far Clip
Plane
Quality
Function:
각 뷰 영역 셀의 크기. 작은 값은 더 정확한 오클루전 컬링을 만들어냅니다. 이 값은 오클루전 정확도와 저장
크기간에 트레이드 오프 값입니다
근접 클립 평면(Near clip plane)은 게임 내에서 사용되는 모든 카메라의 가장 작은 근접 클립 평면으로 설정되어야
합니다.
오브젝트를 고르는 데 사용된 원거리 클립 평면(Far Clip Plane). 거리가 이 값보다 큰 오브젝트는 자동적으로
가려집니다.(게임 내에서 사용되는 모든 카메라의 가장 먼 클립 평면으로 설정되어야 합니다).
오브젝트를 가릴 때 품질/정확도를 결정합니다.
개발 시에 사용하십시오(예, 이것은 부정확하지는 오클루전 컬링이 사용자 게임에서 어떻게 작동하는지 알 수 있게
Preview
Production
해 줍니다).
사용자 게임을 배치할 때 사용하십시오(시간은 더 걸리지만 좀 더 정확합니다)
이 값들을 조절하고 나면 Bake 버튼을 클릭하여 오클루전 컬링 데이터의 처리과정을 시작합니다. 사용자가 만일 그 결과에 만족하지
못하면 Clear^^ 버튼을 클릭하여 이 전에 처리된 데이터를 삭제 할 수 있습니다.
Occlusion Culling - 시각화(Visualization)
오클루전 컬링 인스펙터의 시각화 탭
Properties
Property:
Quick
Function:
사용자가 자신의 오클루전 컬링이 어떻게 동작하는지를 보려면 그 장면에서 신속하게 어느 카메라든 선택할 수 있게
Select
하여 줍니다.
근접 혹은 원거리 평면은 오클루전 데이터를 처리하는 데 사용된 가상 카메라를 설정합니다. 만일 사용자가 원거리와 근거리 평면에
몇 개의 카메라가 있다면, 사용자는 정확한 오브젝트의 선정을 위해서는 그 모든 카메라 중 가장 작고 근접한 평면과 가장 크고
원거리의 평면을 사용해야 합니다.
해당 장면의 모든 오브젝트는 결합 볼륨의 크기에 영향을 미치므로, 그들 모두를 장면의 가시적인 범위 안에 두려고 하십시오.
사용자가 오클루전 데이터를 생성할 준비가 되면 Bake 버튼을 클릭하십시오. Bake 탭의 Quality 선택 박스에서 Preview 와
Production 중에 선택하는 것을 잊지 마십시오. Preview 는 저작 도구에서 사용자의 뷰 영역을 테스트하기 위하여 사용되며 데이터를
만들어내는 가장 빠른 방법입니다. Production 은 사용자가 출시 준비가 완료 되었을 때 타깃 플랫폼(예. iPhone)에서 시범 가동을
하기 위하여 사용됩니다.
오클루전 데이터를 구축하는 데 걸리는 시간은 셀 레벨, 데이터 크기 그리고 사용자가 선택한 품질에 달려 있다는 것을 기억하십시오.
유니티는 주 윈도우 하단에 PVS 생성의 상태를 보여줄 것 입니다.
해당 과정이 끝나면, 사용자는 뷰 영역에 몇몇 다채로운 큐브를 볼 수 있을 것 입니다. 색상 영역은 같은 오클루전 데이터를 공유하는
지역입니다.
사용자가 오클루전 컬링을 위하여 이전에 처리된 모든 데이터를 없애고 싶다면 Clear 에 클릭하십시오.
오브젝트 이동
오클루전 컬링을 움직이는 오브젝트에 적용하려면 사용자는 우선 Occlusion Area 을 생성하고, 그 다음 그 크기를 변경시켜
움직이는 오브젝트가 위치 할 공간과 맞추어야 합니다(물론 그 움직이는 오브젝트는 static 로 표시 할 수 없습니다).
Occlusion Area 을 생성한 후에, Is Target Volume 체크박스를 체크하여 움직이는 오브젝트를 가리십시오.
움직이는 오브젝트를 위한 오클루전 영역 속성
Property:
Function:
오클루전 영역의 크기를 설정합니다.
Size
오클루전 영역의 중앙을 설정합니다. 디폴트는 0,0,0 로 박스의 중앙에 위치합니다.
Center
D 카메라가 있을 수 있는 곳을 설정합니다. Occlusion Area 내에 있는 정적 오브젝트를 가리려면 여기를
Is View Volume
Is Target
체크하십시오.
움직이는 오브젝트를 가리려면 선택하십시오.
Volume
Target
Resolution
Low
Medium
High
해당 영역 내에서 오클루전 컬링이 얼마나 정확해야 할 지를 결정합니다. 이는 오클루전 영역 안에 셀의 크기에
영향을 줍니다. 주: 이것을 Target Areas 만 영향을 줍니다.
이 속성을 사용하면 처리 시간은 줄어들지만 덜 정확합니다.
오클루전 컬링 데이터를 처리하는데 있어 정확성과 걸리는 시간 사이에 균형을 맞춰 줍니다.
처리에 시간은 늘어나지만 정확도는 증가합니다.
사용자가 높은 해상도 보다는 정확도를 원할 때 이 값을 사용하십시오. 하지만 더 많은 시간이 걸린다는 것을
Very High
기억하십시오.
사용자의 움직일 수 있는 오브젝트에 거의 정확한 오클루전 컬링을 원하면 이 값을 사용하십시오. 주: 이 설정은
Extremely High
처리에 많은 시간을 소요합니다.
사용자가 오클루전 영역을 추가 한 후, 그것이 어떻게 박스를 셀로 세분화하는지를 보아야 합니다. 움직이는 오브젝트에서 오클루전
영역이 어떻게 계산 되는지를 보려면, 사용자는 Target 을 선택하고 오클루전 컬링 인스펙터가 열려 있는 동안 안에 Scene
ViewView 버튼을 선택해제(deselect) 하여야 합니다.
Target (움직이는 오브젝트)을 선택하거나 혹은 View (정적 오브젝트)로 계산 된 데이터가 어떻게 움직이는지 미리 볼 수 있습니다
생성된 오클루전 테스트하기
사용자의 오클루전이 설정 된 후, 사용자는 Cull Geometry 옵션 (Occlusion Culling 윈도우에 위치)을 허용하고 장면 뷰에서 Main
Camera 를 움직여 테스트 할 수 있습니다.
장면 뷰에서 오클루전 뷰 (Occlusion View)모드
만일 사용자가 주 카메라를 움직인다면 (사용자가 Play 모드에 있든 혹은 아니든), 사용자는 여러 오브젝트가 스스로를 차단하는
것을 볼 수 있을 것 입니다. 사용자가 여기서 찾아야 할 것은 오클루전 데이터에서 에러입니다. 사용자가 움직이다 보면 갑자기
오브젝트가 장면으로 튀어나오는 것을 보면 에러 임을 확인할 수 있을 것 입니다. 만일 이런 현상이 발생한다면, 에러를 고치기 위해
사용자는 해상도를 바꾸거나(사용자가 target 볼륨으로 실행 중이라면) 혹은 해당 에러를 감추기 위해 오브젝트를 움직이는 것 중
옵션을 선택할 수 있습니다. 오클루전의 문제를 디버깅 하려면, 주 카메라를 지점 체크를 위해 문제의 위치로 옮길 수 있습니다.
이 과정이 끝나면 사용자는 뷰 영역에 몇몇 다채로운 큐브를 볼 수 있을 것 입니다. 푸른 큐브는 Target Volumes 의 셀 분할을
나타냅니다. 흰색 큐브는 View Volumes 의 셀 분할을 나타냅니다. 만일 매개변수가 정확하게 설정되어 있다면 사용자는 일부
오브젝트가 랜덩링 되어 있지 않은 것을 볼 수 있습니다. 이것은 왜냐하면 그들이 카메라의 시각 프러스텀(frustum) 밖이거나 혹은
다른 오브젝트에 의해 시각에서 가려져 있기 때문입니다.
오클루전이 마치면, 만일 사용자가 사용자 장면에 아무것도 가려지지 않을 것을 볼 수 있다면 사용자의 오브젝트를 좀 더 작은
조각으로 분할하여 그들이 완전히 해당 셀 내에 포함 되도록 하여 보십시오.
Loading Resources at Runtime
실행 가능한 주요 게임 내에서 포함되지 않은 사용자의 끝난 게임에서 몇 가지 종류의 에셋을 포함하기를 원하는 시나리오가
있습니다: 독립형, 웹 플레이어 또는 사용자의 iOS/Android 어플리케이션. 예를 들어, 하나의 시나리오는 웹 플레이어의 다운로드
사이즈를 슬림하게 하고 동적으로 개별적인 오브젝트 또는 아이템을 다운로드하고 객체화하게 하는 것입니다. 이 방법으로 오직
필요한 물체많이 사용자에 의해 로드됩니다. 또다른 시나리오는 추가적인 무기, 환경, 캐릭터 또는 심지어 완전한 레벨같은
다운로드가 가능한 컨텐츠를 위한 것일지도 모릅니다.
Unity Pro/iOS Advanced/Android Advanced 에서 사용자는 이러한 태스크를 수행하기 위해서 두 가지 옵션 중에서 선택할 수
있습니다: Asset Bundles, 그리고 Resource Folders. Non-Pro/Advanced 라이센스를 가지는 사람은 Resource Folders 만을
사용할 수 있습니다.
Asset Bundles (Unity Pro-only/iOS Advanced/Android Advanced licenses only)
Asset Bundle 은 에셋의 외부적인 컬렉션 입니다. 사용자는 많은 Asset Bundle 을 가질 수 있고 그러므로 에셋의 많은 다른 외부
컬렉션을 가질 수 있습니다. 이러한 파일은 보통 사용자가 동적으로 접근하기 위해 웹 서버위에 앉아있는 구축된 Unity 플레이어의
외부에서 존재합니다.
Asset Bundle을 구축하기 위해서 사용자는 편집기 스크립트 안으로부터 BuildPipeline.BuildAssetBundle()를 콜합니다.
아규먼트에서 사용자는 빌드된 파일에 포함되는 Objects의 배열을 지정합니다. 이것은 사용자가 AssetBundle.Load()을 사용하는
것에 의해 실시간으로 동적으로 후에 로드할 수 있는 하나의 파일을 빌드할 것입니다.
Resource Folders
Resource 폴더는 구축된 Unity 플레이어에 포함되는 에셋의 컬렉션이나 반드시 인스펙터에서 어떠한 GameObject 로도 반드시
연결되지는 않습니다.
Resource 폴더로 어떤 것이라도 넣기 위해 사용자는 단순히 Project View에서 하나의 새로운 폴더를 생성하고 폴더를
"Resources"라고 이름 짓습니다. 사용자는 사용자의 프로젝트에서 다르게 구성된 다수의Resource 폴더들을 가질 수 있습니다.
사용자가 이러한 폴더의 하나로부터 로드하고 싶을 때마다 사용자는 Resources.Load()를 콜합니다.
사용자의 전개할만한 타겟이 Streaming Web Player 라면 사용자는 어떤 씬이 사용자의 Resource 폴더에 모든 것을 포함할
것인지를 정의할 수 있습니다. 사용자는 Player Settings 에서 이것을 하고 Edit->Project Settings->Player 를 통해서 접근될 수
있습니다. First Streamed Level With Resources 을 파라미터와 함께 세팅하고 사용자의 Resources 폴더에 있는 모든 에셋은 이
레벨이 사용자에게로 스트림할 때 로드될 것입니다.
Note:
Resources 폴더에서 발견되는 모든 에셋과 그들의 의존성은 resources.assets 이라고 불리는 파일에 저장됩니다. 에셋이 벌써 다른
레벨에 의해 사용된다면 그것은 그 레벨을 위해 .sharedAssets 에 저장됩니다. Edit -> PlayerSettings 'First Streamed Level' 세팅은
어떤 레벨에서 resources.assets 이 빌드에서 수집되고 포함될 지를 결정합니다.
"First streamed Level" 이전의 레벨은 Resource 폴더에서 하나의 에셋을 포함하고 있다면 그 에셋은 그 레벨을 위해 에셋에 저장될
것입니다. 그것이 이후에 포함된다면 그 레벨은 "resources.assets" 파일로부터 에셋을 레퍼런스할 것입니다.
Resources folder 에 있는 유일한 에셋은 Resources 을 통해서 접근될 수 있습니다. 그러나 더 많은 에셋은 그들이 의존적이기
때문에 결국 "resources.assets" 파일에 있습니다 (예를 들어 Resources 폴더에서 하나의 재질은 Resources 폴더 외부에서 하나의
텍스쳐를 레퍼런스할 지도 모릅니다).
Resource Unloading
사용자는 AssetBundle.Unload()을 부르는 것에 의해 unloadAllLoadedObjects 파라미터를 위해 true를 패스한다면 AssetBundle에
의해 내부적으로 붙잡혀 있던 오브젝트 둘 다와 AssetBundle.Load()를 사용해서 AssetBundle로 부터 로드된 하나는 파괴될 것이고
번들에 의해 사용된 메모리는 릴리즈될 것입니다.
때때로 사용자는 AssetBundle 을 로드하고 원하는 물체를 객체화하고 그 오브젝트들을 주변에 유지하는 동안 번들에 의해 사용된
메모리를 릴리즈하는 것을 더 선호할지도 모릅니다. 이점은 사용자가 다른 태스크 예를 들어 또다른 AssetBundle 을 로딩하는 것을
위해 메모리를 비울 수 있다는 것입니다. 시나이오에서 사용자는 파라미터로서 false 를 패스할 것입니다. 번들이 파괴된 후에
사용자는 그것으로부터 더이상 오브젝트를 로드할 수 없을 것입니다.
사용자가 또다른 레벨을 로딩하기 전에 Resources.Load()을 사용해서 로드된 씬 오브젝트를 파괴하고 싶다면 그들
위에서 Object.Destroy()를 부릅니다. 에셋을 릴리즈하기 위해서 Resources.UnloadUnusedAssets()를 사용합니다.
스크립트를 통한 소스 에셋 수정하기
자동 인스턴스화
보통 사용자가 어떤 종류의 게임 에셋을 수정하고 싶을 때는 이것이 실행시에 그리고 임시적으로 일어나기릴 원할 것입니다. 예를
들어 만약 캐릭터가 무적 파워업을 들었을 때 무적상태를 보여주기 위해 캐릭터의 재료쉐이더를 바꾸기를 원할 것입니다. 이 처리는
사용되고 있는 재료의 수정을 필요로합니다. 플레이 모드를 빠져나올 때는 재료가 다른 쉐이더를 가지고 있지 않기를 바랄 것이기
때문에 이 변화는 임시적이어야 합니다.
그러나 유니티에서는 영구적으로 소스 에셋을 바꿀 수있는 스크립트를 작성하는 것이 가능합니다. 위의 재료 예제로
시작해보겠습니다.
재료의 쉐이더를 임시로 바구기 위해서는 재료컴포넌트의 쉐이더 속성을 바꿔줍니다.
private var invincibleShader = Shader.Find ("Specular");
function StartInvincibility {
renderer.material.shader = invincibleShader;
}
이 스크립트를 사용하고 플레이 모드를 나오게되면 Material의 상태는 플레이 모드를 시작할 때의 상태로 리셋됩니다. 이것은
renderer.material을 접근할 때마다 일어나는데 재료는 자동으로 인스턴스와되며 그 인스턴스가 리턴 됩니다. 이 인스턴스는
자동으로 동시에 렌더러에 적용됩니다. 그러므로 사용자는 영구적인 변화에 대한 두려움 없이 원하는 어떤 변화도 만들 수 있습니다.
직접적인 수정
중요한 주의 사항
아래의 함수는유니티의 실제 소스 에셋 파일을 수정합니다. 이런 수정은 다시 되돌릴 수 없습니다. 주의해서 사용하세요.
이제 플레이 모드를 빠져나올 때 재료가 리셋되는 것을 원치 않는다고 생각해 보세요. 이를 위해 renderer.sharedMaterial를 사용할
수 있습니다. sharedMaterial 속성은 렌더러(그리고 다른 것들 또한)가 사용하고 있는 실제 에셋을 리턴할 것입니다.
아래의 코드는 Specular 쉐이더를 사용하기 위해 영구적으로 재료를 수정할 것입니다. 이것은 플레이 모드 전의 상태로 재료를
리셋하지 않습니다.
private var invincibleShader = Shader.Find ("Specular");
function StartInvincibility {
renderer.sharedMaterial.shader = invincibleShader;
}
보다시피 sharedMaterial 에 어떤 변화를 주는것은 유용하지만 위험하기도 합니다. sharedMaterial 에서의 어떤 변화도 영구적일
것이며 취소 불가능 합니다.
적용가능한 클래스 멤버
위에서 설명한 공식은 재료이외에도 적용가능 합니다. 이 관습을 따르는 다른 에셋의 모든 리스트는 아래와 같습니다:
•
재료: renderer.material 와 renderer.sharedMaterial
•
메쉬: meshFilter.mesh 와 meshFilter.sharedMesh
•
물리 재료: collider.material 와 collider.sharedMaterial
직접 할당
위 재료, 메쉬 또는 물리 재료에서 공공(public) 변수를 정의하고 관련된 클래스 멤버가 아닌 그 변수를 사용해 수정을하면, 그 수정된
사항이 적용되기 전에 자동으로 인스턴스화 되는 이점을 받지 못합니다.
자동으로 인스턴스화 되지 않는 에셋
Desktop
수정할때 자동으로 인스턴스화 되지 않는 두가지 에셋이 있습니다.
•
Texture2D
•
TerrainData
스크립트를 통한 위 에셋의 수정은 언제나 영구적이며 취소할 수 없습니다. 그래서 스크립트를 통해 지형의 높이맵을 수정한다면
사용자가 직접 인스턴스화하고 값을 할당해야 합니다. 텍스쳐도 마찬가지 입니다. 텍스쳐파일의 픽셀을 수정하면 그 변화는
영구적입니다.
iOS
Texture2D 에셋은 수정 될때 절대 자동으로 인스턴스화 되지 않습니다. 스크립트를 통해 어떤 변화도 영구적이며 취소 불가능
합니다. 텍스쳐파일의 픽셀을 수정하면 그 변화는 영구적입니다.
Android
Texture2D 에셋은 수정 될때 절대 자동으로 인스턴스화 되지 않습니다. 스크립트를 통해 어떤 변화도 영구적이며 취소 불가능
합니다. 텍스쳐파일의 픽셀을 수정하면 그 변화는 영구적입니다.
절차에 맞게 메쉬 기하(Mesh Geometry) 생성하기
Mesh 클래스는 런타임에 메쉬를 생성하고 수정하는 객체의 메쉬 기하에게 스크립트 접근을 가능하게 합니다. 이 기술은 그래픽
효과(객체 늘리기와 줄이기)를 주는데 유용합니다. 또한 단계 디자인과 최적화에도 유용합니다. 다음 섹션에서는 API 와 예제를
살펴봄과 함께 어떻게 메쉬가 형성되는지에 대한 자세한 내용을 설명합니다.
•
메쉬의 구조
•
메쉬 클래스 사용하기
•
예: 빌보드 평면 만들기
메쉬(Mesh)의 구조
메쉬(mesh)는 고체의 효과를 만들어 내기위해 3D 공간에 놓여있는 삼각형들로 이루저져 있습니다. 하나의 삼각형은 그 삼각형의 세
모서리의 점들 또는 꼭지점으로 정의 되어 집니다. 메쉬 클래스에서 그 꼭지점들은 모두 하나의 배열(array)에 저장되어 있으며 각
삼각형은 꼭지점 배열의 인덱스에 해당하는 세개의 정수를 이용하여 지정되어 집니다. 삼각형들은 하나의 정수 배열에 함께
저장되며 그 정수들은 배열을 시작으로 부터 세개씩 그룹지어지게 됩니다. 그래서 요소 0,1,2 는 첫번째 삼각형을, 요소 3,4,5 는
두번째 삼각형을 정의하는 식이 됩니다. 어떤 주어진 꼭지점도 여러 삼각형에서 재사용 될 수 있으나 아래에 왜 이것이 좋지
않으지를 설명해줍니다.
빛(Lighting) 과 법선(Normals)
삼각형들은 물체의 기본 모형을 정의하는데 충분하지만 대부분의 경우 메쉬를 보여주기 위해서는 추가 정보가 필요로 합니다.
물체가 빛에 정확히 그림져지기 위해서는 각 벡터에 법선 벡터(normal vector)가 주어져야 합니다. 법선(normal)은 연관된 꼭지점의
위치에서 메쉬의 표면에서 직각이고 바깥쪽을 향하는 벡터를 말합니다. 그림자 계산 중에 각 꼭지점에서의 법선 벡터는 또 다른
벡터인 들어오는 빛의 방향과 비교되어 집니다. 이 두 벡터가 완벽하게 평행이면 그 표면은 빛을 정면(head-on)으로 받게되어 빛의
최대 밝기가 그림자를 형성하는 것에 사용되어집니다. 그 법선 벡터에 평행(side-on)으로 들어오는 빛은 그 표면에 아무런 조명을
주지 못하게 됩니다. 보통 빛은 그 법선 벡터에 하나의 각도로 도착하게 되며 그림자 형성은 각도에 따라 최대 밝기나 완전한
어둠사이에서 이루어게 됩니다.
메쉬는 삼각형들로 이루어져 있기때문에 모서리의 법선들이 단순히 삼각형의 평면에 수직이라 보여질 수 있습니다. 하지만 사실
모서리 사이의 중간 지점들의 표면에 방향을 주기위해 법선들은 삼각형 전반에 걸쳐 삽입되어 있습니다. 만약 세개의 모든 법선들이
같은 방향을 가리키고 있다면 그 삼각형은 균일하게 빛이 조명되어 질 것입니다. 균일하게 그림자가 형성된 다른 삼각형들이 가지는
효과는 변(edge)에서 매우 뚜렷하고 분명하게 될 것이라는 것입니다. 이것이 정확하게 정육면체 모델이나 아주 날카로운 변을 가진
물체들에게 필요한 것이지만 법선의 삽입은 곡선의 표면을 나타내주기 위해 부드러운 그림자 형성을 위해 사용되어 질 수 있습니다.
근접한 두 삼각형은 모두 그들의 각자의 법선을 필요로 할 것이기 때문에 뚜렷한 변을 나타내기 위해서는 각 변의 꼭지점을 구부릴
필요가 있습니다. 곡선 표면에서는 꼭지점이 변을 따라서 공유될 것이지만 공유된 법선의 최적의 방향을 정하기 위해서는 약간의
직관이 필요로 합니다. 하나의 법선은 단순히 둘러쌓고 있는 삼각형 평면 법선들의 평균일 수 있습니다. 하지만 구와 같은 물체에선
법선들은 단순히 구의 중심에서 바깥쪽을 향하게 됩니다.
Mesh.RecalculateNormals 을 불러줌으로써 사용자가 메쉬 기하학의 의미에 대한 가정들을 만들므로써 Unity 가 법선의 방향을
계산하게 할 수 있습니다. 그 가정들은 삼각형들 사이에서 공유되는 꼭지점들은 부드러운 표면을 가리키는 반면 구부러진
꼭지점들은 뚜렷한 변을 나타냅니다.
대부분의 경우 이것은 나쁜 추정법은 아닌 반면 RecalculateNormals 은 표면이 부드러워도 꼭지점들이 접혀야하는
텍스쳐링(texturing)인 상황에 의해 오류를 범할수도 있습니다
텍스처링(Texturing)
모델은더불어 물체의 상세한 표면을 만들기위해 빛뿐 아니라 텍스처링을 사용할 것입니다. 텍스처(texture)는 늘어나는 고무판에
그려져 있는 이미지라고 할 수 있습니다. 각 메쉬 삼각형에는 텍스쳐 이미지의 삼각형 영역이 정의 되어있고 그 텍스쳐 삼각형은 그
메쉬 삼각형에 맞춰지기 위해 늘려져 고정(“pinned”)되어 있습니다. 이렇게 하기 위해서는 각 꼭지점은 그 메쉬 삼각형에 고정될 그
이미지의 위치 좌표를 저장해야 합니다. 이 좌표는 2D 이며 0 부터 1 까지의 범위를 가집니다.(0 은 이미지의 왼쪽아래 부분을, 1 은
오른쪽 윗부분을 나타냅니다.) 3D 에서의 직교 좌표(Cartesian coordinates)와의 혼동을 피하기위해 이 좌표를 익숙한 X 와 Y 보단
U 와 V 로 나타내며 이것을 흔히 UV 좌표라 부릅니다.
텍스쳐 좌표는 법선처럼 각 꼭지점에서 고유하기 때문에 하나의 변에서 다른 UV 값을 가지기위해 꼭지점을 구부릴 경우도 있습니다.
두개의 인접한 삼각형에서 텍스쳐 이미지(말하자면 얼굴 텍스쳐에서 눈)의 연속되지 않은 부분을 사용하는 것이 하나의 명확한
예제입니다. 또한 대부분의 부피를 포함하는 물체들은 텍스쳐들이 둘러싸고 서로 연계되어있는 seam 을 필요로 합니다. Seam 의 한
측면의 UV 값은 다른 측면의 값과 다를 것입니다.
Using the Mesh Class
메쉬 클래스는 객체의 메쉬 기하의 기본 스크립트 인터페이스입니다. 이것은 꼭지점, 삼각형, 법선 그리고 텍스쳐 좌표를 나타내주기
위해 배열을 사용하며 몇가지 다른 유용한 속성과 메쉬 생성을 도와줄 함수들을 제공합니다.
Accessing an Object's Mesh
메쉬 데이타는 메쉬 필터 컴포넌트(그리고 그 객체는 또한 기하를 시각화하기 위해 메쉬 렌더러를 필요로 합니다)를 사용하는 객체에
첨부가 됩니다. 이 컴포넌트는 익숙한 GetComponent 함수를 사용하여 접근 가능합니다:var mf: MeshFilter = GetComponent(MeshFilter);
// Use mf.mesh to refer to the mesh itself.
Adding the Mesh Data
메쉬 객체는 꼭지점과 그 관련 데이터(법선 그리고 UV 좌표)와 삼각형 데이터를 위한 속성을 가집니다. 꼭지점은 어떤 순서로도
제공될 수 있지만 법선과 UV 의 배열은 순서가 있어서 인덱스가 각 꼭지점과 상응하도록 해야합니다(예를 들어 법선 배열의 요소
0 은 꼭지점 0 의 법선을 제공합니다). 꼭지점은 객체의 로컬 공간의 점들을 나타내는 Vector3s 입니다. 법선은 방향과 로컬 좌표를
나타내는 법선화된 Vector3s 입니다. UV 는 Vector2s 로 나타내지만 Vector2 타입이 U 와 V 라 불리는 필드를 가지지 않으므로
사용자는 마음속으로 그것을 각각 X 와 Y 로 변환합니다.
삼각형은 꼭지점 배열에서 인덱스처럼 동작하는 세개의 정수를 나타냅니다. 삼각형을 표현하기 위해 특별한 클래스를 사용하기
보다는 그 배열은 단순히 정수 인덱스의 리스트입니다. 이것은 각 삼각형을 위해 세개씩 그룹져 있으며 그래서 첫 세개의 요소가
첫번째 삼각형을 정의합니다. 그리고 다음 세개가 다음 삼각형을 정의합니다. 삼각형의 중요한 세부 사항은 구석에 위치한 꼭지점의
순서입니다. 그것은 정렬되어야 하는데 그래서 사용자가 삼각형의 바깥 표면을 보았을 때 각 구석이 시계방향으로 돌수 있도록
되어야 합니다. 어느 구석에서 시작하는지는 중요하지 않습니다.
예: Billboard 평면 생성하기
유니티는 평면 원시 객체를 가지고 있는데 이것은 2D 게임이나 GUI 에 유용한 간단한 평면이며 어쨌든 좋은 예의 시작입니다.
최소한의 평면은 두개의 삼각형으로 각 구석을 정의하는 네개의 꼭지점으로 이루어져 있습니다.
첫째로 꼭지점 배열을 설정합니다. 평면은 XY 축에 있고 넓이와 높이는 파라미터로 정해진다고 가정합니다. 꼭지점의 순서는 왼쪽
아래, 오른쪽 아래, 왼쪽 위, 오른쪽 위의 순서로 제공합니다.
var vertices: Vector3[] = new Vector3[4];
vertices[0] = new Vector3(0, 0, 0);
vertices[1] = new Vector3(width, 0, 0);
vertices[2] = new Vector3(0, height, 0);
vertices[3] = new Vector3(width, height, 0);
mesh.vertices = vertices;
(메쉬 데이터 속성은 씬 뒤에서 코드를 실행시키므로 데이터를 사용자 자신의 배열에 설정하고 이것을 속성에 할당하는 것이 속성을
배열의 요소별로 접근하는 것보다 효율 적입니다.)
다음은 삼각형 입니다. 두 개의 삼각형을 원하므로 각 삼각형은 세 개의 정수로 정의되며 삼각형 배열은 총 여섯개의 요소를
가집니다. 각 구석을 시계 방향으로 정의하는 것을 생각 했을 때, 왼쪽 아래 삼각형은 0, 2, 1 을, 오른쪽 위 삼각형은 2, 3, 1 을 코너
색인으로 사용합니다.
var tri: int[] = new int[6];
//
Lower left triangle.
tri[0] = 0;
tri[1] = 2;
tri[2] = 1;
//
Upper right triangle.
tri[3] = 2;
tri[4] = 3;
tri[5] = 1;
mesh.triangles = tri;
꼭지점과 삼각형으로만 이루어진 메쉬는 에디터에 보이긴하지만 설득력이 있지만 않습니다. 왜냐하면 법선없이 정확히
그림자지워지지 않기 때문입니다. 평면의 법선은 매우 간단한데 모두 같고 평면의 로컬 스페이스에서 Z 의 음방향을 가리킵니다.
법선이 추가되면서 평면은 정확히 그림자를 만들지만 화면에서 효과를 보기 위해서는 빛이 필요합니다.
var normals: Vector3[] = new Vector3[4];
normals[0] = -Vector3.forward;
normals[1] = -Vector3.forward;
normals[2] = -Vector3.forward;
normals[3] = -Vector3.forward;
mesh.normals = normals;
마지막으로, 텍스쳐 좌표를 메쉬에 추가하는 것은 재료를 정확히 나타내는 것을 가능하게 합니다. 이미지 전체를 평면에 걸쳐
보여주고 싶다고 가정한다면 텍스쳐의 코너에 따라 UV 값은 모두 0 또는 1 이 될것입니다.
var uv: Vector2[] = new Vector2[4];
uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(1, 0);
uv[2] = new Vector2(0, 1);
uv[3] = new Vector2(1, 1);
mesh.uv = uv;
완성된 스크립은 아래와 같을 것입니다:var width: float;
var height: float;
function Start() {
var mf: MeshFilter = GetComponent(MeshFilter);
var mesh = new Mesh();
mf.mesh = mesh;
var vertices: Vector3[] = new Vector3[4];
vertices[0] = new Vector3(0, 0, 0);
vertices[1] = new Vector3(width, 0, 0);
vertices[2] = new Vector3(0, height, 0);
vertices[3] = new Vector3(width, height, 0);
mesh.vertices = vertices;
var tri: int[] = new int[6];
tri[0] = 0;
tri[1] = 2;
tri[2] = 1;
tri[3] = 2;
tri[4] = 3;
tri[5] = 1;
mesh.triangles = tri;
var normals: Vector3[] = new Vector3[4];
normals[0] = -Vector3.forward;
normals[1] = -Vector3.forward;
normals[2] = -Vector3.forward;
normals[3] = -Vector3.forward;
mesh.normals = normals;
var uv: Vector2[] = new Vector2[4];
uv[0] = new Vector2(0, 0);
uv[1] = new Vector2(1, 0);
uv[2] = new Vector2(0, 1);
uv[3] = new Vector2(1, 1);
mesh.uv = uv;
}
코드가 Start 함수에서 한 번 실행이되면 메쉬는 게임 동안 계속 같은 상태를 유지합니다. 그러나 Update 함수에 코드를
추가함으로써 프레임마다 메쉬를 바꾸는 것이 가능합니다(이것은 CPU 오버헤드를 상당히 높힙니다).
Execution Order
Unity 스크립팅에서 스크립트가 실행되는 것처럼 미리 정해진 순서대로 실행되는 많은 이벤트 함수가 있습니다. 이 실행 순서는
아래에서 설명됩니다:
First Scene Load
이러한 함수는 씬이 시작될 때 불려집니다 (씬에서 각 물체를 위해서 한 번).
•
Awake: 이 함수는 모든 시작 함수전에 불려지고 prefab 이 객체화된 후에 불려집니다.
•
OnEnable: (물체가 활성화될 때만 불려집니다) : 이 함수는 물체가 활성화된 후에 불려집니다.
Before the first frame update
•
Start: 스크립트 인스턴스가 활성화될 때만 첫 번째 프레임 업데이트 전에 Start 가 불려집니다.
Update Order
사용자가 게임 로직과 상호 작용, 애니메이션, 카메라 위치 등을 계속 트랙할 때 사용자가 사용할 수 있는 몇 가지 다른 이벤트가
있습니다. 공통적인 패턴은 Update()함수에서 대부분의 태스크를 실행한다는 것입니다. 그러나 사용자가 사용할 수 있는 다른
함수들도 있습니다.
•
FixedUpdate: FixedUpdate()은 Update()보다 더 자주 불려집니다. 프레임 레이트가 낮으면 프레임마다 여러번 불려질 수 있고
프레임 레이트가 높다면 프레임 사이에서 한 번도 불려지지 않을 지도 모릅니다. 모든 물리적인 계산과 업데이트는 FixedUpdate()
이후에 직접적으로 일어납니다. FixedUpdate() 내부로 움직임 계산이 적용될 때, 사용자는 Time.deltaTime 에 의하여 사용자의
값을 곱할 필요가 없습니다. 이것은 FixedUpdate()가 신뢰있는 타이머에서 불려지고 프레임 레이트에 독립적이기 때문입니다.
•
Update: Update()는 프레임마다 한 번 불려집니다. 그것은 프레임 업데이트를 위한 주요 함수 입니다.
•
LateUpdate: LateUpdate()는 Update()가 끝난 후에 프레임마다 한 번 불려집니다. Update()에서 수행되는 모든 계산은
LateUpdate()이 시작할 때 끝날 것입니다. LateUpdate()를 위한 공통적인 사용은 다음의 3 인칭 카메라일 것입니다. 사용자가
사용자의 캐릭터를 움직이고 Update() 내부에서 돌게 한다면 사용자는 모든 카메라 움직임과 회전 계산을 LateUpdate()에서
수행할 수 있습니다. 이것은 캐릭터가 카메라가 그것의 위치를 트랙하기 전에 완전히 움직인다는 것을 확실시 할 것입니다.
Rendering
•
OnPreCull: 카메라가 씬을 추려내기 전에 불려집니다. Culling 은 어떤 물체가 카메라에 보일지를 결정합니다. Culling 일 일어나기
전에 OnPreCull 이 불려집니다.
•
OnBecameVisible/OnBecameInvisible: 물체가 카메라에 보이거나/보이지 않게 될 때 불려집니다.
•
OnWillRenderObject: 물체가 보이면 각 카메라를 위해서 한 번 불려집니다.
•
OnPreRender: 카메라가 씬을 렌더링하는 것을 시작하기 전에 불려집니다.
•
OnRenderObject: 모든 보통 씬 렌더링이 끝난 후에 불려집니다. 사용자는 이 시점에 사용자 정의 기하를 그리기 위해 GL 클래스
또는 Graphics.DrawMeshNow 를 사용할 수 있습니다.
•
OnPostRender: 카메라가 씬을 렌더링하는 것을 끝낸 후에 불려집니다.
•
OnRenderImage(Pro only): 스크린 이미지의 포스트 프로세싱을 허용하기 위해서 씬 렌더링이 완전해진 후에 불려집니다.
•
OnGUI: GUI 이벤트에 대한 응답으로서 프레임당 여러번 불려집니다. 각 입력 이벤트를 위한 레이아웃과 키보드/마우스 이벤트에
의해 따라오는 레이아웃과 다시 그리기 이벤트는 처음에 프로세스 됩니다
•
OnDrawGizmos 시각화 목적으로 씬 뷰에서 기즈모를 그리기 위해 사용됩니다
Coroutine
보통의 coroutine 업데이트는 업데이트 함수가 리턴한 후에 실행됩니다. Coroutine 은 주어진 YieldInstruction 가 끝낼 때까지 그것의
실행을 중지할 수 있는 함수입니다. Coroutines 의 다른 사용은 다음과 같습니다:
•
yield; Coroutine 는 다음 프레임에서 부려지는 모든 업데이트 함수가 불려진 후에 계속될 것입니다.
•
yield WaitForSeconds(2); 프레임을 위해 모든 업데이트 함수가 불려진 후에 지정된 시간 지연 후에 계속됩니다
•
yield WaitForFixedUpdate();모든 FixedUpdate 가 모든 스크립트에서 불려진 후에 계속됩니다
•
yield WWW WWW 다운로드가 완료된 후에 계속됩니다.
•
yield StartCoroutine(MyFunc); Coroutine 을 연결하고 첫 번째로 MyFunc coroutine 를 완료하기를 기다릴 것입니다.
When Quitting
이러한 함수들은 사용자의 씬에서 모든 활동적인 물체위에서 불려집니다, :
•
OnApplicationQuit: 이 함수는 어플리케이션이 죵료하기 전에 모든 게임 물체위에서 불려집니다. 편집기에서 사용자가 플레이
모드를 멈출 때 불려집니다. 웹 플레이어에서 웹 뷰가 닫힐 때 불려집니다.
•
OnDisable: 이 함수는 행동이 비활성화될 때 불려집니다.
So in conclusion, this is the execution order for any given script:
•
모든 Awake calls
•
모든 Start Calls
•
while (변수 델타 타임을 위한 단계)
o
모든 FixedUpdate 함수들
o
Physics simulation
o
OnEnter/Exit/Stay trigger 함수들
o
OnEnter/Exit/Stay collision 함수들
•
Rigidbody 보간은 transform.position 과 회전을 적용합니다
•
OnMouseDown/OnMouseUp 등의 이벤트
•
모든 Update 함수들
•
애니메이션은 발전하고 블렌드되고 transform 에 적용됩니다
•
모든 LateUpdate 함수들
•
Rendering
Hints
•
사용자가 LateUpdate 에서 coroutine 을 시작한다면 그것은 렌더링 바로 전에 LateUpdate 후에 불려질 것입니다.
•
Coroutines 은 모든 업데이트 함수 이후에 실행됩니다.
그래픽 성능 최적화
Desktop
게임이 끊김 없이 부드럽게 동작하는 것은 게임의 성공 여부에 매우 중요 합니다. 유니티가 이를 위해 존재합니다. 저희들은 다양한
하드웨어에 유니티 iOS 가 빨리 동작하도록 많은 시간과 노력을 기울였습니다. 아래에는 게임의 스피드를 최대화 하기 위한 몇몇
간단 한 안내서를 소개합니다.
줄여서 얘기하면 – 통합(combine), 통합, 통합
•
성능을 신경 쓰신다면, 메쉬들을 통합하세요.
•
성능을 신경 쓰신다면, 통합된 메쉬들이 같은 재료(material)와 질감을 공유하도록 확인하세요.
•
Profiler 와 Rendering Statistics 창이 유용할 것입니다!
자세히 살펴보면:
현대의 그래픽 카드들은 많은 다각형을 표현해 내는데 익숙하지만, 그래픽 카드에 모든 일괄처리(batch)들은 많은 과부하를 야기
합니다. 만약, 100 개의 삼각형 오브젝트가 있는 것은 1500 개의 삼각형을 표현해 내는 것만큼 많은 성능 소모가 일어 납니다. 최적의
표현 성능을 내는 이상적인 장소는 메쉬당 1500-4000 개의 삼각형입니다.
Mesh Renderer 가 부탁된 오브젝트들을 표현하는 것은 성능의 일정한 대가를 치러야 합니다. 보기 절두체(view frustum)내에서 그
대가를 치릅니다. 장면(scene)내에서 빈 GameObjects 들을 많이 가지고 있는 것은 표현 비용이 없습니다.
•
표현 성능을 향상 시키는 가장 좋은 방법은 오브젝트들을 결합해서 각 메쉬가 1500 개 또는 더 이상의 오브젝트를 가지고, 전체
메쉬를 위해 하나의 Material 를 사용하는 것입니다.
재료를 공유하지 않는 두개의 오브젝트들을 결합하는 것은 성능의 부하를 주지 않는다는 것을 이해해야 합니다. 효율적으로
결합하려면, 메쉬가 통합 후에 하나의 재료를 쓴다는 것을 확인하시기 바랍니다.
오브젝트들을 결합 할 때 한가지는 알아야 합니다. 장면에 많은 조그마한 빛들을 사용하면, 근접한 오브젝트들을 결합 하는 것이 더
합리적입니다.
많은 재료를 가지는 메쉬를 표현하는 비용은, 각 재료로 다수의 렌더러(renderer)를 가지는 것과 같은 비용 입니다. 다수의 재료들을
가지는 가장 보편화된 이유는 두 개의 메쉬들은 같은 질감들을 공유하지 않습니다. 표현 성능을 최적화 시키려면, 통합하는
오브젝트들이 같은 질감을 공유하도록 하셔야 합니다.
•
유니티는 많은 다각형을 밀어 표현 하는것에 강점이 있습니다. 유니티는 모든 기하를 그래픽 카드로 업로드 하는데, 이는 좋은
캐쉬(cache) 효율과 최적화된 데이터 배열을 위함입니다.
•
단지 그래픽 카드는 많은 수의 일괄처리를 다룰 필요가 없음을 확인해야 합니다.
•
전면 렌더링 통로 Forward rendering path 를 사용하면, 오브젝트에 영향을 주는 Pixel Lights 의 개수는 성능에 많은 영향을 준다.
전면 렌더링 통로에서의 픽셀 불빛들
주의: 이는 오직 전면 렌더링 통로 Forward rendering path 에서만 적용이 됩니다.
픽셀 불빛을 사용하면, 각각의 GameObject 는 오브젝트에 영향을 주는 픽셀 불빛의 갯수 만큼 표현되어야 합니다. 멀리 떨어져 있는
두 오브젝트를 결합하면, 오브젝트의 크기가 증가할 것이고, 이 큰 오브젝트에 영향을 주는 많은 물빛들을 가지게 될 것입니다.
오브젝트들이 분리되어있으면, 멀리 떨어진 메쉬의 부분에 빛들이 적용될 필요는 없습니다.이는 통합된 메쉬를 표현하는데
통합되지 않는 메쉬(따라서 아무것도 저장하지 않는) 의 개수 만큼 표현하는 결과가 생깁니다. 이런 이유로, 멀리 떨어진
GameObjects 들을 각각의 메쉬들로 보존해야 합니다.
메쉬를 표현할때, 유니티는 메쉬 주위의 모든 불빛을 찾습니다. 그리고, 어떤 빛들이 메쉬에 가장 영향을 미치는지 알아냅니다.
QualitySettings 은 얼마나 많은 빛이 픽셀 빛과 정점 (vertex) 빛으로 도래되는지를 변경할 때 사용합니다.
모든 빛들은 메쉬로부터 얼마나 떨어지고, 얼마나 강도가 있는지에 기반하여 중요성을 계산합니다.
어떤 빛들은 다른 빛들보다 게임의 맥락에서 더 중요합니다. 이러한 이유로, 모든 빛은 Render Mode 설정을 가집니다. 이 설정은
Important 와 Not Important 로 나눠집니다.
헤드 라이트를 가진 게이머의 차가 밤에 운전하는 것을 상상해 보십시오. 헤드 라이트들은 게임에서 가장 중요한 불빛들입니다.
이러한 이유로, 헤드라이트의 렌더 상태는 Important 로 설정되어야 합니다.
별로 중요하지 않는 불빛을 가지고, 픽셀 빛으로부터 시각적으로 얻는 것이 없다면 렌더 상태는 Not Important 로 설정합니다. 이런
방식으로 렌더링 성능이나 시각적 성능을 낭비하지 않습니다.
레이어당 누락 거리
그리기 호출의 개수를 줄이기 위해 작은 오브젝트들을 누락시키고 싶을 때가 있습니다. 예를 들어, 조그만 바위나 잔재는 커다란
빌딩보다 작은 거리에서는 보이지 않습니다. 이를 위해서는, 작은 오브젝트들을 분리된 레이어에 놓고, 레이어당
누락거리를 Camera.layerCullDistances 스크립트 함수를 사용하여 설정하십시오.
그림자들
데스크톱 플랫폼에서 배치한다면, 그림자들에 신경을 써야 합니다. 그림자들은 일반적으로 (성능상의)비용이 많이 듭니다.
그림자들이 정확하게 사용되지 않으면 게임의 성능에 많은 부하를 줍니다. 그림자들에 대한 더 많은 정보는 Shadows page 를
읽으시길 바랍니다.
주의: 그림자들은 현재 iOS 나 Android 디바이스들에는 지원되지 않습니다.
더 살펴보기
•
최적화된 캐릭터 모델링
•
렌더링 통계
iOS
iOS 를 위해서 컨텐트의 최적화를 원한다면 learn more about iOS hardware devices 페이지를 참조 하십시오.
알파 테스팅
데스크톱과는 반대로, 알파테스팅 (또는 픽셀 쉐이더에서 discard$ / clip$$ 연산)은 iOS 에서 성능상 비용이 많이 듭니다. 알파
테스트 쉐이더를 알파 블렌드로 교체를 원하시면, 그렇게 하십시오. 알파 테스트가 정말 필요하시면, 보이는 알파 테스트 픽셀
지역을 최소로 유지 시키십시오.
정점 성능
일반적으로 iPhone 3GS 나 새로운 디바이스들을 타겟으로 할때, 프레임당 40K 나 더 적은 정점을 목표로 합니다. MBX GPU 가
장착된 iPhone, iPhone 3G, 1 세대 2 세대 iPod Touch 경우 프레임당 10K 나 더 적은 정점을 목표로 합니다.
라이팅 성능
픽셀당 동적 라이팅(lighting)은 모든 영향 받는 픽셀에 중요한 비용이 추가 되고, 다중 패스들에 렌더링 오브젝트들을 이끌 수
있습니다. 하나의 오브젝트에 영향을 주는 하나의 Pixel Light 보다 픽셀 라이트를 더 가지는 것을 피하시고, 방향성 빛을 선호하시길
바랍니다. Pixel Light 는 Render Mode 설정이 Important 로 설정되어 있음을 명심하시기 바랍니다.
정점당 동적 라이팅은 정점 변환에 많은 비용이 더 추가 됩니다. 하나의 오브젝트에 영향을 줄때는 다중 불빛을 피하시기 바랍니다.
정적 오브젝트들을 위해서는 베이크 라이팅 (bake lighting)을 사용하십시오.
모델 기하 최적화
모델 기하를 최적화 할 때, 두 가지 기초 룰이 있습니다:
•
필요하지 않다면, 더 많은 추가 면을 사용하지 마세요.
•
UV 매핑솔기(seam)의 수를 유지하고, 하드 모서리(hard edge)를 가능한 적게 하십시오.
그래픽 하드웨어가 프로세싱하는 실질적인 정점의 개수는 3D 어플리케이션에 표시되는 것과는 같지 않습니다. 모델링
어플리케이션들은 모델을 이루는 포인트들, 즉 기하 정점 카운트를 표시합니다.
그래픽 카드들은, 몇몇 정점들은 구분 되어야 합니다. 정점이 다중의 법선(normal)들 (하드 모서리 위에서) 을 가지거나, 다중의 UV
좌표를 가지거나, 다중의 꼭지점 색상을 가지면, 이는 분리되어야 합니다. Unity 에서 보는 정점의 숫자는 3D 어플리케이션에서 진열
되는 것과 항상 다릅니다.
질감 압축
iOS 의 네이티브 PVRT compression formats 압축 포맷을 사용하십시오. 질감의 사이즈를 감소시킬 뿐만 아니라(더 빠른 불러오기
시간과 더 작은 메모리 사용), 렌더링의 성능을 증가 시킵니다. 압축된 질감은 32bit RGBA 에 비교해서 메모리 대역폭의 아주
일부분만 필요합니다. 성능 비교를 위해서는 iOS Hardware Guide 를 참조하십시오.
몇몇 이미지는 PVRT 압축 질감의 알파 채널에서 시각적 조형물로 되기 싶습니다. 그런 경우 이미지 소프트웨어에 PVRT 압축
변수들의 직접적인 변경을 원할 수 있습니다. PVRT 포맷을 만든 Imagination Tech의 PVRTexTool을 사용하여 PVR export
plugin을 설치해서 직접적인 변경이 가능합니다. ..pvr확장을 가진 압축 이미지는 유니티 에디터에 가져오기 될 것이며, 수동으로
설정된 압축 변수들은 보존 될 것입니다.
PVRT 압축 포맷이 충분한 시각적 질을 전달하지 않는다면, UI 질감과 같은 추가의 이미지 작업이 필요합니다. 이 경우 32bit RGBA
질감대신 16bit 질감의 사용을 고려해야 합니다. 최소한, 메모리 대역폭이 반으로 줄 것입니다.
성능 좋은 쉐이더를 작성하기 위한 팁들
iPhone3GS 이후로 GPU 들은 픽셀과 정점 쉐이더(shader)들을 충분히 지원하지만, 복잡한 픽셀당 기능을 가진 데스코톱 쉐이더의
성능과 초당 30 프레임들을 동작하는 iOS 디바이스의 성능을 추월하는 기대는 하면 안됩니다. 대부분 쉐이더 들은 편리하게 최적화
되어있고, 연산과 질감은 좋은 프레임 비율을 달성하기 위해서는 최소화 하여야 합니다.
복잡한 수식 연산들
수식 연산들(pow,, exp, log, cos, sin, tan)은 GPU 에 많은 부하를 줍니다. 최고의 방법은 부분당(per fragment) 하나의 연산 이상을
가지지 않는 것입니다. 때로는 질감 찾기(lookup)가 더 좋은 대안입니다.
자신만의 규격화된 normalize, dot, inversesqrt 사용을 회피하십시오. 항상 내장되어있는 연산들을 사용하십시오. 이것이 더 좋은
코드를 생성할 것입니다.
Disscard 연산은 부분들(fragments)을 느리게 만들것입니다.
부동소수 연산들
사용자 쉐이더들을 작성할 때 부동 소수 변수들의 소수점 자리를 명시하십시오. 좋은 성능을 위해서는 작은 포맷이 더 중요하다는
것은 매우 중요합니다.
쉐이더가 GLSL ES 로 쓰여지면, 소수점 자리는 다음과 같습니다:
•
highp - full 32 비트의 부동소수 포맷입니다. 정점변환에 적합하지만 가장 느립니다
•
mediump - 16 비트의 부동소수 포맷입니다. 질감 UV 좌표에 적합합니다. 대략 highp 보다 x2 빠릅니다.
•
lowp - 비트의 부동소수 포맷입니다. 색상과 빛 연산, 그리고 고성능 연산에 적합합니다. highp 보다는 __x4 배 정도 빠릅니다.
쉐이더가 GG 또는 표면 쉐이더로 쓰여지면, 소수점은 다음과 같습니다:
•
float - - GLSL ES 에서 highp 와 유사, 가장 느림
•
half - GLSL ES 에서 mediump 와 유사, float 보다 _x2__ 빠름
•
fixed - GLSL ES 에서 lowp 와 유사, float 보다 4x4 빠름
일반적인 쉐이더 성능을 알아보시려면 Shader Performance page 페이지를 참조하세요.
하드웨어 문서
Apple hardware 문서를 공부하고 쉐이더를 작성best practices for writing shaders하는데 시간을 가지시길 바랍니다. 부동 소수점의
힌트를 더 공격적으로 사용하길 권유합니다.
Lightmaps 으로의 Bake Lighting
정적 라이팅의 장면을 Unity 내의 내장된 Lightmapper 를 사용해서 베이크(bake)하십시오. lightmapped 환경을 생성하는 과정은
Unity 에서 장면에 빛을 배치하는 것보다 더 시간이 걸립니다. ¬¬그러나:
•
더 많이 빠릅니다 (2-3 배, 2 픽셀 라이트)
•
더 좋게 보입니다. 왜냐하면, 전체적 조명을 베이크 할수 있고, lightmapper 는 결과들을 부드럽게 할 수 있습니다
재료들 공유
다수의 오브젝트들이 같은 카메라로 표현되면, 유니티 iOS 는 더 다양한 내부적 최적화를 할 수 있을 것입니다. 예:
•
다양한 렌더 상태들을 OpenGL ES 로 하는 것을 피함.
•
정점과 픽셀 프로세싱에 필요한 다양한 종류의 변수들 연산을 피함
•
그리기(draw)호출들의 감소를 위한 작은 오브젝트들의 일괄처리
•
그리기 호출을 줄이기 위한 정적 속성을 가능하게 하는 크고 작은 오브젝트들의 일괄 처리
모든 이런 최적화들은 CPU 사이클들을 줄여줄 것입니다. 그러므로, 질감들을 하나의 지도로 합하고 같은 재료(material)을 사용하기
위한 다수의 오브젝트를 만드는 것은 비용을 줄이므로, 권유합니다!
게임을 빠르게 하기 위한 간단한 체크리스트
•
정점 카운트를 아래로 유지하세요:
o
iPhone 3GS 와 더 최신의 디바이스를 타겟으로 할때는 프레임당 40K 를 하세요 (SGX GPU 를 사용).
o
더 오래된 디바이스들은 프레임당 10K 로 하세요 (MBX GPU 를 사용)
•
내장 쉐이더를 사용한다면, Mobile 카테고리를 살펴보세요. Mobile/VertexLit 는 현재 가장 빠른 쉐이더입니다.
•
장면당 다른 재료(material)의 개수를 낮게 유지하세요- 가능하면 다른 오브젝트들 사이에서 더 많은 재료를 공유하세요.
•
내부 최적화를 위해서 움직이지 않는 오브젝트들에게 Static 속성을 설정하세요.
•
가능한 질감들을 위해서는 PVRTC 포맷을 사용하세요. 아니면, 32bit 대신 16bit 질감을 선택하세요.
•
통합기(combiners)또는 픽셀 쉐이더를 사용하세요. 이는 다중 패스 접근법 대신에 부분당 몇몇 질감을 혼합하기 위함입니다.
•
사용자 설정 쉐이더를 작성시에는, 항상 가장 작은 부동 소수점을 사용하세요:
o
fixed / lowp -- 칼라와 라이팅 정보, 법선들을 위해서는 완벽합니다,
o
half / mediump -- 질감 UV 좌표들을 위해서 쓰입니다,
o
float / highp -- 픽셀 쉐이더에서는 피합니다. 정점 쉐이더에서 정점 위치 계산을 위한 사용에 괜찮습니다.
•
픽셀 쉐이더에서 복잡한 수식 연산(pow, sin, cos 등)을 최소화 합니다.
•
필요하지 않으면 Pixel Lights 는 쓰지 않습니다. – 기하에 영향을 주는 (가능한 방향성의) 하나의 픽셀 라이트를 선택하세요.
•
필요하지 않으면 동적 라이트를 사용하지 않습니다 – 베이크 라이트를 대신 선택하세요.
•
부분당 (per fragment) 더 작은 질감을 사용하세요.
•
알파 테스팅을 피하세요. 알파 블렌딩(alpha-blending)을 대신 사용하세요.
•
필요하지 않으면 안개를 사용하지 마세요.
•
폐색 누락(Occlusion culling) 의 장점을 알아보시고, 복잡한 정적 장면에 많은 폐색이 있을 시에는 가시 기하와 그리기 호출의 양을
줄이기 위해서 사용하세요. 폐색 누락으로부터 어떤 이득의 단계를 얻을 것인지 계획하세요.
•
원거리 기하를 “위장(fake)” 위해서는 스카이박스(skybox)들을 사용하세요.
더 살펴보기
•
iOS 성능 최적화 Optimizing iOS Performance
•
iOS 하드웨어 안내 iOS Hardware Guide
•
iOS 자동 그리기 호출 일괄처리 iOS Automatic Draw Call Batching
•
최적화 캐릭터들의 모델링 Modeling Optimized Characters
•
렌더링 통계 Rendering Statistics
Android
라이팅 성능
픽셀당 동적 라이팅(lighting)은 모든 영향 받는 픽셀에 중요한 비용이 추가 되고, 다중 패스들에 렌더링 오브젝트들을 이끌 수
있습니다. 하나의 오브젝트에 영향을 주는 하나의 픽셀 라이트 보다 Pixel Light 를 더 가지는 것을 피하시고, 방향성 빛을
선호하시길 바랍니다. Pixel Light 는 Render Mode 설정이 Important 로 설정되어 있음을 명심하시기 바랍니다.
정점당 동적 라이팅은 정점 변환에 많은 비용이 더 추가 됩니다. 하나의 오브젝트에 영향을 줄때는 다중 불빛을 피하시기 바랍니다.
정적 오브젝트들을 위해서는 베이크 라이팅 (bake lighting)을 사용하십시오.
모델 기하 최적화
모델 기하를 최적화 할 때, 두 가지 기초 룰이 있습니다:
•
필요하지 않다면, 더 많은 추가 면을 사용하지 마세요
•
UV 매핑솔기(seam)의 수를 유지하고, 하드 모서리(hard edge)를 가능한 적게 하십시오
그래픽 하드웨어가 프로세싱하는 실질적인 정점의 개수는 3D 어플리케이션에 표시되는 것과는 같지 않습니다. 모델링
어플리케이션들은 모델을 이루는 포인트들, 즉 기하 정점 카운트를 표시합니다.
그래픽 카드들은, 몇몇 정점들은 구분 되어야 합니다. 정점이 다중의 법선(normal)들 (하드 모서리 위에서) 을 가지거나, 다중의 UV
좌표를 가지거나, 다중의 꼭지점 색상을 가지면, 이는 분리되어야 합니다. Unity 에서 보는 정점의 숫자는 3D 어플리케이션에서 진열
되는 것과 항상 다릅니다.
질감 압축
모든 OpenGL ES 2.0 를 지원하는 안드로이드 디바이스들은 ETC1 compression format 을 지원합니다. 그러므로, ETC1 을 선호하는
질감 포맷으로 사용하길 권유합니다. 압축된 질감은 질감의 사이즈를 줄이는데 중요할 뿐만 아니라(빠른 불러오기 시간과 더 작은
메모리 사용), 렌더링 성능의 향상도 크게 기여합니다. 압축된 질감은 32bit RGBA 에 비교해서 메모리 대역폭의 아주 일부분만
필요합니다.
만약 Nvidia Tegra 나 Qualcomm Snapdragon 과 같은 그래픽 구조를 타겟으로 하면, 그러한 구조에 전속적인 압축 포맷을 사용하는
것도 고려해 볼만 합니다. 안드로이드 마켓은질감 압축 포맷의 지원의 필터링을 허락합니다. DXT compressed textures 와
같은 .apk 와 같은 배포파일은 지원하지 않는 디바이스에서는 압축이 허용되지 않을 수 있습니다.
Mip Maps 허용
항상 Generate Mip Maps 를 허용하는 것이 좋습니다. 질감 압축이 GPU 렌더링시 질감 데이터의 전송의 한계를 돕듯이, mip
mapped 질감은 GPU 가 더 작은 삼각형으로 낮은 해상도를 사용하게 하는 것을 가능하게 합니다. 이 규칙의 예외는 texel(texture
pixel)이 UI 요소들이나 순수 2D 게임에서 렌더된 스크린 픽셀에 1:1 매핑하는 것입니다.
성능 좋은 쉐이더를 작성하기 위한 팁들
모든 안드로이드 OpenGL ES 2.0 GPU 들은 픽셀과 정점 쉐이더(shader)들을 충분히 지원하지만, 복잡한 픽셀당 기능을 가진
데스코톱 쉐이더의 성능과 초당 30 프레임들을 동작하는 안드로이드 디바이스의 성능을 추월하는 기대는 하면 안됩니다. 대부분
쉐이더 들은 편리하게 최적화 되어있고, 연산과 질감은 좋은 프레임 비율을 달성하기 위해서는 최소화 하여야 합니다.
복잡한 수식 연산들
수식 연산들(pow, exp, log, cos, sin, tan)은 GPU 에 많은 부하를 줍니다. 최고의 방법은 부분당(per fragment) 하나의 연산 이상을
가지지 않는 것입니다. 때로는 질감 찾기(lookup)가 더 좋은 대안입니다.
자신만의 normalize, dot, inversesqrt 연산들의 사용을 회피하십시오. 항상 내장되어있는 연산들을 사용하십시오. 이것이 더 좋은
코드를 생성할 것입니다.
Discard 연산은 부분들(fragments)을 느리게 만들 것입니다.
부동소수 연산들
사용자 쉐이더들을 작성할 때 부동 소수 변수들의 소수점 자리를 명시하십시오. 좋은 성능을 위해서는 작은 포맷이 더 중요하다는
것은 매우 중요합니다.
쉐이더가 GLSL ES 로 쓰여지면, 소수점 자리는 다음과 같습니다:
•
highp - 32 비트의 부동소수 포맷입니다. 정점변환에 적합하지만 가장 느립니다
•
mediump - 16 비트의 부동소수 포맷입니다. 질감 UV 좌표에 적합합니다. 대략 highp 보다 x2 배 빠릅니다
•
lowp - 10 비트의 부동소수 포맷입니다. 색상과 빛 연산, 그리고 고성능 연산에 적합합니다. highp 보다는 x4 배 정도 빠릅니다
쉐이더가 GG 또는 표면 쉐이더로 쓰여지면, 소수점은 다음과 같습니다:
•
float - GLSL ES 에서 highp 와 유사, 가장 느림
•
half - GLSL ES 에서 mediump 와 유사, float 보다 x2 빠름
•
fixed - GLSL ES 에서 lowp 와 유사, ffloat 보다 x4 배
일반적인 쉐이더 성능을 알아보시려면 Shader Performance page 페이지를 참조하세요. 인용된 성능 그림들은즉 삼성 Nexus S 와
같은 기기들에 사용가능한 PowerVR 그래픽 환경을 기반으로 합니다. 다른 하드웨어 환경들은 레지스터 정밀(precision)의
감소로부터 덜 혹은 더 수혜를 받을 것입니다.
Lightmaps 으로의 Bake Lighting
정적 라이팅의 장면을 Unity 내의 내장된 Lightmapper 를 사용해서 베이크(bake)하십시오. lightmapped 환경을 생성하는 과정은
Unity 에서 장면에 빛을 배치하는 것보다 더 시간이 걸립니다, 그러나:
•
더 많이 빠릅니다 (2-3 배, 2 픽셀 라이트)
•
더 좋게 보입니다. 왜냐하면, 전체적 조명을 베이크 할수 있고, lightmapper 는 결과들을 부드럽게 할 수 있습니다
재료들 공유
다수의 오브젝트들이 같은 카메라로 표현되면, 유니티 안드로이드는 더 다양한 내부적 최적화를 할 수 있을 것입니다. 예:
•
다양한 렌더 상태들을 OpenGL ES 로 하는 것을 피함.
•
정점과 픽셀 프로세싱에 필요한 다양한 종류의 변수들 연산을 피함
•
그리기(draw)호출들의 감소를 위한 작은 오브젝트들의 일괄처리
•
그리기 호출을 줄이기 위한 정적 속성을 가능하게 하는 크고 작은 오브젝트들의 일괄 처리
모든 이런 최적화들은 CPU 사이클들을 줄여줄 것입니다. 그러므로, 질감들을 하나의 지도로 합하고 같은 재료(material)을 사용하기
위한 다수의 오브젝트를 만드는 것은 비용을 줄이므로, 권유합니다!
게임을 빠르게 하기 위한 간단한 체크리스트
•
내장 쉐이더를 사용한다면, Mobile 카테고리를 살펴보세요. Mobile/VertexLit 는 현재 가장 빠른 쉐이더입니다.
•
장면당 다른 재료(material)의 개수를 낮게 유지하세요- 가능하면 다른 오브젝트들 사이에서 더 많은 재료를 공유하세요.
•
내부 최적화를 위해서 움직이지 않는 오브젝트들에게 Static 속성을 설정하세요.
•
가능한 질감들을 위해서는 ETCI 포맷을 사용하세요. 아니면, 32bit 대신 16bit 질감을 선택하세요.
•
mipmaps 를 사용하세요.
•
통합기(combiners)또는 픽셀 쉐이더를 사용하세요. 이는 다중 패스 접근법 대신에 부분당 몇몇 질감을 혼합하기 위함입니다.
•
사용자 설정 쉐이더를 작성시에는, 항상 가장 작은 부동 소수점을 사용하세요:
o
fixed / lowp -- 칼라와 라이팅 정보, 법선들을 위해서는 완벽합니다,
o
half / mediump -- 질감 UV 좌표들을 위해서 쓰입니다,
o
float / highp -- 픽셀 쉐이더에서는 피합니다. 정점 쉐이더에서 정점 위치 계산을 위한 사용에 괜찮습니다
•
픽셀 쉐이더에서 복잡한 수식 연산(pow, sin, cos 등)을 최소화 합니다.
•
필요하지 않으면 Pixel Lights 는 쓰지 않습니다. – 기하에 영향을 주는 (가능한 방향성의) 하나의 픽셀 라이트를 선택하세요.
•
필요하지 않으면 동적 라이트를 사용하지 않습니다 – 베이크 라이트를 대신 선택하세요.
•
부분당 (per fragment) 더 작은 질감을 사용하세요.
•
알파 테스팅을 피하세요. 알파 블렌딩(alpha-blending)을 대신 사용하세요
•
필요하지 않으면 안개를 사용하지 마세요.
•
폐색 누락(Occlusion culling) 의 장점을 알아보시고, 복잡한 정적 장면에 많은 폐색이 있을 시에는 가시 기하와 그리기 호출의 양을
줄이기 위해서 사용하세요. 폐색 누락으로부터 어떤 이득의 단계를 얻을 것인지 계획하세요.
•
원거리 기하를 “위장(fake)” 위해서는 스카이박스(skybox)들을 사용하세요.
더 살펴보기
•
iPhone 그래픽 성능 최적화 iPhone Optimizing Graphics Performance (그래픽 환경이 Imagination Tech's PowerVR 로 알려진경우)
최적화된 캐릭터 모델링
Skinned Mesh Renderer 사용하기
사용자 캐릭터는 하나의 skinned mesh renderer 를 사용하여야 합니다. 보통 하나의 캐릭터를 위해 여러개의 메쉬를 사용할 필요는
없습니다. 유니티에서도 하나의 animation component 와 하나의 skinned mesh renderer 가 같이 사용될 때 어떤 것을 보여주는지
선택하고 경계를 정하는 지에 관련된 최적화 기능을 가지고 있습니다. 성능을 고려한다면 캐릭터당 다수의 스킨이 있는 메쉬는 좋은
선택이 아닙니다. 한 캐릭터에 두개의 skinned mesh renderers 를 사용한다면 캐릭터를 렌더링하기 위해 두배의 시간이 들 것입니다!
여러 재료(Material)를 사용하지 마세요
메쉬에서 가능한 적은 수의 materials 를 사용하여야 할 것입니다. 한 캐릭터에서 한가지 이상의 재료를 사용하기 위한 이유는 다른
그림자(예를 들어 눈을 위한 특별한 그림자 사용을 원할 때)를 사용하기 위한 이유 한가지 뿐입니다. 그러나 대부분의 경우 캐릭터당
2-3 개의 재료가 충분할 것입니다. 만약 캐릭터가 총을 가지고 있다면 그 총이 분리 될수도 있으므로 총은 다른 객체로 정의하는 것이
유용할 것입니다.
뼈대의 양을 줄이세요
보통의 데스크탑 게임은 15-60 정도의 뼈대를 가진 구조를 사용합니다. 적은 수의 뼈대를 사용할 수록 더 빨라집니다. 30 개의 뼈대로
데스크탑 플랫폼과 모바일 플랫폼에서 상당히 괜찮은 결과를 보여줄 수 있습니다. 정말 필요한 경우가 아니면 모바일 플랫폼에선
30 개보다 적은 데스크탑 플랫폼에서는 30 개 정도의 빼대를 사용하기를 권장합니다.
다각형의 개수
다각형을 몇 개를 사용하여야 하는 것은 사용될 플랫폼과 필요로하는 퀄리티에 때라 달라집니다. 모바일 플랫폼에서 300-1500 개의
삼각형 데스크탑 플랫폼에서는 500-6000 개의 삼각형이 적당합니다. 화면에 많은 수의 캐릭터를 원하거나 오래된 시스템어서
돌리길 원하면 각 캐릭터별 다각형의 개수를 줄여야 할 것입니다. 예를 들어, Half Life2 의 캐릭터들은 2500-5000 개의 삼각형을
사용하였습니다. PS3 나 Xbox360 에서의 차세대 AAA 게임들은 5000-7000 의 삼각형으로 만든 캐릭터를 가지고 있습니다.
IK 의 FK 구분
Inverse kinematics (IK) 와 forward kinematics (FK)를 구분하세요. 애니메이션을 불러올 때 IK 노드들은 FK 로 구워집니다. 그러므로
유니티는 IK 노드 자체를 필요로하지 않습니다. 유니티에서 GameObjects 를 제거하거나 모델링 툴의 노드를 제거할 수 있습니다.
그것을 제거함으로써 IK 노드들이 더이상 매 프래임당 다시 애니메이션화 할 필요가 없어집니다. 이런 이유로 IK 와 FK 를 같이 섞여
있는 계층을 가지는 것은 정말 좋지 않은 생각 입니다. 대신 하나의 IK 만을 위한 계층과 하나의 FK 만을 위한 계층을 만들어야
합니다. 이런 방법으로해야 모든 IK 계층을 쉽게 제거할 수 있습니다.
재사용 가능한 Rig 사용하기
재사용 가능한 rig 을 만드십시오. 이것은 사용자가 다른 캐릭터간 애니메이션을 공유하게 하는 것을 가능하게 합니다.
뼈대의 이름을 정확히 만듭니다
뼈대의 이름을 정확히 만듭니다 (왼쪽 힙, 왼쪽 발목, 왼쪽 발, 등등). 특히 캐릭터에서 뼈대의 이름을 정확히 하는 것은 정말
중요합니다. 예를 들어 만약 사용자가 하나의 캐릭터를 Ragdoll 로 바꾼다면 각 몸체를 위해 맞는 뼈대를 찾아야 할 것입니다. 이름이
정확하지 않다면 모든 몸체를 찾는데 많은 시간이 걸릴 것입니다.
Rendering Statistics Window
Game View 는 오른쪽 상단에 Stats 버튼이 있습니다. 이 버튼이 눌리면 화면 위로보이는 창에 실시간 렌터링 통계자료가 보입니다.
이것은 사용자 게임을 최적화하는데 매우 유용합니다. 그 통계는 빌드 목적에 따라 매우 다양할 것입니다.
렌더링 통계 윈도우
통계 윈도우는 다음의 정보를 포함합니다:
게임의 하나의 프레임(FPS)을 처리하고 렌더링하는데 걸리는 시간. 이것은 프레임을 업데이트하고 게임뷰를
Time per frame
and FPS
렌더링하는 시간만을 포함합니다. 에디터에서 씬뷰, 인스펙터 그리고 다른 에디터에서만 처리하는 것들에 대한
시간은 포함되지 않습니다.
총 몇개의 객체가 그려졌는가. 이것은 여러번 그려진 객체들도 합쳐집니다. 예를들어 픽셀빛에 영향을 받는 어떤
Draw Calls
객체는 여러번의 드로 콜(Draw call)을 추가할 것입니다.
Batched (Draw
같이 배치된 그림 콜의 개수. 배치란 여러 객체의 렌더링을 하나의 드로 콜로 만들어 CPU 사용을 줄이는 것을
Calls)
말합니다. 좋은 배치를 위해서는 가능한 많은 객체어서 재료들을 공유해야 합니다.
Tris and Verts
삼각형와 꼭지점의 개수. 이것은 사양이 optimizing for low-end hardware 때 가장 중요한 것입니다.
Used Textures
프레임을 그리는데 사용된 텍스쳐의 수와 메모리 크기.
생성된 Render Textures 의 수와 메모리 크기. 또한 이 프레임에서 몇 번이나 액티브한 렌더 텍스쳐가
Render Textures
바뀌었는지도 포함합니다.
Screen
화면의 크기, 앤티 앨리어싱 단계, 차지한 메모리.
VRAM usage
대략의 현 비디오 메모리(VRAM) 사용량. 또한 사용자 그래픽 카드가 가지는 메모리 크기도 보여줍니다.
그래픽 카드에 로드된 유니크한 메쉬(vertex buffers)의 개수. 각각의 모델은 새로운 VBO 를 만들것입니다. 어떤
VBO total
경우에는 크기가 바뀐 객체가 추가로 VBO 를 만들기도 합니다. 정적 배치의 경우 여러개의 객체가 하나의
VBO 를 공유하기도 합니다.
Visible Skinned
렌더된 스킨이 있는 메쉬의 개수.
Meshes
Animations
플레이 되고 있는 애니메이션의 개수.
Desktop
좀더 자세한 사항은 Optimizing Graphics Performance 를 보세요.
iOS
Optimizing iOS Graphics Performance 를 보세요.
Android
좀더 자세한 사항은 Optimizing Android Graphics Performance 를 보세요.
또한 Profiler 는 추가적인 렌더링 통계를 보여줍니다.
파일 사이즈 줄이기
유니티는 모든 가져온 애셋들에 대해 후 처리 합니다
유니티는 항상 가져온 파일들에 대해 후 처리 합니다. 파일을 jpg 대신 다중 레이어 psd 파일 (multi-layered psd file)로 저장하는 것은
배치(deploy)할 플레이어의 크기에 아무런 차이를 주지 않을 것입니다. 파일들을 편의를 위해서 현재 작업하는 포맷(예: .mb
파일들, .psd 파일들, .tiff 파일들)으로 저장하십시오.
유니티는 사용 않는 애셋들을 추출 합니다
프로젝트 폴더내에 애셋들의 크기는 빌드된 플레이어의 크기에 영향을 주지 않습니다. 유니티는 게임에서 어떤 애셋들이 사용되는지
사용되지 않는지를 감지하는 데는 매우 영리합니다. 유니티는 게임을 빌드하고 게임에 포함될 필요가 있는 애셋들의 리스트를
생성하기 전에, 애셋들에 대한 모든 참조(reference)들을 지켜봅니다. 그러므로, 프로젝트 폴더내에서 사용되지 않는 애셋들을 유지
할 수 있습니다.
유니티는 사용된 파일 사이즈의 개요를 프린트합니다
유니티가 플레이어의 빌드를 마친 후에, 어떤 종류의 애셋이 가장 큰 파일 규모를 차지하고 있는지를 프린트하고, 빌드에서 포함된
애셋들을 프린트합니다.
Desktop
열람을 위해서는: Console window (Window -> Console)에 있는 Open Editor Log 버튼을 누르십시오.
iOS
열람을 위해서는, 콘솔 로그를 여십시오: Help -> Open Editor console log 메뉴.
Android
열람을 위해서는, 에디터의 콘솔 로그를 여십시오: 콘솔 창에서 Open Editor Log 버튼 (Window -> Console).
공간을 차지 하는 것에 대한 개요
질감 사이즈 최적화
질감들은 종종 빌드 시에 가장 많은 공간을 차지합니다. 첫 번째 해야 할 일은 압축 질감 포맷들 (DXT(Desktop platforms) 또는
PVRTC)을 가능하면 사용 하는 것입니다.
만약 사이즈가 줄어들지 않는다면, 질감들의 사이즈를 줄이도록 시도해 보십시오. 여기서의 트릭(trick)은 실제 소스 컨텐트를 변경할
필요가 없습니다. 단지 프로젝트 보기의 질감을 선택하고, 가져오기 설정들에서 Max Texture Size 를 설정하십시오. 질감을
사용하는 오브젝트에 줌인(zoom in) 하는 것은 좋은 아이디어입니다. 그리고 Scene View 에서 안 좋아 보이기 시작 할 때까지, 최대
질감 사이즈를 조정하십시오.
최대 질감 사이즈를 변경하는 것은 질감 애셋에 영향을 주지 않고, 게임의 해상도에만 영향을 줍니다
해당 질감이 얼마나 많은 메모리를 차지하는가?
Desktop
압축
메모리 압축
RGB Compressed DXT1
0.5 bpp (bytes/pixel)
RGBA Compressed DXT5
1 bpp
RGB 16bit
2 bpp
RGB 24bit
3 bpp
Alpha 8bit
1 bpp
RGBA 16bit
2 bpp
RGBA 32bit
4 bpp
iOS
압축
메모리 압축
RGB Compressed PVRTC 2 bits
0.25 bpp (bytes/pixel)
RGBA Compressed PVRTC 2 bits
0.25 bpp
RGB Compressed PVRTC 4 bits
0.5 bpp
RGBA Compressed PVRTC 4 bits
0.5 bpp
RGB 16bit
2 bpp
RGB 24bit
3 bpp
Alpha 8bit
1 bpp
RGBA 16bit
2 bpp
RGBA 32bit
4 bpp
Android
압축
메모리 압축
RGB Compressed DXT1
0.5 bpp (bytes/pixel)
RGBA Compressed DXT5
1 bpp
RGB Compressed ETC1
0.5 bpp
RGB Compressed PVRTC 2 bits
0.25 bpp (bytes/pixel)
RGBA Compressed PVRTC 2 bits
0.25 bpp
RGB Compressed PVRTC 4 bits
0.5 bpp
RGBA Compressed PVRTC 4 bits
0.5 bpp
RGB 16bit
2 bpp
RGB 24bit
3 bpp
Alpha 8bit
1 bpp
RGBA 16bit
2 bpp
RGBA 32bit
4 bpp
총 질감 사이즈를 알아내기 위해서는: 너비(width) * 높이(height) * bpp. 만약 Mipmaps 를 가지면, 33% 추가.
유니티는 디폴트로 가져오기 시에 모든 질감들을 압축합니다. 이는 Preferences 에서 더 빠른 워크플로우(faster workflow)에서 끌 수
(turn off) 있습니다. 그러나, 게임을 빌드 할 시에는, 모든 아직 압축되지 않은 질감들이 압축될 것입니다.
메쉬와 애니메이션 사이즈 최적화 하기
Meshes 과 가져오기한 애니메이션 클립들은 압축되어서 게임 파일에서 더 적은 공간을 차지하도록 할 수 있습니다. 압축은 메쉬
가져오기 설정들(Mesh Import Settings)에서 켜 질 수 있습니다.
메쉬와 애니메이션 압축은 양자화(quantization)를 사용합니다. 이는 더 작은 공간을 사용하지만, 압축은 부 정확성을 나타낼 수
있습니다. 어떤 레벨의 압축이 해당 모델들을 위해서 받아들여질지를 실험하십시오.
메쉬 압축은 오직 더 작은 데이터 파일들로 만들지만, 실행 시에는 더 작은 메모리를 사용하지 않는다는 점을 유념하십시오.
애니메이션 Keyframe reduction 는 더 작은 데이터 파일들과, 실행시의 더 작은 메모리 사용을 만듭니다. 일반적으로, 키 프레임
줄이기는 항상 사용해야 합니다.
추가적으로, 게임 빌드와 실행 시의 메모리를 아끼기 위해서, 메쉬들 내에서 노멀들 또는/그리고 탄젠트들을 저장 않도록 선택할 수
있습니다. 이는 메쉬 가져오기 설정들의 드롭다운에서 Tangent Space Generation 을 설정해서 이루어 집니다. 경험에 기반해서:
•
탄젠트들은 노멀 매핑들을 위해서 사용합니다. 노멀 매핑을 사용하지 않으면, 해당 메쉬들에서 탄젠트들을 저장할 필요가 아마 없을
것입니다.
•
노멀들을 라이팅(lighting)을 위해 사용합니다. 몇몇 메쉬들에 실시간 라이팅을 사용하지 않으면, 노멀들을 해당 메쉬들에 아마도
저장할 필요가 없을 것입니다.
플레이어들 내에서 포함된 dll 들을 줄이기
플레이어를 빌드할 때 (데스크톱, 안드로이드 또는 아이오에스(iOS)), System.dll이나 System.Xml.dll 파일에 의존 되지 않는 것이
중요합니다. 유니티는 플레이어들 설치 시에System.dll 파일이나 System.Xml.dll 를 포함하지 않습니다. 만약 xml이나
System.dll이 상주하는 몇몇 지네릭 컨테이너들(generic containers)의 사용을 원하면, 요구되는 dll들은 플레이어들에 포함 되야
함을 의미합니다. 이는 다운로드 사이즈에 1MB를 추가 시키는데, 플레이어들의 배포에 좋지 않고, 이를 방지해야 합니다. 만약 몇몇
xml 파일들의 파싱(parsing)이 필요하면 Mono.Xml.zip과 같은 더 작은 xml 라이브러리를 사용할 수 있습니다. 대부분의 지네릭
컨테이너들은 mscorlib에 포함되어 있지만, Stack<>과 몇몇은 System.dll에 포함되어 있습니다. 그러므로, 이를 방지해야 합니다.
보시다시피, 플레이어를 빌딩시에 유니티는 System.Xml.dll 과 System.dll 을 포함합니다
유니티는 플레이어들의 배포에 다음과 같은 DLL 들을 포함합니다: mscorlib.dll, Boo.Lang.dll, UnityScript.Lang.dll 그리고
UnityEngine.dll
플렛폼에 따른 컴파일
유니티는 "Platform Dependent Compilation"라는 기능을 포함합니다. 이것은 사용자가 하나의 지원되는 플랫폼을 위한 코드를
컴파일하고 실행하기 위해서 자신의 스크립트를 나누게 해주는 전처리 프로세서로 이루어져 있습니다.
또한 에디터에서 이 코드를 실행시킬 수 있으므로 사용자는 모바일/콘솔을 위한 코드를 컴파일할 수 있고 에디터에서 테스트 할수
있습니다!
플랫폼을 정의합니다 플랫폼은 사용자 스크립트를 위해 유니티가 지원하는 것을 정의 합니다:
Property:
UNITY_EDITOR
Function:
사용자 게임 코드에서 유니티 에디터를 부르기위해 정의.
맥 OS 의 코드 컴파일/실행을 위한 플랫폼 정의(이것은 Universal, PPC 와 Intel architecture 를
UNITY_STANDALONE_OSX
포함합니다).
UNITY_DASHBOARD_WIDGET 맥 OS 의 dashboard widget 코드 생성때 플랫폼 정의.
UNITY_STANDALONE_WIN
윈도우즈 독립 실행형 프로그램 코드 컴파일 실행할 때 사용.
UNITY_WEBPLAYER
웹 플레이어 내용을 위한 플랫폼 정의(이것은 윈도우즈 웹플레이어를 포함합니다).
UNITY_WII
Will 콘솔 코드의 컴파일 실행을 위한 플랫폼 정의.
UNITY_IPHONE
아이폰 코드의 컴파일과 실행을 위한 플랫폼 정의.
UNITY_ANDROID
안드로이드 플랫폼을 위한 플랫폼 정의.
UNITY_PS3
플레이 스테이션 3 코드를 위한 플랫폼 정의.
UNITY_XBOX360
Xbox 360 코드 실행을 위한 플랫폼 정의.
주의: 위 정의는 버전 3.0 에서 도입되었습니다.
또한 사용자는 작업중인 엔진의 버전에 따라 코드를 선택적으로 컴파일 할 수 있습니다. 현재 지원되는 것은:
UNITY_2_6
유니티 주 버전 2.6 의 플랫폼 정의.
UNITY_2_6_1
유니티 주 버전 2.6 특정 버전 1 의 플랫폼 정의.
UNITY_3_0
유니티 주 버전 3.0 의 플랫폼 정의.
UNITY_3_0_0
유니티 버전 3.0 의 특정 버전 0 의 플랫폼 정의.
UNITY_3_1
유니티 버전 3.1 의 특정 버전 0 의 플랫폼 정의.
UNITY_3_2
유니티 버전 3.2 의 특정 버전 0 의 플랫폼 정의.
UNITY_3_3
유니티 버전 3.3 의 특정 버전 0 의 플랫폼 정의.
UNITY_3_4
유니티 버전 3.4 의 특정 버전 0 의 플랫폼 정의.
주의: 2.6.0 이전 버전에선 플랫폼 정의가 있지 않은데 이 버전에서 처음으로 도입되었기 때문 입니다.
전컴파일 코드 테스트.
어덯게 컴파일 되기 전의 코드를 사용할 수 있는지에대한 작은 예제를보여드를 것입니다. 이것은 사용자가 빌드하기 위한 플랫폼에
따라 간단하게 메세지를 프린트합니다.
무엇보다도 File -> Build Settings 를 눌러 코드를 테스트하고 싶은 플랫폼을 선택합니다. 이것은 목표 플랫폼을 선택하기위해 빌드
세팅 윈도우를 띄울 것입니다.
WebPlaye 가 목표 플랫폼으로 선택된 빌드 세팅 윈도우
컴파일 되기 전의 코드를 테스트하기 위한 플랫폼을 선택하고 Switch Editor 버튼을 눌러 유니티에게 어떤 플랫폼을 목표로하는지
알려주세요.
스크립트를 생성하고 이 코드를 복세/붙여넣기 하세요:
JavaScript 예제:
function Awake() {
#if UNITY_EDITOR
Debug.Log("Unity Editor");
#endif
#if UNITY_IPHONE
Debug.Log("Iphone");
#endif
#if UNITY_STANDALONE_OSX
Debug.Log("Stand Alone OSX");
#endif
#if UNITY_STANDALONE_WIN
Debug.Log("Stand Alone Windows");
#endif
}
C# Example:
using UnityEngine;
using System.Collections;
public class PlatformDefines : MonoBehaviour {
void Start () {
#if UNITY_EDITOR
Debug.Log("Unity Editor");
#endif
#if UNITY_IPHONE
Debug.Log("Iphone");
#endif
#if UNITY_STANDALONE_OSX
Debug.Log("Stand Alone OSX");
#endif
#if UNITY_STANDALONE_WIN
Debug.Log("Stand Alone Windows");
#endif
}
}
Boo 예제:
import UnityEngine
class PlatformDefines (MonoBehaviour):
def Start ():
ifdef UNITY_EDITOR:
Debug.Log("Unity Editor")
ifdef UNITY_IPHONE:
Debug.Log("IPhone")
ifdef UNITY_STANDALONE_OSX:
Debug.Log("Stand Alone OSX")
ifdef not UNITY_IPHONE:
Debug.Log("not an iPhone")
그러면 선택한 플랫폼에 따라 플레이가 눌리면 유니티 콘솔에 메세지중 하나가 프린트 될 것입니다.
Debugging
게임을 만들때는 장명(scene) 설정이나 스크립트 에러로 계획하지 않았거나 원치않는 행동들이 발생할 수 있습니다. 그런 원치않는
행동들을 주로 bugs 라고하며 그것들을 고치는 과정을 debugging 이라고 합니다. 유니티는 게임을 디버깅을 위한 몇가지 방법을
제공합니다. 다음 페이지에서 그 방법들에 대해 읽을 수 있습니다.
•
콘솔
•
디버거
•
로그 파일
o
숨겨진 폴더 접속
Console
상태바에의 에러를 더블클릭하거나 Window->Console 을 선택하면 Console 을 불러올 수 있습니다 .
에티터에서의 콘솔
콘솔은 게임에서의 메세지, 경고, 에러 또는 디버그 결과물을 보여줍니다. Debug.Log(), Debug.LogWarning,
또는 Debug.LogError()를 이용해 콘솔로 보내질 메세지를 정의할 수 있습니다. 메세지를 보낸 스크립트로 가기위해선 메세지를 더블
클릭하면 됩니다. 콘솔 툴바에는 또 몇가지의 옵션들이 있습니다.
콘솔 제어 툴바는 디버그 결과물을 필터하는데 도움을 줍니다.
•
Clear 를 누르면 콘솔에서의 현재의 모든메세지를 지웁니다.
•
Collapse 가 활성화되면, 동일한 메시지들은 한번만 보여집니다.
•
Clear on play 가 활성화 되면, 플레이 모드로 갈 때마다 콘솔에서 모든 메세지는 지워집니다.
•
Error Pause 가 활성화 되면 Debug.LogError()는 일시 정지가 발생하게 되지만 Debug.Log()는 그렇지 않습니다.
•
Open Player Log 를 누르면 텍스트 에디터(또는 맥에서의 Console app)에서 Player Log 가 열릴 것입니다.
•
Open Player Log 를 누르면 텍스트 에디터(또는 맥에서의 Console app)에서 “Editor Log”가 열릴 것입니다.
Debugger
Unity 디버거는 사용자가 사용자의 코드를 실시간 검사하게 해줍니다. 예를 들어 그것은 사용자가 언제 함수가 어떤 값들과 함께
불려질는지를 결정할 수 있도록 도와줍니다. 게다가 그것은 사용자가 사용자의 게임이 실행되는 동안에 주어진 시간에 스크립트의
값을 보는 것을 허용합니다. 사용자는 그들을 차례차례 실행하는 것에 따라서 사용자의 스크립트에서 버그와 로직 문제들을 찾을 수
있습니다.
Unity 는 사용자의 게임에서 스크립트를 디버그하기 위해서 MonoDevelop IDE 를 사용합니다. 사용자는 엔진에서 지원하는 모든
언어를 디버그할 수 있습니다 (JavaScript, C#, and Boo).
디버거가 사용자의 모든 코드와 모든 부호들을 로드해야 한다는 것을 명심하세요. 이것은 실행동안에 사용자 게임의 성능에 작은
영향을 줄 수도 있다는 것을 참고하세요. 일반적으로 이런 오버헤드는 게임에 영향을 줄 만큼 크지는 않습니다.
MonoDevelop window 는 unity 의 하나의 script 를 디버깅 합니다
Debugging in Unity.
윈도우즈에서 사용자는 Unity 설치의 부분으로서 MonoDevelop 을 설치할지를 선택해야 합니다 (기본으로 선택됩니다).
•
사용자가 사용자의 프로젝트에서 전에 MonoDevelop 을 사용한 것이 없다면 사용자의 MonoDevelop 프로젝트를 동기화 합니다.
이것은 MonoDevelop 내에서 사용자의 프로젝트를 열 것입니다.
•
사용자가 분석하기를 원하는 라인을 클릭하는 것에 의해 사용자의 스크립트에서 필요한 breakpoints 를 세팅합니다.
•
Unity 또는 사용자의 플레이어를 시작합니다.
o
Unity: 사용자가 Preferences 윈도우에서 "Allow attached debugging"를 체크되도록 합니다.
o
Players: 사용자가 "Development build"와 "Allow script debugging" 옵션을 활성화한 상태로 사용자 플레이어를 구축하도록 합니다.
•
MonoDevelop 에서 사용자의 프로젝트를 엽니다.
•
MonoDevelop 에서 툴바에서 Attach 버튼을 클릭하거나 Run 메뉴로부터 Attach 를 선택합니다.
•
나타나는 다이아로그로 부터 사용자가 디버그하고 싶은 아이템을 선택합니다.
•
참고:
o
현재 지원되는 디버깅 타겟: Unity 편집기, 데스트탑 독립형 플레이어, Android 와 iOS 플레이어
o
사용자의 플레이어가 배경에서 실행되지 않도록 세팅된다면 (디폴트), 사용자는 사용자의 플레이어가 리스트에 나타나도록 하기
위해서 몇 초간 그것에 초점을 맞출 필요가 있을지도 모릅니다.
o
Android 와 iOS 플레이어는 스크립트 디버깅이 활성화될 때 활성화된 네트워킹을 가져야 합니다. 모든 플레이어는 MonoDevelop 가
실행되는 컴퓨터로서 같은 네트워크 서브넷 위에 있어야할 필요가 있습니다.
•
사용자가 플레이 모드에 들어갈 때 사용자의 스크립트 코드는 디버거에서 실행할 것입니다.
•
하나의 breakpoint 가 일어날 때 스크립트 실행은 멈출 것이고 사용자는 사용자의 스크립트 메서드로 부터 들어가고
건너뛰고 나오고 사용자의 변수를 검사하고 콜 스택을 검사하기 위해서 MonoDevelop 를 사용할 수 있어야 할 것입니다.
o
주의: 사용자가 탑 레벨 메서드 (e.g. Update())에서 디버깅을 끝낼 때 또는 사용자가 다음의 breakpoint 로 가기를 원할 때
사용자는 사용자의 함수의 끝 밖으로 나가는 것 대신에 Continue 명령을 사용하는 것에 의해 더 좋은 디버거 성능을 경험할
수 있을 것입니다.
•
사용자가 디버깅을 끝낼 때, 툴 바에서 Detach 또는 Stop 버튼을 클릭하거나 Run 메뉴에서 Detach 또는 Stop 를 선택합니다.
Hints.
•
사용자가 this 오브젝트로 하나의 watch 를 추가한다면, 사용자는 스크립트가 부착된 GameObject 의 내부 값(위치, 스케일,
회전...)을 검사할 수 있습니다.
iOS remote debugging instructions
위에서 설명된 지시사항 외에도 Unity iOS 어플리케이션은 성공적인 디버깅을 위해서 몇몇의 부가적인 스텝을 필요로 합니다:
1.
사용자의 iDevice 를 사용자의 WiFi 네트워크에 부착합니다 (리모트 프로파일링을 위한 것과 같은 필수조건).
2.
Unity 편집기에서 Hit build & run.
3.
어플리케이션이 구축, 설치되고 Xcode 를 통해서 시작될 때 Xcode 에서 Stop 을 클릭합니다.
4.
사용자의 iDevice 에서 수동적으로 사용자의 어플리케이션을 찾고 시작합니다. (주의: 어플리케이션이 Xcode 를 통해서
시작되면 사용자는 하나의 breakpoint 에 다다른 후에 다시 시작할 수 없을 것입니다).
5.
App 이 디바이스에서 실행될 때, MonoDevelop 로 바꾸고 디버깅 툴에서 attach 아이콘을 클릭합니다. 가능한 인스턴스
리스트에서 사용자의 디바이스를 선택합니다 (몇몇의 인스턴스가 보여지면 아래 것을 선택합니다).
로그 파일
개발 중에는 웹플레이어, 독립 실행형 플레이어, 목표로하는 장치또는 에디터의 로그에서 정보를 얻어야할 때가 있습니다. 보통
문제가 있어서 무슨 문제인지를 정확히 알아야할때 이 로그 파일들을 볼 필요가 있습니다.
맥에서 웹플레이어, 플레이어, 그리고 에디터 로그는 동일하게 표준 Console.app 유틸리티를 통해 접근가능 합니다.
윈도우즈에서는 웹플레이어와 에디터로그는 기본적으로 윈도우즈 익스플러로에서는 보이지 않는 폴더에 위치하고 있습니다. 이
상황을 해결하기 위해선 Accessing hidden folders 페이지를 보세요.
에디터
에디터 로그는 유니티 콘솔창에 Open Editor Log 버튼을 통해 볼수 있습니다.
Mac OS X
~/Library/Logs/Unity/Editor.log
Windows XP *
C:\Documents and Settings\username\Local Settings\Application Data\Unity\Editor\Editor.log
Windows Vista/7 *
C:\Users\username\AppData\Local\Unity\Editor\Editor.log
(*) 윈도우즈에서 에디터 로그 파일은 로컬 프로그램 데이터 폴더에 저장 됩니다: %LOCALAPPDATA%\Unity\Editor\Editor.log,
where LOCALAPPDATA은 CSIDL_LOCAL_APPDATA에 의해 정의 됩니다.
Desktop
맥에서 모든 로그는 동일하게 표준 Console.app 유틸리티를 통해 접근가능 합니다.
웹플레이어
Mac OS X
Windows XP *
Windows Vista/7 *
~/Library/Logs/Unity/WebPlayer.log
C:\Documents and Settings\username\Local
Settings\Temp\UnityWebPlayer\log\log_UNIQUEID.txt
C:\Users\username\AppData\Local\Temp\UnityWebPlayer\log\log_UNIQUEID.txt
Windows Vista/7 + IE7 + UAC
C:\Users\username\AppData\Local\Temp\Low\UnityWebPlayer\log\log_UNIQUEID.txt
*
(*) 윈도우즈에서 웹플레이어 로그는 임시 폴더인에 저장되어 있습니다: %TEMP%\UnityWebPlayer\log\log_UNIQUEID.txt, where
TEMP 는 GetTempPath에 의해 정의 됩니다.
플레이어
Mac OS X
~/Library/Logs/Unity/Player.log
Windows *
EXECNAME_Data\output_log.txt
(*) EXECNAME_Data 는 게임에서 실행파일 옆에 있는 폴더입니다.
iOS
장치로그는 GDB 콘솔이나 Organizer 콘솔을 이용해 XCode 에서 접근 가능합니다.Organizer 콘솔은 사용자 프로그램이
XCode 디버거를 통해 실행되고 있지 않을때 크래쉬 로그를 얻는데 유용합니다.
iOS의 개발 가이드안의 Debugging Applications를 참고하세요. 또한 저희 Troubleshooting와 Bugreporting 가이드도 유용할
것입니다.
Android
장치로그는 logcat console를 이용해 볼수 있습니다. Android SDK/platform-tools 디렉토리에 있는adb프로그램을
logcat파라미터와 함께 이용하세요:
$ adb logcat
LogCat을 볼수 있는 다른 방법은 Dalvik Debug Monitor Server (DDMS)를 이용하는 것입니다. DDMS는 Eclipse나 안드로이드
SDK/툴에서 시작될 수 있습니다. 또한 DDMS는 몇가지 디버그 관련 프로그램을 제공합니다.
숨겨진 폴더 보기
윈도우에서는 로그 파일들은 기본적으로 숨겨진 폴더에 저장 되어집니다. 윈도우 익스플로러에서 그 파일들을 찾기 위해서는
아래와 같이 하면 됩니다.
윈도우 XP 에서 숨겨진 폴더 보기
로컬 설정(Local Settings)이 되어있는 폴더는 기본적으로 숨겨져 있습니다. 그 폴더를 보기 위해서는 윈도우 익스플로러에서 Tools>Folder Options...->View (tab)를 통해 숨겨진 폴더 보기를 활성화하면 됩니다.
윈도우 XP 에서 숨겨진 폴더 보기 활성화 하기
윈도우 비스타/7 에서 숨겨진 폴더 보기
기본적으로 AppData 폴더는 숨겨지있습니다. 그 폴더를 보기 위해서는 윈도우 익스플로러에서 Tools->Folder Options...->View
(tab)를 통해 숨겨진 폴더 보기를 활성화하면 됩니다. 툴 메뉴는 기본적으로 숨겨져 있는데 Alt 키를 한번 눌러줌으로써 보이게
됩니다.
윈도우 비스타/7 에서 숨겨진 폴더 보기 활성화 하기
Plugins - – 프로/모바일 만의 기능
유니티는 C, C++, Objective-C 에 기반을 둔 Plugins 에 대한 광범위한 지원을 합니다. 플러그인은 사용자 게임 코드가(Javascript,
C# 또는
Boo 로 작성된 ) 본래 코드 라이브러리를 부르는 것을 가능하게 합니다. 이것은 유니티가 다른 middleware 라이브러리 또는 기존의
게임 코
드와 통합되는 것을 가능하게 합니다.
주의: 플러그인은 프로에만 존재하는 기능입니다. 데시크탑 빌드에서 플러그인은 독립 실행형에서만 작동합니다. 보안을 이유로
웹 플레이어가 빌드 될때는 비활성화 됩니다.
플러그인을 사용하기 위해서는 두가지를 해야 합니다:
•
C 기반 언어로 플러그인을 작성하고 컴파일 합니다.
•
플러그인에 있는 함수를 부르기 위한 C# 스크립트를 생성합니다.
플러그인은 하나의 간단한 C 인터페이스를 제공합니다. 그 스크립트는 플러그인에 드러난 함수를 부릅니다.
여기 아주 간단한 예제가 있습니다:
The C File of a Minimal Plugin:
float FooPluginFunction () { return 5.0F; }
A C# Script that Uses the Plugin:
Desktop
using UnityEngine;
using System.Runtime.InteropServices;
class SomeScript : MonoBehaviour {
// This tells unity to look up the function FooPluginFunction
// inside the plugin named "PluginName"
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
void Awake () {
// Calls the FooPluginFunction inside the PluginName plugin
// And prints 5 to the console
print (FooPluginFunction ());
}
}
iOS
using UnityEngine;
using System.Runtime.InteropServices;
class SomeScript : MonoBehaviour {
// This tells unity to look up the function FooPluginFunction
// inside the static binary
[DllImport ("__Internal")]
private static extern float FooPluginFunction ();
void Awake () {
// Calls the native FooPluginFunction
// And prints 5 to the console
print (FooPluginFunction ());
}
}
Android
using UnityEngine;
using System.Runtime.InteropServices;
class SomeScript : MonoBehaviour {
// This tells unity to look up the function FooPluginFunction
// inside the plugin named "PluginName"
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
void Awake () {
// Calls the FooPluginFunction inside the PluginName plugin
// And prints 5 to the console
print (FooPluginFunction ());
}
}
Xbox360
using UnityEngine;
using System.Runtime.InteropServices;
class SomeScript : MonoBehaviour {
// This tells unity to look up the function FooPluginFunction
// inside the static binary
[DllImport ("__Internal")]
private static extern float FooPluginFunction ();
void Awake () {
// Calls the native FooPluginFunction
// And prints 5 to the console
print (FooPluginFunction ());
}
}
플러그인 생성 하기
Desktop
Mac OS X 를 위한 플러그인 빌드하기
Mac OS X 를 위한 플러그인을 빌드하면 번들을 생성해야 합니다. 가장 쉬운 방법은 XCode 를 이용하는 것입니다. File>NewProject... 를 이
용하고 Bundle - Carbon/Cocoa Loadable Bundle 를 선택합니다.
플러그인 구현을 위해 C++ (.cpp) 또는 Objective-C (.mm)를 이용한다면 name mangling issues를 피하
기 위해 함수가 C 링키지와 함께 선언되도록 해야합니다.
extern "C" {
float FooPluginFunction ();
}
원도우즈를 위한 플러그인 빌드하기
윈도우즈에서 플러그인은 DLL 파일과 내보내진 함수들입니다. 사실 DDL 파일을 생성할 수 있는 어떤 언어나 개발 환경도
플러그인을 생
성할 수 있습니다.
만약 C++을 사용한다면 함수를 C 링키지와 함께 선언해서 name mangling issues 를 피하세요.
C#에서 사용자 플러그인 사용하기
사용자 번들을 만들면 그것을 Assets->Plugins 폴더로 복사해야 합니다. 사용자가 함수를 아래와 같이 정의할때 유니티는 이름으로
그
것을 찾을 것입니다:
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
PluginName 은 파일의 확장자명은 포함하지 말아야 합니다. 플러그인 코드를 바꿀때마다 프로젝트 스크립트를 다시 컴파일
해야함을
잊지 마세요. 그렇지 않으면 플러그인은 최신 코드를 가지지 못할 것입니다.
배치
크로스 플랫폼 플러그인을 위해서는 플러그인 폴더가 .bundle (Mac) 과 .dll (Windows) 파일 모두를 포함하고 있어야 합니다. 일단
플러그인
을 플러그인 폴더에 넣으면 더이상 사용자가 할 일은 없습니다. 유니티가 자동으로 개발 플랫폼에 맞는 플러그인을 선택하고
플레이어
에 포함합니다.
iOS
iOS 를 위한 본래 플러그인과 프로그램 빌드하기
1.
사용자 extern method 를 다음과 같이 정의합니다:
2.
[DllImport ("__Internal")]
private static extern float FooPluginFunction ();
3.
에디터를 iOS 플랫폼으로 바꿉니다
4.
사용자 본래 구현을 생성된 Xcode 프로젝트의 "Classes" 폴더에 추가합니다 (프로젝트가 업데이트 될때 이 폴다는
덮어씌여지지 않습니
다. 그러나 사용자 본래 코드를 백업하는 것을 잊지 마세요).
플러그인 구현을 위해 C++ (.cpp) 또는 Objective-C (.mm)를 이용한다면 name mangling issues를 피
하기 위해 함수가 C 링키지와 함께 선언되도록 해야합니다.
extern "C" {
float FooPluginFunction ();
}
C#에서 사용자 플러그인 사용하기
iOS 본래 플러그인은 실제 장치에서만 불릴수 있으므로 모든 본래 코드 함수를 추가적인 C#코드 레이어로 감싸세요. 이
코드는 Application.platform 를 확인할수 있으며 실제 장치에서 실행될때만 본래 함수를 부를수 있고 에디터에서 실행될 때는 모형
값을 리
턴합니다. Bonjour 브라우저 샘플 프로그램을 확인하세요.
본래 코드에서 C# / JavaScript 부르기
유니티 iOS 는 제한적인 native->managed callback 기능을 UnitySendMessage 을 통하여 지원합니다:
UnitySendMessage("GameObjectName1",
"MethodName1", "Message to send");
이 함수는 세개의 파라미터를 가지고 있습니다: 게임 객체 이름, 부를 게임 객체 스크립트 함수, 불려진 함수에 넘겨줄
메세지.알아야할 제한은:
1.
다음의 시그니쳐와 사응하는 스크립트 함수만이 본래 코드에서 불려질 수 있습니다: function MethoName(message:string)
2.
UnitySendMessage 으로의 콜은 비동기이고 하나의 프레임 딜레이가 있습니다.
자동화된 플러그인 통합
유니티 iOS 는 제한적인 자동화된 플러그인 통합을 지원합니다.
1.
Assets/Plugins/iOS 에 있는 모든 .a,.m,.mm,.c,.cpp 는 자동으로 생성된 Xcode 프로젝트로 통합 됩니다.
2.
통합은 symlinking 파일을 통해 가능한데 Assets/Plugins/iOS 에서 마지막 목적지로 통합하며 이것은 몇가지 workflow 에
영향을 줄것입니
다.
1.
Xcode 프로젝트 트리에 .h 파일은 포함되지 않았지만 그들은 마지막 목적지 파일 시스템에 나타나고
그래서.m/.mm/.c/.cpp 의 컴파일
을 가능하게 합니다.
주의: 하위 폴더는 지원되지 않습니다.
iOS 팁
1.
Managed -> unmanaged 콜은 iOS 에서 상당이 비쌉니다. 프레임당 여러개의 기본 함수를 부르지 않도록하세요.
2.
위에서 말한 것처럼 사용자 기본 함수를 장치에서 실제 코드를 부르고 에디터에서 모의 값을 리턴하는 추가적인 C#
레이어로 감싸세요.
3.
기본 함수에서 리턴된 스트링 값은 UTF-8 로 인코딩되고 힙에 할당되어야 합니다. Mono marshaling 콜은 이것을 위해서는
무료입니다.
4.
위에서 언급한것 처럼 Xcode 의 "Classes" 폴더는 상요자 기본 코드를 두기에 좋은데 왜냐하면 프로젝트가 업데이트되도
덮어씌여지지 않기 때문입니다.
5.
기본 코드를 저장하기 좋은 또다른 곳은 에셋 폴더나 그 하위의 다른 폴더들 입니다. Xcode 프로젝트에서 참조를 기본 코드
파일에 추가합니다. "Classes" 하위 폴더에서 오른쪽 클릭 후 "Add->Existing files..."를 선택합니다.
Android
안드로이드 플러그인 빌드하기
안드로이드 플러그인을 시작하려면 Android NDK가 필요합니다. 어떻게 공유 라이브러리를 만드는지에 익숙해 지세요.
플러그인을 만드는데 C++ (.cpp)를 사용한다면 name mangling issues를 피하기 위해 함수가 C linkage와 선언되야 합니다.
extern "C" {
float FooPluginFunction ();
}
C#에서 플러그인 사용하기
일단 공유 라이브러리를 만들면 그것을 Assets->Plugins->Android 폴더에 복사합니다. 유니티는 아래와 같은 함수를 정의할때
이름으로 그것을 찾을 것입니다:
[DllImport ("PluginName")]
private static extern float FooPluginFunction ();
PluginName은 ‘lib’로 시작하거나 ‘.so’ 로 끝이나면 안되는 것을 명심하세요. 모든 기본 코드 함수를 추가적인 C#코드 레이어로
감싸기를 권합니다. 이 코드는 [[ScriptRef:Application-platform.html |
Application.platform]] 를 체크할 수 있고 실제 장치에서 실행될 때만 기본 함수를 부르며 에이터에서 실행될 때는 모의 값을
리턴합니다. 사용자는 플랫폼에 의존하는 코드 컴파일을 제어하기 위해
platform defines 를 사용할 수 있습니다.
배치
크로스 플랫폼 플러그인을 위해서는 플러그인 폴더가 몇가지 다른 플랫폼(즉 libPlugin.so 는 Android, Plugin.bundle 는 Mac 그리고
Plugin.dll 는 Windows)을 위한 플러그인을 포함합니다. 유니티가 자동으로 개발 플랫폼에 맞는 플러그인을 선택하고 플레이어에
포함합니다.
자바 플러그인 사용하기
안드로이드 플러그인 메카니즘은 또한 안드로이드 OS 와 상호작용을 가능하게 하는데 자바가 사용되는 것을 허용합니다. 자바
코드는 C#에서 직접 불릴 수 없으으로 사용자가 C#와 자바사이에서 그 콜을 해석하기 위해 기본 플러그인을 작성 합니다.
안드로이드에서 자바 플러그인 빌드하기
자바 플러그인을 만드는 것에는 몇가지 방법이 있습니다. 공통점은 필러그인에 필요한 .class 파일들을 포함하는 .jar파일로 끝난다는
것입니다. 한가지 방법은 JDK를 받는 것으로 시작해서 사용자 .java파일을 명령 라인에서 javac로 .class파일을 만들기 위해 컴파일
하고 그들을 jar 명령어 라인 툴을 이용해 .jar로 패기지화합니다. 다른 방법은 Eclipse IDE를 ADT와 함께 사용하는 것입니다.
기본 코드에서 자바 플러그인 사용하기
일단 자바 플러그인(.jar)을 만들었으면 Assets->Plugins->Android 폴더로 복사해야 합니다. 유니티는 .class파일과 나머지 자바
코드를 패키지화하고 Java Native Interface (JNI)라는 것으로 그것을 부릅니다. JNI는 두가지 방법으로 동작하는데; 자바에서 기본
코드 부르기 그리고 기본 코드에서 자바(또는 JavaVM)와 상호작용하기.
기본 코드에서 사용자 자바 코드를 찾기 위해서는 자바 VM 에 액세스 해야합니다. 다행히 그것은 매우 쉬운데 사용자의 C(++)코드에
다음과 같은 함수를 추가합니다:
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* jni_env = 0;
vm->AttachCurrentThread(&jni_env, 0);
}
이것이 C(++)에서 자바를 이용하기 전부 입니다. JNI 에 대한 완전히 설명하는 것은 이 문서의 내용을 넘어선 것이지만 클래스 정의
찾기, 생성자 (<init>) 함수 해결하기 그리고 아래와 같이 새로운 객체 인스턴스 만들기 등을 포함합니다:
jobject createJavaObject(JNIEnv* jni_env) {
jclass cls_JavaClass = jni_env->FindClass("com/your/java/Class");
// find class definition
jmethodID mid_JavaClass = jni_env->GetMethodID (cls_JavaClass, "<init>", "()V");
// find constructor method
jobject obj_JavaClass = jni_env->NewObject(cls_JavaClass, mid_JavaClass);
return jni_env->NewGlobalRef(obj_JavaClass);
// create object instance
// return object
with a global reference
}
헬퍼 클래스와 사용자 자바 플러그인 만들기
AndroidJNIHelper 와 AndroidJNI 는 JNI 사용을 쉽게해 줍니다.
AndroidJavaObject 와 AndroidJavaClass 는 많은 것을 자동화해주고 캐쉬를 사용해서 자바 콜을 빠르게 해줍니다.
AndroidJavaObject 와 AndroidJavaClass 조합은 AndroidJNI 와 AndroidJNIHelper 위에서 만들어 지고 그 안에 많은 로직이
있습니다(자동화를 다루는). 이런 클래스틀은 자바 클래스의 정적 멤버를 다루기 위해 ‘static’ 버전으로도 있습니다.
사용자가 원하는 어떤 방법을 사용해도 되지만 JNI 와 AndroidJNI 클래스 멤버 또는 AndroidJNIHelper 와 AndroidJNI 그리고 결국
최대 자동화와 편의를 위해 AndroidJavaObject/AndroidJavaClass 를 이용하세요.
•
UnityEngine.AndroidJNI는 C에 있는 JNI콜을 위한 wrapper입니다. 이 클래스의 모든 멤버는 static이며 Java Native Interface와
일대일 관계를 갖습니다.
•
UnityEngine.AndroidJNIHelper는 다음 레벨에서 사용 되는 헬퍼 기능을 제공하지만 아마 어떤 특별한 이유로 유용할 수 있기 때문에
public 함수로 사용 됩니다.
•
UnityEngine.AndroidJavaObject 와 UnityEngine.AndroidJavaClass
의 인스턴스는 각각 java.lang.Object 와 java.lang.Class (또는 서브클래스)의 인스턴스와 일대일 매핑이 됩니다. 그들은 자바와
3 가지 타입의 상호작용을 제공합니다:
•
함수 콜하기
•
필드 값 얻기
•
필드 값 지정하기
Call 은 두가지 타입이 있습니다:
'void'
리턴 타입으로 generic 타입이 사용됩니다.
Call 타입과
non-void return
Call
타입이 있습니다.
void 타입이 아닌 콜은
Get/Set 은 항상 generic 타입만을 취합니다.
Example 1
//The comments is what you would need to do if you use raw JNI
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string");
// jni.FindClass("java.lang.String");
// jni.GetMethodID(classID, "<init>", "(Ljava/lang/String;)V");
// jni.NewStringUTF("some_string");
// jni.NewObject(classID, methodID, javaString);
int hash = jo.Call<int>("hashCode");
// jni.GetMethodID(classID, "hashCode", "()I");
// jni.CallIntMethod(objectID, methodID);
여기서는 java.lang.String의 인스턴스를 만들고 있으며 초기화하고 그 스트링을 위해
hash value를 되찾습니다.
AndroidJavaObject 생성자는 적어도 하나의 파라미터를 취합니다: 인스턴스를 생성하고자 하는 클래스의 이름. 클래스 이름 뒤에
있는 것은 모두 객체의 생성자 콜을 위한 파라미터이며 이 경우 스트링은 "some_string". 그러면 Call 함수에서 왜 generic 타입을
파라미터로 사용하는 지에 대한 이유인 int 를 리턴하는 hashCode()를 사용합니다.
주의: dotted notation 를 사용해서 중첩 자바 클래스를 인스턴스화 할 수 없습니다. 내부 클래스는 $ 분별자를 사용해야하며 이것은
점과 슬래스 형식에서 모두 작동할 것입니다. 그래서 LayoutParams 클래스가 ViewGroup 클래스가 중첩되었을
때 android.view.ViewGroup$LayoutParams 또는 android/view/ViewGroup$LayoutParams 가 사용될 수 있습니다.
Example 2
위 샘플 플러그인중 하나는 어떻게 현 프로그램을 위한 캐쉬 디렉토리를 얻을 수 있는지를 보여줍니다:
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
// jni.FindClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
// jni.GetStaticFieldID(classID, "Ljava/lang/Object;");
// jni.GetStaticObjectField(classID, fieldID);
// jni.FindClass("java.lang.Object");
Debug.Log(jo.Call<AndroidJavaObject>("getCacheDir").Call<string>("getCanonicalPath"));
// jni.GetMethodID(classID, "getCacheDir", "()Ljava/io/File;"); // or any baseclass thereof!
// jni.CallObjectMethod(objectID, methodID);
// jni.FindClass("java.io.File");
// jni.GetMethodID(classID, "getCanonicalPath", "()Ljava/lang/String;");
// jni.CallObjectMethod(objectID, methodID);
// jni.GetStringUTFChars(javaString);
여기서는 of AndroidJavaObject 대신 AndroidJavaClass 로 시작하는데 왜냐하면 사용자가 com.unity3d.player.UnityPlayer의
static멤버의 액세스를 원하며 새로운 객체 생성을 윈치 않습니다(이미 Android UnityPlayer에 하나가 만들어져 있습니다). 그러면
static필드인 “currentActivity”에 액세스하지만 이번에는 generic파라미터로 AndroidJavaObject 를 사용합니다. 왜냐하면 실제 필드
타입 ([[http://developer.android.com/reference/android/app/Activity.html |
android.app.Activity]])이 java.lang.Object 위 하위 클래스이기 때문이고 어떤
non-primitive type도 AndroidJavaObject (이 룰에 스트링은 예외인데 자바에서 primitive타입이 아니라도 스트링이 직접 액세스
될수 있습니다)로 액세스 되어야 하기 때문입니다.
그런 후 캐쉬 디렉토리를 대표하는 File객체를 얻기위해 이제
[[http://developer.android.com/reference/android/content/Context.html#getCacheDir() |
getCacheDir()]]를 통해 간단히 Activity를 이동하고 스트링 표현을 얻기위해
[[http://developer.android.com/reference/java/io/File.html#getCanonicalPath() |
getCanonicalPath()]]를 부르세요.
물론 요즘엔 캐쉬 디렉토리를 얻기위해 그럴 필요가 없습니다; 저희는
Application.temporaryCachePath, [[ScriptRef:Application-persistentDataPath.html |
Application.persistentDataPath]]를 통해 프로그램의 캐쉬와 파일 디렉토리 액세스를 제공합니다.
Example 3
마지막으로 UnitySendMessage 를 사용해 어떻게 데이타를 자바에서 스크립트 코드로 보내는지에 대한 작은 트릭입닌다.
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
void Start () {
JNIHelper.debug = true;
using (JavaClass jc = new JavaClass("com.unity3d.player.UnityPlayer")) {
jc.CallStatic("UnitySendMessage", "Main Camera", "JavaMessage", "whoowhoo");
}
}
void JavaMessage(string message) {
Debug.Log("message from java: " + message);
}
}
자바 클래스인 com.unity3d.player.UnityPlayer 은 이제 static 함수인 UnitySendMessage 를 가지며 이것은 iOS 의
[[KrMain.Plugins#iPhonePlugins |
UnitySendMessage]] 와 같고 자바에서 스크립트 코드로 데이터를 보낼 때 쓸수 있습니다.
그러나 여기서 우리는 그것을 스크립트 코드에서 직접 부릅니다. 그것은 결국 자바쪽으로 메세지를 전달하며 자바쪽에서는
“JavaMessage”라는 함수가 있는 “Main Camera”이라는 이름의 객체에 메세지 전달을 위해 유니티에서 콜백 합니다.
유니티에서 자바 플러그인을 사용하는 가장 좋은 방법들
이 섹션은 주로 JNI, Java, 안드로이드 경험이 많지 않은 사람을 목표로 했기에 우리는 AndroidJavaObject/AndroidJavaClass 접근이
유니티 자바 코드와 상호작용 한다고 가정합니다.
첫번째로 알아야 할것은 AndroidJavaObject / AndroidJavaClass 에서의 모든작업은 비싸다는 것입니다(JNI 접근 처럼). managed 와
native/java 사이의 변환을 최소화 하기를 권합니다. 이것은 성능과 복잡도 모두를 위한 것입니다.
기본적으로 자바 함수가 실제 모든 작업을 하게하고 AndroidJavaObject / AndroidJavaClass 를 이용해 그 함수와의 대화를 통해
결과를 얻을 수 있습니다. JNI 헬퍼 클래스로 가능한 많은 양을 캐쉬하려 한다는 것을 아는 것은 도움이 될 것입니다.
//The first time you call a Java function like
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some_string"); // somewhat expensive
int hash = jo.Call<int>("hashCode"); // first time - expensive
int hash = jo.Call<int>("hashCode"); // second time - not as expensive as we already know the java method and can call it
straight
이것은 JIT 와 같은 방법입니다: 그것을 처음에 콜할 때는 코드가 존재하지 않아 느릴 것입니다. 다음에는 빨라집니다. 다시 말해
모든 객체의 .Call /.Get / .Set 마다 대가를 치뤄야하지만 처음으로 콜한 다음에는 대가가 적다는 말입니다. AndroidJavaClass /
AndroidJavaObject 를 생성하는 데도 대가가 따릅니다.
Mono garbage collector 는 AndroiJavaObject / AndroidJavaClass 의 생성된 모든 인스턴스를 해제해야 하는데 그것을 $$using(){}
문에 두고 가능한 빨리 지워지도록 하기를 권합니다. 그렇지 않으면 그들이 언제 지워질지 장담할 수 없습니다.
AndroidJNIHelper.debug =
true;$$ 를 설정하면 디버그 출력문이 Garbage Collector 의 행동도 보여줄 것입니다.
//Getting the system language with the safe approach
void Start () {
using (AndroidJavaClass cls = new AndroidJavaClass("java.util.Locale")) {
using(AndroidJavaObject locale = cls.CallStatic<AndroidJavaObject>("getDefault")) {
Debug.Log("current lang = " + locale.Call<string>("getDisplayLanguage"));
}
}
}
사용자는 또한 자바 객체 lingering 을 없게 하기위해 .Dispose()함수를 직접 부를수 있습니다. 실제 C# 객체는 좀더 오래 존재할
수있는데 mono 에 의해 결국 가비지 콜렉트될 것입니다.
UnityPlayerActivity 자바 코드 확장하기
유니티 안드로이드는 UnityPlayerActivity(안드로이드 유니티 플레이어 주요 자바 클래스, 유니티 iOS 의 AppController.mm 와
비슷함)의 확장이 가능합니다.
UnityPlayerActivity (UnityPlayerActivity.java 는 맥의
/Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/src/com/unity3d/player 그리고 보통
C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer\src\com\unity3d\player에서 찾을 수
있습니다)에서 유도된 새로운Activity 를 생성 함으로써 프로그램은 안드로이드 OS와 유니티 안드로이드의 어떤 또는 모든 기본
상호작용을 오버라이드할 수 있습니다.
그렇게 하기 위해서는 유니티 안드로이드에 있는 classes.jar를 찾습니다. 이것은 PlaybackEngines/AndroidPlayer/bin라고 불리는
설치 폴더(윈도우즈에서는 보통/Applications/Unity그리고 맥에서는/Applications/Unity)에서 찾을 수 있습니다. 그러면 classes.jar
파일을 새로운 활동을 컴파일하는 classpath에 추가합니다. manifest이 어떤 활동이 시작되어야 하는지 나타내듯이
새로운AndroidManifest.xml의 생성 또한 필요합니다. 그 AndroidManifest.xml 또한Assets->Plugins->Android에 위치하여야 합니다.
그 새로운 활동은 OverrideExample.java 처럼 보일 수 있습니다:
package com.company.product;
import com.unity3d.player.UnityPlayerActivity;
import android.os.Bundle;
import android.util.Log;
public class OverrideExample extends UnityPlayerActivity {
protected void onCreate(Bundle savedInstanceState) {
// call UnityPlayerActivity.onCreate()
super.onCreate(savedInstanceState);
// print debug message to logcat
Log.d("OverrideActivity", "onCreate called!");
}
public void onBackPressed()
{
// instead of calling UnityPlayerActivity.onBackPressed() we just ignore the back button event
// super.onBackPressed();
}
}
그리고 이것은 매치하는 AndroidManifest.xml 을 보여줍니다:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.product">
<application android:icon="@drawable/app_icon" android:label="@string/app_name">
<activity android:name=".OverrideExample"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
예제
Desktop
Simplest Plugin
T이것은 기본 작업(숫자 프린트, 스트링 프린트, 두개의 float더하기, 두개의 int 더하기)만 하는 프로젝트와 플러그인의 기본적인
예제입니다. 유니티 플러그인에 대해 처음으로 배우는 것이라면 이 예제를 확인하세요.
프로젝트는 here에서 찾을 수 있습니다.
이 프로젝트는 윈도우즈 와 맥 프로젝트 파일을 포함합니다.
Midi Plugin
이것은 애플의 CoreMidi API 를 이용하는 OS X 를 위한 완성된 Midi 플러그인입니다. 이것은 간단한 C API 와 C API 를 이용한
C#클래스를 제공합니다. 그 C# 클래스는 NoteOn 와 NoteOff 이벤트와 그 속도에 대한 쉬운 접근과 함께 하이 레벨의 API 를
포함합니다.
Texture Plugin
이 예제는 C++에서 OpenGL 로 직접 어떻게 이미지 데이터를 텍스쳐로 할당 하는지를 보여줍니다(유니티가 OpenGL 렌더러를
사용할 때만 가능). 이 예제는 Xcode(맥에서)와 Visual Studio(윈도우즈에서) 프로젝트 파일을 모두 포함합니다. 플러그인과 유니티
프로젝트를
here에서 찾을 수 있습니다.
iOS
Bonjour Browser Sample
A si기본 코드 플러그인을 사용하는 가단한 예제 here이 샘플은 유니티 iOS프로그램에서 어떻게 objective-C 코드를 부르는지를
보여줍니다. 이 프로그램은 아주 간단한Bonjour client를 구현합니다. 이 프로그램은 유니티 iOS프로젝트(Plugins/Bonjour.cs: 기본
코드를 위한C# 인터페이스, BonjourTest.js: 프로그램 로직을 구현한 JS 스크립트)와 XCode프로젝트를 빌드하기 위해 추가되어야할
기본 코드(에셋/코드)로 이루어져 있습니다.
Android
네이티브 플러그인 샘플 Native Plugin Sample
이 샘플은 어떻게 C 코드가 유니티 안드로이드 어플리케이션에서 호출될 수 있는지 설명합니다. 이 팩키지는 합계를 네이티브
플러그인으로 계산된 두 개의 값으로 나타내는 씬을 포함합니다. 플러그인을 컴파일 하기 위해서는 Android NDK 가 필요하다는
것을 알아두세요.
Java Plugin Sample
자바 코드의 사용 예제 here
이 샘플은 어떻게 자바 코드와 안드로이드 OS가 상호작용 하는지와 C#과 자바간에 어떻게 C++이 연결되는지를 보여줍니다.
패키지는 눌렸을 때 안드로이드 OS에서 정의된 캐쉬 디렉토리를 패치하는 버튼을 보여주는 씬을포함합니다. 플러그인을 컴파일
하려면 JDK와 Android NDK 가 모두 필요합니다.
같은 예이지만 기본 코드를 C#으로 감싸기위한 미리 빌드된 JNI라이브러리에 기반을 둔 예제 here
Command line arguments
Unity 편집기를 그것이 연 상태로 특정 태스크를 실행하도록 만들기 위해서 커맨드 라인 아규먼트와 함께 시작하는 것이 가능합니다.
이것은 자동적인 게임 빌드, 테스트 스윗 등등을 허용합니다. below 를 살펴보시기 바랍니다.
게다가 Unity 와 함께 구축되어 있는 혼자하는 게임은 어떤 커맨드 라인 파라미터를 허용합니다. below 를 살펴보시기 바랍니다.
Unity Editor command line arguments
-batchmode
Unity 를 batch 모드에서 실행합니다. 이것은 항상 그것이 어떠한 팝업 윈도우도 나타나지 않도록 함에 따라 그리고 어떠한 사람의
개입의 필요를 제거함에 따라 다른 커맨드 라인 아규먼트와 함께 결합되어 사용되야 합니다. 스크립트 코드의 실행 동안에 하나의
예외가 발생할 때 에셋 서버 업데이트는 실패하거나 또는 다른 오퍼레이션 들도 실패하고 Unity 는 즉시 1 을 리턴 코드로 하고
종료합니다.
Batch 모드에서 Unity 는 그것의 로그가 콘솔로 나가는 버전을 쓸 것입니다. 완전한 디버그 정보를 위해서 Unity 의 Log Files 를
보시기 바랍니다.
-quit
다른 커맨드 라인 아규먼트의 실행을 끝내면서 Unity 를 깨끗하게 멈춥니다.
-buildWindowsPlayer
혼자서하는 윈도우즈 플레이어를 구축합니다 (예 -buildWindowsPlayer path/to/your/build.exe).
-buildOSXPlayer
혼자서하는 윈도우즈 플레이어를 구축합니다 (eg, -buildOSXPlayer path/to/your/build.app).
-importPackage packagepath
주어진 package 를 불러옵니다. 어떠한 import 다이아로그도 보여지지 않습니다.
-createProject pathname
주어진 경로에 빈 프로젝트를 생성합니다.
-projectPath pathname
주어진 경로에 프로젝트를 오픈 합니다.
-assetServerUpdate IP[:port] projectName username password [r <revision>]
IP:port 에 의해 주어진 Asset Server 에서 프로젝트의 업데이트를 강요합니다. 포트는 선택적이로 주어지지 않았다면 그것은
스탠다드 원(10733)이 되도록 가저됩니다. 사용자가 옳은 프로젝트와 작업하고 있다는 것을 확신시키기 위해서 -projectPath
아규먼트와 함께 결합된 이 명령을 사용하는 것은 충고될 수 있습니다. 프로젝트 이름이 주어지지 않으면 Unity 에서 열어진 마지막
프로젝트가 사용됩니다. -projectPath 에 의해 주어진 경로에서 프로젝트가 존재하지 않으면 하나가 자동적으로 생성됩니다.
-executeMethod ClassName.MethodName
Unity가 시작되자마자static method를 실행하고 선택적인 에셋 서버 업데이트가 실행된 후에 프로젝트 폴더는 열려집니다. 이것은
계속적인 통합을 하기 위해 사용될 수 있습니다 : Unit 테스트, 빌드 만들기, 데이터 준비하기.사용자가 커맨드 라인 프로세스로부터
에러를 리턴하고 싶다면 사용자는 Unity가 1 과 함께 종료하도록 하는 예외를 던지거나 또는 0 이 아닌 코드와
함께 EditorApplication.Exit를 콜합니다.
-executeMethod 를 사용하기 위해서 사용자는 편집기 폴더의 스크립트와 클래스의 static 함수를 가질 필요가 있습니다.
// C# example
using UnityEditor;
class MyEditorScript
{
static void PerformBuild ()
{
string[] scenes = { "Assets/MyScene.unity" };
BuildPipeline.BuildPlayer(scenes, ...);
}
}
// JavaScript example
static void PerformBuild ()
{
string[] scenes = { "Assets/MyScene.unity" };
BuildPipeline.BuildPlayer(scenes, ...);
}
-exportPackage
주어진 경로에서 하나의 패키지를 export 합니다. 사용법:-exportPackage exportAssetPath exportFileName
Where:exportAssetPath: unity 프로젝트에서 export 하는 폴더입니다
exportFileName: 패키지 이름입니다
현재 그것은 전체 폴더만을 export 하는 것을 지원합니다.
-nographics (Windows only)
Batch 모드에서 실행할 때 그래픽 디바이스를 초기화하지 않아야 합니다. 이것은 GPU 를 가지지 않는 기계 위에서 사용자의 자동
워크플로우를 실행하도록 하는 것을 가능하게 합니다.
Example usage
Back 모드에서 Unity 를 실행합니다. MyEditorScript.MyMethod 메서드를 실행하고 완료시 종료합니다.
Windows:
C:\program files\Unity\Editor>Unity.exe -quit -batchmode -executeMethod MyEditorScript.MyMethod
Mac OS:
/Applications/Unity/Unity.app/Contents/MacOS/Unity -quit -batchmode -executeMethod MyEditorScript.MyMethod
Batch 모드에서 Unity 를 실행합니다. 주어진 프로젝트 경로를 사용하고 에셋 서버로부터 업데이트 합니다. 모든 에셋이 다운로드
되어지고 에셋 서버로부터 불려진 후에 주어진 메서드를 실행합니다. 메서드가 실행을 마치면 자동적으로 Unity 를 종료합니다.
/Applications/Unity/Unity.app/Contents/MacOS/Unity -batchmode -projectPath ~/UnityProjects/AutobuildProject
-assetServerUpdate 192.168.1.1 MyGame AutobuildUser l33tpa33 -executeMethod MyEditorScript.PerformBuild quit
Unity Standalone Player command line arguments
Unity 와 함께 구축된 혼자서하는 플레이어는 커맨드 라인 아규먼트를 이해합니다:
-batchmode
게임을 "headless" 모드로 실행합니다. 게임은 어떤 것도 보여주지 않을 것이면 사용자 입력을 허용하지 않을 것입니다. 이것은
networked games 의 실행하는 서버를 위해서 대부분 유용합니다.
-force-opengl (Windows only)
심지어 Direct3D 가 가능할 때도 게임이 렌더링을 위해서 OpenGL 을 사용하도록 만듭니다. 보통 Direct3D 이 사용됩니다;
그리고 Direct3D 9.0c 이 가능하지 않는 경우에만 OpenGL 이 사용됩니다.
-single-instance (Windows only)
게임의 한 인스턴스가 한 번에 실행되도록 합니다. 또다른 게임이 벌써 실행되고 있다면 그것을 -single-instance 와 함께 다시
시작하는 것은 기존에 존재하고 있는 것에 포커스를 둘 것입니다.
-nolog (Windows only)
Output 로그를 생성하지 않습니다. 주로 output_log.txt는 실행될 수 있는 게임 옆에 *_Data 폴더에 씌여집니다.
거기서 Debug.Log 결과는 프린트 됩니다.
-force-d3d9-ref (Windows only)
Direct3D의 "Reference" 소프트웨어 렌더러를 사용해서 게임을 실행하도록 만듭니다. DirectX SDK는 이것이 작동하도록 하기
위해서 설치될 필요가 있습니다. 이것은 자동 테스트 스윗을 만들기 위해 매우 유용합니다. 거기서 사용자는 렌더링이 무슨 그래픽
카드이냐에 상관없이 정확하게 같은 것을 하는 것을 확실시하고 싶어합니다.
-adapterN (Windows only)
게임이 또다른 디스플레이에서 전체 스크린으로 실행되도록 허용합니다. 거기서 N 은 디스플레이 숫자를 의미합니다.
-popupwindow (Windows only)
윈도우는 팝업 윈도우로서 생성될 것입니다 (프레임 없이).
Shaders
유니티의 모든 렌더링은 Shaders 로 이루어집니다. 쉐이더는 그래픽 하드웨어가 렌더링을 위해 어떻게 셋업되는지 설정하게 해주는
스크립트 입니다. 유니티는 60 개가 넘는 내장된 쉐이더를 가지고 있는데 사용자가 그들을 확장할 수도 있습니다. 그 내장된
쉐이더는 Built-in Shader Guide 에 문서화 되어있습니다.
유니티에서 쉐이더는 세가지 방법으로 만들어 질수 있습니다:
•
표면(Surface) 쉐이더 가 가장 좋은 방법일 것입니다. 쉐이더가 빛, 그림자, 프로젝터 등과 상호작용할 필요가 있다면 표면 쉐이더를
사용하세요. 표면 쉐이더는 또한 복잡한 쉐이더를 간단한 방법으로 만들수 있게 해주는데 이것은 추상화의 높은 레벨 입니다.
대부분의 표면 쉐이더에서 빛은 연기되는 형태(사용자 정의된 빛모델에서는 예외가 있음)로 계산되는데 이것은 쉐이더가 여러 빛과
효율적으로 상호작용하는 것을 가능하게합니다. 몇줄의 Cg/HLSL 로 쉐이더를 작성할수 있으며 더 많은 양의 코드가 그것에서 자동
생성됩니다.
•
꼭지점과 조각 쉐이더 는 사용자가 표면 쉐이더가 다룰 수 없는 색다른 효과를 내고 싶을 때, 쉐이더가 빛과 상호작용할 필요가 없을
때, 또는 이미지 효과를 낼 때 필요한 쉐이더 입니다. 이런 방법으로 만들어진 쉐이더는 필요한 효과를 만드는데 가장 유연한
방법(표면 쉐이더도 자동으로 수많은 꼭지점과 조각 쉐이더로 전환됩니다)이지만 대가를 치루어야 하는데 더 많은 코드를
만들어야하며 빛과 상호작용하기가 까다롭습니다. 이 쉐이더도 Cg/HLSL 로 쓰여집니다.
•
고정 기능 쉐이더는 프로그래밍 쉐이더를 지원하지 않는 오래된 하드웨어에 필요합니다. 사용자의 게임이 오래된 하드웨어나 간단한
모바일 플랫폼에서 실행될 때 게임이 무언가 감지가능한 것을 렌더링하게 하기위해서 이 고정 기능 쉐이더가 다른 쉐이더를
대체하기 위한 수단으로 사용될수 있습니다. 이 쉐이더는 Microsoft 의 .FX 파일이나 NVIDIA 의 CgFX 와 비슷한 ShaderLab 이라는
언어로만 만들어집니다.
어떤 타입을 선택하던 쉐이더 코드의 상당 부분은 쉐이더 구조를 정리하는 ShaderLab 으로 변환됩니다. 이것은 아래와 같습니다:
Shader "MyShader" {
Properties {
_MyTexture ("My Texture", 2D) = "white" { }
// other properties like colors or vectors go here as well
}
SubShader {
// here goes the 'meat' of your
// - surface shader or
// - vertex and fragment shader or
// - fixed function shader
}
SubShader {
// here goes a simpler version of the SubShader above that can run on older graphics cards
}
}
ShaderLab reference 에서 ShaderLab 문법의 기본적인 개념을 읽고 아래에 있는 튜토리얼을 해보기를 권합니다.
튜토리얼에는 다른 종류의 쉐이더를 위한 많은 예제가 있습니다. 특히 표면 쉐이더의 더 많은 예제를 위해서는 Resources
section에서 유니티 내장 쉐이더의 소스코드를 볼 수 있습니다. 유니티의 Image Effects 패키지는 많은 흥미있는 꼭지점과 조각
쉐이더를 포함하고 있습니다.
쉐이더의 개요를 읽고 shader reference 도 확인하세요!
•
Tutorial: ShaderLab & Fixed Function Shaders
•
Tutorial: Vertex and Fragment Shaders
•
Tutorial: Surface Shaders
Shaders: ShaderLab & 고정함수 쉐이더
이 지침서는 사용자가 자신만의 쉐이더를 생성하여 사용자 게임을 더 멋있게 만들 수 있는 방법을 가르쳐줍니다!
유니티는 ShaderLab 이라고 불리는 강력한 쉐이딩과 머티리얼 언어를 갖추고 있습니다. 스타일 상으로 이는 CgFX 와 Direct3D
Effects (.FX) 언어와 비슷하여 - Material 을 디스플레이 하는데 필요한 모든 것을 표현하여 줍니다.
쉐이더(Shader)는 유니티의 Material Inspector 와 여러 종류의 그래픽 하드웨어 성능을 타깃으로 구현한 다수 쉐이더의
구현(SubShaders)에서 보여주는 속성으로, 그 각각은 그리고 완전한 그래픽 하드웨어 랜더링 상태, 고정 함수 파이프라인 설정
혹은 사용할 버텍스(vertex)/프래그먼트(fragment) 을 설명합니다. Vertex 와 fragment 프로그램은 고수준의 Cg/HLSL 프로그램
언어입니다.
이 지침서는 고정 함수(fixed function)과 프로그램 가능한(programmable) 파이프라인을 둘 다 사용하는데 쉐이더를 어떻게 작성할
지를 알려줍니다. 저희는 이 지침서의 독자가OpenGL과 Direct3D 랜더링 상태, 고정 함수와 프로그램 가능한 파이프라인에 대한
기초적인 이해가 있고 Cg, HLSL 혹은 GLSL 프로그램 언어에 대해서도 일부 알고 있다고 가정합니다. 일부 쉐이더 지침서와
문서는NVIDIA와 AMD 개발자 사이트에서도 찾을 수 있습니다.
시작하기
새로운 쉐이더를 생성하려면, 메뉴 바에서 Assets->Create->Shader 을 선택하든지 혹은 현존하는 쉐이더를 복제하여 거기서
시작하면 됩니다. 새로운 쉐이더는 Project View 에서 그것을 더블클릭 하여 편집할 수 있습니다.
가장 기본적인 쉐이더부터 시작해봅니다:
Shader "Tutorial/Basic" {
Properties {
_Color ("Main Color", Color) = (1,0.5,0.5,1)
}
SubShader {
Pass {
Material {
Diffuse [_Color]
}
Lighting On
}
}
}
위 간단한 쉐이더는 가장 기본적으로 가능한 것을 보여줍니다. Main Color 라 불리는 컬러 속성을 설정하고 장미색조의 ((red=100%
green=50% blue=50% alpha=100%) 디폴트 값을 할당합니다. 그리고 Pass 를 호출하여 해당 오브젝트를 랜더링 하고, Pass 에서는
diffuse 머티리얼 컴포넌트를 _Color 속성으로 설정하고 pre-vertex lighting 을 켭니다.
이 쉐이더를 시험하려면, 머티리얼을 하나 생성하고, 드롭다운 메뉴에서(Tutorial->Basic)해당 쉐이더를 선택한 다음 그 머티리얼을
어느 오브젝트에 할당합니다. 머티리얼 인스펙터에 있는 색깔을 수정하고 변화를 감상하십시오. 이제 좀 더 복잡한 것으로 시도해
봅니다!
기초적 버텍스 라이팅(Basic Vertex Lighting)
만일 사용자가 기존의 복잡한 쉐이더를 열면, 언뜻 전체를 이해하기가 어려울 수 있습니다. 일단 사용자가 첫 발을 뗄 수 있도록
유니티에 내장되어 출품되는 VertexLit 이라는 쉐이더를 해부해 보겠습니다. 이 쉐이더는 표준적인 버텍스당 (per-vertex) 라이팅을
실행하기 위해 고정 함수 파이프라인(fixed function pipeline)을 사용합니다.
Shader "VertexLit" {
Properties {
_Color ("Main Color", Color) = (1,1,1,0.5)
_SpecColor ("Spec Color", Color) = (1,1,1,1)
_Emission ("Emmisive Color", Color) = (0,0,0,0)
_Shininess ("Shininess", Range (0.01, 1)) = 0.7
_MainTex ("Base (RGB)", 2D) = "white" { }
}
SubShader {
Pass {
Material {
Diffuse [_Color]
Ambient [_Color]
Shininess [_Shininess]
Specular [_SpecColor]
Emission [_Emission]
}
Lighting On
SeparateSpecular On
SetTexture [_MainTex] {
constantColor [_Color]
Combine texture * primary DOUBLE, texture * constant
}
}
}
}
} 모든 쉐이더들은 Shader 라는 키워드에서 시작해서 해당 쉐이더의 이름을 나타내는 문자열로 이어집니다. 이 이름은 Inspector 에
나타나는 이름입니다. 이 쉐이더의 모든 코드는 이 후 중괄호{ } 사이에 위치 되어야 합니다. (이것을 블록(block)이라 부릅니다).
•
이름은 짧고 의미 있어야 하지만 .shader 파일 이름과 동일해야 하는 것은 아닙니다.
•
유니티에서 쉐이더를 서브메뉴에 두려면, 빗금(slash, /)를 사용합니다. 예를 들면, MyShaders/Test 는 MyShaders 라 불리는
서브메뉴 안에 Test 를 보여주고 혹은 MyShaders->Test 로 표시합니다.
쉐이더는 Properties 블록으로 구성되어 있고 그 뒤에는 SubShader 블록이 따라옵니다. 각각의 블록은 다음 섹션에 설명되어
있습니다.
속성
쉐이더 블록의 시작 부분에서 사용자는 Material Inspector. 에서 아티스트가 편집 할 수 있는 어떤 속성이든 설정할 수 있습니다.
VertexLit 의 예에서 해당 속성은 이렇게 됩니다:
해당 속성들은 Properties 록 내에서 별개의 라인들로 리스트 되어 있습니다. 각각의 속성은 내부 이름(Color, MainTex)으로
시작하고, 괄호 뒤에는 인스펙터에서 보여주는 이름과 속성의 타입이 나옵니다:
사용 가능한 타입의 종류는 Properties Reference 을 참조하십시오. 디폴트 값은 속성의 타입에 따라 다릅니다. 컬러의 사례에서는,
디폴트 값은 네 콤포넌트 벡터이어야 합니다.
이제 속성 설정은 끝났고, 실제 쉐이더를 작성 할 준비가 되었습니다.
쉐이더 본문(The Shader Body)
본격적으로 시작하기 전에, 쉐이더의 기본 구조를 정해 봅니다.
서로 다른 그래픽 하드웨어는 다른 성능을 가지고 있습니다. 예를 들어, 어떤 그래픽 카드는 프래그먼트 프로그램을 지원 하지만
어떤 하드웨어는 지원하지 않습니다; 어떤 것은 pass 당 네 텍스처를 펼칠 수 있지만 어떤 것은 두 개나 하나만 가능한 것 등입니다.
사용자의 하드웨어가 무엇이든 최대한 효율적으로 사용할 수 있도록, 모든 SubShaders 를 점검하여 해당 하드웨어가 지원하는 첫
번째 것을 사용합니다.
Shader "Structure Example" {
Properties { /* ...shader properties... }
SubShader {
// ...subshader that uses vertex/fragment programs...
}
SubShader {
// ...subshader that uses four textures per pass...
}
SubShader {
// ...subshader that uses two textures per pass...
}
SubShader {
// ...subshader that might look ugly but runs on anything :)
}
}
이 시스템은 유니티가 모든 현존하는 하드웨어를 지원하고 각각의 품질을 최상으로 보장하는 것을 가능케 합니다. 하지만 이는 또한
결과적으로 긴 쉐이더를 만들게 됩니다.각 SubShaders 블록 내에서 사용자는 모든 pass 가 공유하는 랜더링 상태를 설정하고,
랜더링 pass 자체를 정합니다. 사용 가능한 명령어의 전체 리스트는 SubShader Reference 에서 찾을 수 있습니다.
Passes
각 subshader 는 pass 의 모음입니다. 각 pass 에는 object geometry 가 랜더링 되므로 적어도 하나 이상의 pass 가 존재해야 합니다.
저희 VertexLit 쉐이더에는 단 하나의 pass 만 있습니다:
// ...snip...
Pass {
Material {
Diffuse [_Color]
Ambient [_Color]
Shininess [_Shininess]
Specular [_SpecColor]
Emission [_Emission]
}
Lighting On
SeparateSpecular On
SetTexture [_MainTex] {
constantColor [_Color]
Combine texture * primary DOUBLE, texture * constant
}
}
// ...snip...
하나의 pass 설정된 어떤 명령이든 해당 geometry 를 특정한 방법으로 랜더링 하기 위한 그래픽 하드웨어를 설정합니다. 위 사례의
Material 블록은 우리의 속성 값을 고정 함수 라이팅 머티리얼 설정과 바인딩 합니다. Lighting On 이라는 명령은 표준 버텍스
라이팅을 켜고, SeparateSpecular On 은 스페큘러 하이라이트(specular highlight)에 별개의 색깔 사용을 허용합니다.
이 모든 명령들이 지금까지는 고정 함수 OpenGL/Direct3D 하드웨어 모델과 직접적으로 연관됩니다. 여기에 관해 더 자세한 정보를
보려면OpenGL red book을 참조하십시오.
다음 명령, SetTexture 는 아주 중요한 명령입니다. 이 명령들은 사용자자 쓰고자 하는 텍스처와 어떻게 그것을 조합하고 합치고
우리의 랜더링에 적용할 지를 설정합니다. SetTexture 명령 다음에는 우리가 사용하고자 하는 속성 이름이 따라옵니다(_MainTex
여기). 그 다음은 combiner block 이 오는데 이는 해당 텍스처를 어떻게 적용되는지를 정합니다.
이 블록에서 Color of the Material, _Color 이라 이름하는 상수 컬러 값을 정합니다. 이 상수 컬러는 아래에서 사용될 것 입니다.
다음 명령에서는 해당 텍스처를 어떻게 컬러 값과 조합 할 것인지를 명시합니다. 이는 Command 명령어를 사용하여 해당 텍스처를
다른 것과 혹은 한 색깔과 어떻게 섞을 것인지를 명시합니다:
Combine ColorPart, AlphaPart
여기서 ColorPart 와 AlphaPart 는 각각 색깔 조합(RGB)과 알파(A) 콤포넌트를 설정합니다. 만일 AlphaPart 가 생략된다면,
ColorPart 와 같은 조합을 사용합니다.
위 VertexLit 의 사례에서:
Combine texture * primary DOUBLE, texture * constant
여기서 texture 는 현재의 텍스처 (여기서는_MainTex)로부터 오는 컬러입니다. 이것은 primary 버텍스 컬러와 곱해집니다(*).
Primary 컬러는 버텍스 라이팅 컬러이며, 위의 머티리얼 값에서 계산되어 집니다. 마지막으로, 그 결과를 2 배로 곱해 빛의 강도를
강화합니다(DOUBLE). The alpha value 알파값(코머 뒤에)은 texture 를 constant 값(위 constantColor 에 설정)과 곱한 것입니다.
또 다른 자주 사용되어지는 combiner 모드는 previous 라 불립니다(이 쉐이더에는 미 사용). 이것은 모든 이전 SetTexture 단계의
결과이며, 여러 텍스처와 그리고/혹은 컬러가 서로 합성하는데 사용되어 집니다.
요약
저희 회사의 VertexLit 쉐이더는 표준 버텍스 라이팅을 설정하고 텍스처 combiner 를 설정하여 랜더링 후 빛의 강도가 배가
시킵니다.더 많은 pass 를 쉐이더에 넣으면 차례로 하나씩 랜더링 될 것 입니다. 하지만 지금으로써는 이미 원하는 효과를
얻었으므로 불필요합니다. 우리는 단 하나의 SubShader 만 필요하며 고급 사양을 사용하지 않습니다 – 바로 이 쉐이더는 유니티가
지원하는 모드 그래픽 카드에서 작동할 것 입니다.쉐이더는 우리가 생각할 수 있는 가장 기본적은 쉐이더 입니다. 우리는 어떠한
일부 하드웨어에 특정적인 오퍼레이션을 사용하지도 않았고, ShaderLab 과 Cg 가 제공해야 하는 특별하거나 멋진 명령을 더
사용하지도 않았습니다.
다음 장 next chapter 에서는 계속해서 Cg 언어를 사용하여 맞춤형 버텍스 & 프로그램을 작성하는 방법을 설명하겠습니다.
나무
Desktop
유니티의 Terrain Engine 에는 나무(Tree)를 위한 특별 지원사항이 있습니다. 사용자는 Terrain 에 수천 개의 나무를 배치할 수 있고
실제 프레임 속도로 게임 내에서 랜더링을 할 수 있습니다. 이는 카메라 주변에 있는 나무들은 3D 로 랜더링을 하고 먼 곳에 있는
나무들은 2D 빌보드(Billboard)로 옮겨서 작동 됩니다. 먼 곳에 위치한 빌보드는 그것이 보여지는 여러 각도에 따라 자동으로 방향을
바꾸며 업데이트를 합니다. 이러한 전이 시스템은 나무의 미세환경을 성능 면에서 아주 손쉽게 하여 줍니다. 사용자는 mesh-tobillboard 전이의 매개 변수들을 변경하여 완전히 컨트롤 할 수 있으며, 이렇게 하면 사용자가 필요로 하면 최상의 성능을 얻을 수
있습니다.
아름다운 환경을 만들기 위해 사용자는 수많은 나무를 손쉽게 페인트 할 수 있습니다
나무 추가하기
Inspector 에서 Place Trees 버튼을 선택하십시오.
in the.
사용자의 terrain 에 나무를 배치하기 전에, 사용자는 해당 나무를 사용가능 한 나무 라이브러리에 추가하여야 합니다. 이 작업을
하려면 Edit Trees button->Add Tree 를 클릭하십시오. Add Tree 대화 창이 나타날 것 입니다.
추가 나무 대화창
사용자의 Project View 에서 나무를 선택하고 그 것을 Tree 변수로 드래그합니다. 사용자가 해당 나무에 "바람에 구부러지는"동영상
효과를 약간 추가하고 싶다면 Bend Factor 를 편집 할 수 있습니다. 준비가 되면 Add 를 클릭하십시오. 선택된 Inspector 에서
나무가 나타날 것입니다.
인스펙터에 새로이 추가된 나무가 선택된 것으로 나타납니다
사용자는 원하는 만큼 나무를 추가할 수 있습니다. 각각의 나무는 사용자의 Terrain 에 배치되기 전에 인스펙터에서 선택 가능하여야
합니다.
현재 선택된 나무는 항상 푸른색으로 하이라이트 됩니다
나무 배치하기
도구를 사용하는 동안, 해당 나무를 배치하려면 Terrain 의 어디든 클릭하십시오. 그 나무를 지우려면 Shift 버튼을 누르고 해당
Terrain 을 클릭하십시오.
페인트 브러쉬 도구를 사용하면 손쉽게 나무를 색칠할 수 있습니다
나무를 배치할 때 사용자가 택할 수 있는 몇 가지 옵션이 있습니다.
Property:
Function:
Brush Size
나무 배치 브러쉬의 미터 단위 반경.
Tree Spacing
나무 사이 나무 너비의 비율.
Color Variation
각 나무간에 허용된 색상 차이 값.
Tree Height
에셋과 비교한 각 나무의 높이 조절.
Height Variation
각 나무간에 허용된 높이 차이 값.
Tree Width
에셋과 비교한 각 나무의 넓이 조절.
Width Variation
각 나무간 허용된 넓이 차이 값.
나무 색칠 팁
각자 다른 브러쉬 크기가 다른 영역 크기를 커버합니다
사용자가 그리는 나무밀도를 조절하기 위하여 Tree Spacing 조절
나무 편집하기
추가된 나무를 위해 들여온 매개변수 어느 것이라도 변경하려면, 상세 사항을 선택하고 Edit Trees button->Edit Detail 을 선택하거나,
혹은 사용자가 편집하고 싶은 나무를 더블클릭 하십시오. 그러면 Edit Tree 대화 창이 뜨고, 사용자는 그 중 어느 설정이라도 변경 할
수 있습니다.
집단 배치하기
사용자가 만일 나무를 그리기 보다는 그냥 전체 숲은 생성하고 싶다면, 그냥 Terrain->Mass Place Trees 을 사용하면 됩니다. 여기서,
사용자는 Mass Place Trees 대화 창을 보게 될 것 입니다. 사용자는 원하는 나무의 숫자를 설정하고 즉석에서 배치 할 수 있습니다.
사용자의 Terrain 추가된 모든 나무가 해당 집단 배치에 사용될 것 입니다.
10,000 나무가 한번에 배치됨
소스 에셋 업데이트 하기(Refreshing Source Assets)
만일 사용자가 사용자의 나무 에셋 소스파일을 업데이트 하였다면, 수동으로 이를 Terrain 에 다시 들여오기를 실행하여야 합니다.
이렇게 하려면 Terrain->Refresh Tree and Detail Prototypes 을 실행 합니다. 이것은 사용자가 소스 에셋을 변경하고 저장한 후에
실행되며, 사용자 Terrain 의 나무들을 즉시 변경 할 것 입니다.
나무 생성하기
나무들은 두 가지 방법으로 terrain engine 에 생성 될 수 있습니다:
첫 번째 방법은 유니티에 내장된 Tree creator 을 사용하는 것이고 두 번째 방법은 유니티와 호환되는 제 3 업체의 모델링 프로그램을
사용하는 것 인데 이 경우에는 모든 나무는 두 개의 Materials 을 가진 하나의 메쉬(mesh)로 이루어져야 합니다. 하나는 나무
기둥(trunk)이고 하나는 잎(leaves)을 위해서 입니다.
성능을 높이려면, 평균 나무 하나 당 triangle 개수는 2000 개 이하로 유지하여야 합니다. Triangle 이 작을수록 성능은 더 좋아집니다.
나무 메쉬의 pivot point 는 정확하게 나무의 루트이어야 하며, 그것은 나무가 배치되면 표면과 만나는 지점이 됩니다.
나무들은 Nature/Soft Occlusion Leaves 와 Nature/Soft Occlusion Bark shader 를 사용하여야 합니다. 이러한
쉐이더(shaders)를 사용하려면 사용자는 해당 나무를 "Ambient-Occlusion"이라는 이름을 포함한 특수 폴더에 두어야 합니다.
사용자가 해당 폴더에 모델을 넣고 다시 들여오기(reimport)를 실행하면, 유니티가 그 나무를 위한 부드러운 주변 오클루젼(soft
ambient occlusion)을 계산합니다. "Nature/Soft Occlusion" 폴더가 이 정보를 필요합니다. 이를 따르지 않으면 나무가 검은 부분이
나와서 이상해 보입니다.
또한 유니티는 "Terrain Demo.unitypackage"에 몇 개의 고품질의 나무들은 같이 출시하였습니다. 사용자는 이 나무들의 바로 사용자
게임에 활용 할 수 있습니다.
로 폴리(Low Poly) 나무 사용하기
하나의 나무에 잎들을 만들려면 단 6 개의 triangles 로 이루어져 있고 꽤 많은 만곡을(curvature) 보이고 있습니다. 더 많은 만곡을
원한다면 더 많은 triangles 을 추가 할 수 있습니다. 하지만 중요한 것은, 나무를 만들 때는 quads 가 아니라 triangles 을 가지고
만들어야 합니다. 만일 사용자가 quads 을 사용하면 가지에 똑 같은 만곡을 얻으려면 기본 두 배수의 triangles 이 필요하다는 것
입니다. 나무는 많은 수의 다각형으로 인해 그 자체로 많은 fillrate 을 소비하며 거의 모든 것은 알파(alpha)로 인해 보이지 않습니다.
성능 저하를 막기 위하여 이러한 것은 피해야 하나 물론 목표는 밀집한 나무들을 만드는 것입니다. 이것이 바로 Oblivion 의 나무가
진가를 발휘하는 이유 중 하나 입니다. 이 나무들은 너무나 밀집하여 잎 사이로 볼 수 조차 없습니다.
나무의 충돌 설정
사용자의 나무가 콜라이더(collider)를 활용하게 하고 싶다면 그것은 쉽습니다. 사용자가 나무 에셋 파일을 들여올 때, Scene View
내에서 인스턴스화 하고 Capsule Collider 를 추가하여 변경한 후, 해당 GameObject 을 새 Prefab 로 만들면 됩니다. 그런 후 사용자
Terrain 에 나무들을 추가할 때, 사용자는 Capsule Collider 가 부착된 해당 나무 Prefab 을 추가하면 됩니다. 사용자는 나무와의
충돌을 추가할 경우에만 Capsule Colliders 을 사용할 수 있습니다.
나무를 충돌하게 하기.
Terrain 콜라이더 인스펙터
사용자의 나무를 리지드바디와(rigid bodies) 충돌하게 하고 싶다면, 반드시 Create Tree Colliders 박스를 확인하여야 합니다. 아니면
사용자 오브젝트는 사용자가 생성한 나무들을 관통해 버릴 것 입니다.
iOS
이 기능들은 현재는 iOS 타깃에는 사용할 수 없습니다.
Android
이 기능들은 현재는 안드로이드 타깃에는 사용할 수 없습니다.
Graphics Emulation
유니티 에디터로 작업할 때 낮은 성능의 그래픽 하드웨어를 에뮬레이션 할 수 있습니다. 사용자 쉐이더(shader)와 렌더링(rendering)
효과들을 작성할 때 매우 유용합니다. 이는 누군가가 가지고 있을지 모르는 8 년 된 그래픽카드에 게임이 어떤 식으로 보일지 빠르게
테스트 할 수 있습니다.
그래픽 에뮬레이션을 가능하게 하려고 하면 Edit->Graphics Emulation 로 가서, 에뮬레이션 레벨을 선택합니다.
주의: 현재의 타켓 플랫폼에 따라 사용 가능한 에뮬레이션 옵션들은 변합니다. Publishing builds page 에서 더 많은 관련 정보를 찾을
수 있습니다.
그래픽 에뮬레이션 가능하게 하기
기술적 세부사항
그래픽 에뮬레이션은 지원하는 그래픽의 capabilities 을 제한 합니다. 하지만, 그래픽 하드웨어의 performance 은 에뮬레이션 하지
않습니다. 에디터 안의 게임은 그래픽 카드에서의 표현(render)을 따릅니다. 에뮬레이션의 질을 줄임에 따라 더 많은 기능이
불가능하게 됩니다.
에뮬레이션은 그래픽의 기능들을 점검 할 수 있는 빠른 방법이지만, 게임은 실제적인 하드웨어에서 테스트 해야 합니다. 이는
실질적인 성능, 특정 그래픽 카드와 운영체계, 또는 드라이버의 버전을 드러내게 됩니다.
에뮬레이션 레벨들(Emulation Levels)
그래픽 에뮬레이션 레벨들은 다음과 같습니다:
Desktop
No
에뮬레이션이 수행되지 않습니다.
Emulation
그래픽카드를 쉐이더 모델(Shader Model) 3.0 레벨의 기능으로 에뮬레이션 합니다. 긴 정점 & 조각 쉐이더
SM3.0
SM2.0
(Radeon
프로그램들(Long vertex & fragment shader programs) 과 내부 탑재된 그림자들을 지원합니다.
쉐이더 모델 2.0 기능들, “ATI Radeon” 스타일. 정점과 조각 프로그램들(Vertex & fragment programs), 내부 탑재
그림자들, ATI 텍스트 조각 쉐이더 확장(ATI text fragment shader extension), 8 질감 단위(8 texture units).
9500)
SM2.0
(GeForce
쉐이더 모델 2.0 기능들, NVIDIA GeForce 스타일. 정점 & 조각 프로그램들(Vertex & fragment programs), 내부 탑재된
그림자들, 4 질감 단위(4 texture units).
FX)
SM1.4
(Radeon
쉐이더 모델 1.4 기능들. 정점 프로그램들(Vertex programs), ATI 텍스트 조각 쉐이더 확장(ATI text fragment shader
extension), 6 질감 단위(6 texture units). 지원되지 않는 것들:조각 프로그램들(fragment programs), 내부 탑재
8500)
그림자들.
SM1.1
쉐이더 모델 1.1 기능들. 정점 프로그램들, 4 질감 단위(4 texture units). 지원되지 않는 것들:조각 프로그램들(fragment
(GeForce 3)
programs), 내부 탑재 그림자들.
DX7 (Radeon
DirectX 7 레벨 기능들. 정점 프로그램들(일반적으로 소프트웨어 모드에서의), 3 질감 단위. 지원되지 않는 것들: 조각
7500)
프로그램들(fragment programs), 내부 탑재 그림자들.
DirectX 7 레벨 기능들. 정점 프로그램들(일반적으로 소프트웨어 모드에서의), 2 질감 단위, 질감의 사이즈는 2048 로
DX7
(GeForce 2)
제한, cubemap 의 사이즈는 512 로 제한. 지원되지 않는 것들: 조각 프로그램들, 내부탑재 그림자들, 볼륨 질감들, 몇몇
복잡한 질감 혼합 모드들.
DirectX 6 레벨 기능들. 2 질감 단위(2 texture units), 질감의 사이즈는 1024 로 제한. 지원되지 않는 것들: 정점과 조각
DX6
프로그램들(vertex & fragment programs), 내부 탑재 그림자들, 큐브맵들(cubemaps), 볼륨 질감들(rectangle textures),
세 개의 보강된 질감 혼합 모드들, DOT3 질감 혼합 모드들(DOT3 texture combine modes), 프로젝트 된 질감들.
모든 사람들이 잊어버린 (오래된) 그래픽 카드를 에뮬레이션 합니다. 하나의 질감 단위, 질감의 사이즈는 512 로
제한하며, 정점 빛(vertex light)의 개수는 4 로 제한합니다. 지원되지 않는 것들: 정점과 조각 프로그램들(vertex &
Dinosaur
fragment programs), 내부 탑재 그림자들, 큐브맵들(cubemaps), 표현질감들(RenderTextures), 볼륨 질감들(volume
textures), 직사각형 질감들, 세 개의 보강된 질감 혼합 모드들, DOT3 질감 혼합 모드들(DOT3 texture combine
modes), 프로젝트 된 질감들.
iOS
에뮬레이션이 수행되지 않습니다.
No Emulation
iPhone 4, 3GS, iPad
iPhone 3GS 를 에뮬레이션 하거나 OpenGL ES 2.0 가 구동되는 더 신형인 iOS 하드웨어를 에뮬레이션
합니다.
OpenGL ES2.0
iPhone 4, 3GS, iPad
iPhone 3GS 를 에뮬레이션 하거나 OpenGL ES 1.1 이 구동되는 더 신형인 iOS 하드웨어를 에뮬레이션
합니다.
OpenGL ES1.1
Generic OpenGLES1.1 (4
OpenGL ES 1.1 이 구동되는 iOS hardware 를 부분 에뮬레이션 합니다. 유니티 에디터를 구동하거나
texture stages)
4 개의 질감 합성 기 (texture combiner)를 지원하는 구형의 카드와 드라이버를 연동할 때 유용합니다.
iPhone 3GS 보다 오래된 iPhone/iPod 터치 하드웨어를 에뮬레이션 합니다. 2 개의 질감 합성 기를
iPhone (MBXlite)
지원합니다.
Android
No Emulation
Generic OpenGL ES2.0
에뮬레이션이 수행되지 않습니다.
OpenGL ES 2.0 를 연동하는 하드웨어를 에뮬레이션 합니다.
Partially emulates Android hardware running OpenGL ES 1.1 를 연동하는 Android 하드웨어를
Generic OpenGLES1.1
(4 texture stages)
부분적으로 에뮬레이션 합니다. 유니티 에디터를 연동하거나 오직 4 개의 질감 합성 기를 지원하는
오래된 카드나 드라이버를 연동하는데 유용합니다.
그래픽 카드가 특정 에뮬레이션 레벨을 지원하지 않는 경우, 그 레벨은 불가능(disable)하게 됩니다. 예를 들어, Intel GMA950 (Intel
915/945/3000) 카드는 쉐이더 모델 3.0 (Shader Model 3.0)을 지원하지 않으므로, 해당 레벨의 에뮬레이션을 하는 방법이 존재하지
않습니다.
네트워크 에뮬레이션
유니티의 네트워킹 기능 중에 낮은 대역폭을 가진 지역 유저의 게임 경험을 테스트하기 위해 느린 인터넷 속도를 에뮬레이트 할 수
있는 기능이 있습니다.
네트워크 에뮬레이션을 활성화하기 위해서는 Edit->Network Emulation 으로 가서 가서 원하는 접속 속도를 선택합니다.
네트워크 에뮬레이션 활성화
기술 세부 사항
네트워크 에뮬레이션은 Network 과 NetworkView 클래스를 위한 네트워크 에 패킷을 보내는 것을 지연합니다. 핑은 인공적으로 다른
모든 옵션들을 위해 확대된 것이며 그 확대된 값은 에뮬레이트 접속 속도가 느려질수록 증가합니다. Dial-Up 설정에서는 최악의
접속을 시뮬레이트 하기위해 패킷 드랍핑과 변화가 있습니다. 서버나 클라언트에서 에뮬레이션은 동일할 것입니다.
네트워크 에뮬레이션은 오직 Network 와 NetworkView 클래스에만 영향을 주며 .NET 소켓으로 쓰여진 네트워크 코드는 바뀌거나
에뮬레이트 되지 않을 것입니다.
웹플레이어의 보안 샌드박스(Security Sandbox of the Webplayer)
Desktop
유니티 3.0 에서 웹 플레이어는 Adobe Flash player�에서 사용한 것과 매우 흡사한 보안 모델을 구현합니다. 이 보안 제한은 오직 웹
플레이어와 엑티브 구축 타깃이 웹 플레이어인 경우의 편집기에만 적용됩니다. 해당 보안모델은 몇 가지 부분으로 이루어집니다:
•
사용자의 unity3d 파일을 호스트 하는 것을 제외한 도메인에 접근하는 데이터에 대한 제한.
•
소켓(Socket) 사용에 대한 일부 제한사항.
•
출입 금지로 간주하는 메소드(파일 삭제 등)의 호출의 불허함.
•
사용자가 직접 쓰기를 실행하지 않은 클래스 내의 사적/내부적 메소드의 호출에 대한 System.Reflection 의 사용을 불허함.
현재는 처음 2 개의 보안 모델만 편집기(Editor)에 적용하였습니다. 다음에서 a detailed list of which methods / classes are available
in the webplayer를 확인하십시오.
유니티에 내장된 웹 플레이어 네트워킹 기능 (UnityEngine.Network, UnityEngine.NetworkView 클래스들 등)은 영향을 받지
않습니다.
이 문서는 어떻게 하면 사용자의 콘텐츠가 유니티 웹플레이어의 3.0 버전과 계속 작동할 수 있게 하는지를
설명합니다.
•
the Unity API reference for information about the WWW class를 참조하십시오.
•
the .NET API reference for information about the .NET Socket class를 참조하십시오.
비록 WWW 클래스와 소켓이 같은 정책 스키마(policy schema)를 사용하지만 그 둘은 완전히 별개의 시스템입니다. WWW 정책은
해당 정책이 주관하는 웹 서비스에서만 승인사항을 설정하지만, 소켓 정책은 모든 TCP/UDP 소켓 연결에 다 적용됩니다.
유니티 편집기는 "Emulate Web Security"라는 기능과 함께 제공되는데 이는 웹 플레이어의 보안 모델을 시행합니다. 이것을
사용하면 익숙한 편집기에서 쉽게 문제점을 감지해 낼 수 있습니다. 사용자가 해당 설정을 찾으려면 Edit->Project Settings>Editor 을 통하면 됩니다.
WWW 클래스 사용의 의미
유니티의 웹 플레이어는 "crossdomain.xml"라는 http 에 제공하는 정책파일이 사용자가 WWW 클래스를 통하여 접근하고자 하는
도메인에 존재하리라 전제합니다 (unity3d 파일을 호스트 하는 동일한 도메인 내에 있다면 필요치 않습니다).
예를 들면, 테트리스 게임을 생각하면, 다음 url 에서 호스트 한다면:
http://gamecompany.com/games/tetris.unity3d
다음 url 에서 고득점 리스트를 사용해야 한다면:
http://highscoreprovider.net/gethighscore.php
이 경우, 사용자는crossdomain.xml파일을 다음http://highscoreprovider.net/crossdomain.xml과 같은
highscoreprovider.net도메인의 루트에 둘 필요가 있을 것 입니다.
해당 crossdomain.xml 의 내용은 Flash 플레이어에 사용한 포맷으로 되어 있습니다. 아마 사용자는 그 자리에 이미
crossdomain.xml 파일이 존재하는 것을 볼 가능성이 아주 높습니다:
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>
그 파일이 http://highscoreprovider.net/crossdomain.xml에 놓이면, 해당 도메인의 소유자는 웹서버의 그 콘텐츠가 모든 도메인에서
접근하는 어떤 플레이어에 의해서도 사용이 가능함을 선언합니다.
유니티 웹 플레이어는 <allow-http-request-headers-from domain> and <site-control permitted-cross-domain-policies>
태그는 지원하지 않습니다. crossdomain.xml 파일은 ASCII 파일이어야 함을 주의하십시오.
소켓 사용의 의미:
유니티 웹 플레이어는 특정 호스트에 연결하려면 소켓 사용 정책을 필요로 합니다. 그 정책은 디폴트로는 타깃 호스트의 843 번
포트에서 호스팅 되지만 다른 포트에서 호스팅 할 수 도 있습니다. 디폴트가 아닌 포트를 사용하는 경우 기능적으로 달라지는
것은 Security.PrefetchSocketPolicy() API call을 통하여 수동으로 불러와야 하며, 만일 1024 번 보다 높은 번호의 포트에서 호스팅
된다면 해당 정책은 1024 번보다 높은 포트에서만 접근을 허가할 수 있게 됩니다.
디폴트 포트를 사용하면 다음과 같이 동작합니다: 유니티 웹 플레이어가 호스트와 TCP 소켓 접속을 시도합니다. 우선 호스트 서버가
요청하는 접속을 수락할 지를 확인합니다. 이 작업은 843 번 포트에 TCP 소켓을 하나 열고 해당 새 접속을 통해 소켓 정책을
수신하기를 기다립니다. 다음 유니티의 웹 플레이어는 호스트 서버의 정책이 해당 접속을 허가하는지를 확인하고 만일 그렇다면
에러 없이 진행합니다. 이 과정은 사용자의 코드에는 보이지 않게 발생하므로 해당 보안 모델을 사용하기 위해 사용자 코드를 변경할
필요가 없습니다. 소켓 정책의 한 예를 들면 다음과 같습니다:
<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" to-ports="1200-1220"/>
</cross-domain-policy>"
이 정책인 실질적으로 말하는 것은 “어떤 도메인에서 오는 콘텐츠이든 포트 1200-1220 사이에서는 자유롭게 소켓 접속을 생성 할 수
있습니다”라는 것 입니다. 유니티 웹 플레이어는 이를 준수하고, 이 포트 범위 밖에서 소켓 접속을 시도하면 거절할 것
입니다(SecurityException 을 보냅니다).UDP 접속을 사용할 시의 해당 정책 역시, TCP 와 비슷한 방식으로 시행될 필요가 있을 경우
자동 소환 될 수 있습니다. 차이점은 TCP 에서 자동 소환은 사용자가 무언가에 Connect 를 실행할 때 발생합니다(사용자가 해당
서버에 접속 허락을 보장하는). 하지만 UDP 는 비 연결식이므로(connectionless) 이것 역시 사용자가 API call 을 실행하여 데어나르
주거나 받을 때 발생합니다(사용자가 해당 서버와 데이터를 수신/발신이 허용되는지를 확인합니다).소켓 정책에 사용된 포맷은 일부
태그가 지원되지 않는다는 것을 제외하면 Flash player 에 사용된 것과 동일합니다. 유니티 웹 플레이어는 "*" 만을 도메인 설정에
유효한 값으로 지원하고, "to-ports" 설정은 필수사항입니다.
<?xml version="1.0" encoding="ISO-8859-1"?>
<!ELEMENT cross-domain-policy (allow-access-from*)>
<!ELEMENT allow-access-from EMPTY>
<!ATTLIST allow-access-from domain CDATA #REQUIRED>
<!ATTLIST allow-access-from to-ports CDATA #REQUIRED>
해당 소켓 정책은 TCP 와 UDP 연결 타입 둘 다에 적용되므로 TCP 와 UDP 트래픽 모두 하나의 정책 서버에서 제어할 수
있습니다.사용자 편의를 위하여, 포트 번호 843 번을 그냥 모니터링만 하는 작은 프로그램 하나를 저희가 제공합니다; 여기서
연결요청을 수신하면 해당 프로그램은 유효한 소켓 정책을 보낼 것 입니다. 서버코드는 유니티 설치 폴더의
Tools/SocketPolicyServer 에 있습니다. Mac 에서는 이미 구축된 실행 파일이 작동할 수 있으면 그 이유는 그것이 Mono
실행파일이기 때문입니다. 이를 실행하려면 "mono sockpol.exe"라고 그냥 입력하면 됩니다.외부업체의 네트워크 주로 멀티플레이어
게임 네트워킹에 사용되는 라이브러리(libraries)의 경우에 피어 투 피어 기능에 의존하지 않고 전용서버를 이용하는 한은 이러한
요구사항에 부합하여 작동할 수 있어야 합니다.
감시 소켓(Listening sockets)
Y 사용자는 웹 플레이어에서는 서버 역할을 할 수가 없으므로 감시소켓(listening sockets)을 생성 할 수 없습니다. 그러므로 웹
플레이는 서로 직접 통신(peer 2 peer) 할 수는 없습니다. TCP 소켓을 사용하면 사용자는 소켓 정책시스템이 허용하는 한 원격
종점(endpoints)만 연결 할 수 있습니다. UDP 에서도 동일하게 작동하지만 비 연결(connectionless) 방식 프로토콜이므로 개념이
약간 달라 사용자가 패킷을 수신/발신하기 위해 연결/감시(listen) 등을 수행할 필요가 없습니다. 이러한 정책은 서버가 초기에
allow-access-from domain 가 달린 유효한 정책으로 답신을 보냈을 때만 사용자는 해당 서버로부터 패킷을 받을 수 있게
강제함으로써 작동합니다.
이러한 성가신 정책이 왜 필요할까요?
이와 같은 소켓과 WWW 정책은 유니티 웹 플레이어를 설치하는 사용자를 보호하기 위해 존재하는 보안 기능입니다. 이러한 제한을
가하지 않으면, 다음과 같은 공격이 가능해지게 됩니다:
•
밥(Bob)은 백악관 직원입니다.
•
프랭크(Frank)는 사악합니다. 그는 게임인 척 하는 유니티 게임을 제작하지만,
백그라운드에서는http://internal.whitehouse.gov/LocationOfNuclearBombs.pdf. i에 WWW 작업을 실행합니다.
internal.whitehouse.gov는 인터넷에서는 접속 할 수가 없는 서버이지만 밥은 백악관 직원이므로 그의 워크스테이션 컴퓨터에서는
접근 가능합니다.
•
프랭크가 http://frank.com/secretDataUploader.php로 pdf 데이터들을 전송합니다.
•
플랭크는 해당 게임을 http://www.frank.com/coolgame.unity3d에 둡니다
•
프랭크가 어떻게 하여 밥이 같이 게임 할 것을 설득합니다.
•
밥이 게임을 합니다.
•
해당 게임이 조용히 기밀문서를 다운받아 프랭크에게 보냅니다.
이 경우 WWW와 소켓 보안이 지원되면 이러한 공격은 실패하게 됩니다. 왜냐하면 pdf 을 다운받기 전에
유니티가http://internal.whitehouse.gov/crossdomain.xml에게 “당신의 서버에 있는 이 데이터가 일반에게 공개되어도 되는
것인가요?” 하고 질문을 던집니다. 웹 서버에 crossdomain.xml을 둔다는 것은 그 질문에 대한 대답으로 볼 수 있습니다. 이 사례의
경우, of internal.whitehouse.gov의 시스템 오퍼레이터는 이러한 파일을 두지 않을 것이고, 그러므로 유니티는 해당 pdf을 다운받지
않을 것 입니다.비록 불편하지만 유니티 웹 플레이어를 설치하는 사용자를 보호하기 위하여 유니티 개발자들은 콘텐츠 개발 시
이러한 보안 대책을 세울 필요가 있습니다. 동일한 제한이 모든 주요 플러그인 기술에도 있습니다(Flash, Silverlight, Shockwave).
예외(Exceptions)
웹 플레이어 사용자를 보호하는 것과 콘텐츠 개발자의 편의성 사이에 균형을 잘 맞추기 위해서, 저희는 위에서 설명한 보안
메커니즘에 예외를 두었습니다.- 사용자는 crossdomain.xml 파일이 없는 서버로부터 이미지 다운로드를 할 수 있습니다. 하지만
해당 이미지를 사용하여 사용자가 할 수 있는 것은 사용자의 장면(scene)에 이것을 텍스처로 사용하는 것뿐입니다. 사용자는 그것에
GetPixel()을 사용할 수 없으며 스크린으로부터 되 읽어 올 수도 없습니다. 이 두 가지 모두 SecurityException 이 발생할 될 것입니다.
이러한 논리는 이미지를 다운받는 것은 괜찮으나 콘텐츠 개발자가 그것에 대한 접근은 불가하다는 것 입니다. 그러므로 사용자는
그것을 디스플레이 할 수는 있지만 해당 이미지의 데이터를 다른 서버로 전송할 수는 없습니다.
Visual Studio C# Integration
What does this feature get me?
더욱 정교한 C# 개발 환경.
Smart autocompletion, 소스 파일에서의 컴퓨터의 도움을 받는 변화, smart syntax highlighting, 등을 생각해 보세요.
What's the difference between Express and Pro?
VisualStudio C# 2010 은 Microsoft제품 입니다. 이것은 Express 와Profesional 에디션을 나옵니다.
Express 에디션은 무료이고 http://www.microsoft.com/express/vcsharp/에서 다운로드 받을 수 있습니다.
Professional 에디션은 무료가 아니며 다음에서 더 많은 정보를 찾을 수 있습니다: http://www.microsoft.com/visualstudio/enus/products/professional/default.mspx
유니티의 VisualStudio 통합은 두가지 컴포넌트를 가집니다:
1) VisualStudio 프로젝트 파일을 생성, 관리하는 유니티. Express 과 Profesional 와 작업하세요.
2) 사용자가 스크립트를 더블클릭할때 유니티가 자동으로 VisualStudio 를 엽니다. Professional 에서만 작동합니다.
I've got Visual Studio Express, how do I use it?
•
유니티 메뉴에서 Assets->Sync VisualStudio Project 를 선택합니다.
•
새롭게 생성된 사용자 유니티 프로젝트의 .sln 파일을 찾으세요(사용자 에셋 폴더위 상위 폴더).
•
Visual Studio Express 로 파일을 여세요.
•
이제 사용자는 모든 스크립트 파일을 수정할 수 있으며 그것을 사용하기 위해서 유니티로 돌아오세요.
I've got Visual Studio Profesional, how do I use it?
•
유니티에서 Edit->Preferences 로 가서 Visual Studio 가 사요자의 preferred 외부 에디터로 선택 되었는지 확실히 합니다.
•
사용자 프로젝트에서 C# 파일을 더블클릭하세요. Visual Studio 가 자동으로 사용자 파일을 엽니다.
•
파일을 편집, 저장하며 유니티로 돌아갈 수 있습니다.
A few things to watch out for:
•
Visual Studio 가 자신의 C# 컴파일러와 같이 나오고 이것을 사용자 c# 스크립트에 에러가 있는지 확인 할 때 사용됩니다. 유니티는
아직 자신의 C# 컴파일러 스크립트 컴파일을 합니다. Visual Studio 의 컴파일러를 사용하는 것은 아직 유용한데 왜냐하면 에러가
있을 때 매번 유니티로 바꿀 필요가 없기 때문입니다.
•
Visual Studio 의 C#컴파일러는 유니티의 것보다 좀더 많은 기능을 가지고있습니다. 이 말은 어떤 코드는(특히 새로운 C#기능들)
Visual Studio 에서 에러가 없지만 유니티에서는 있을 수 도 있습니다.
•
유니티는 자동으로 Visual Studio .sln 과 .csproj 파일을 생성하고 관리합니다. 누군가 유니티에서 파일을 추가/리네임/이동/제거하면
유니티는.sln 과 .csproj 파일을 다시 생성합니다. 사용자는 Visual Studio 에서 파일을 추가할 수 있습니다. 유니티는 그 새로운 파일을
불러오고 프로젝트 파일을 재생성하며 이 새로운 파일을 추가하여 그것을 만듭니다.
•
• 유니티는 에셋 서버 엡데이트 또는 SVN 업데이트 이후에는 Visual Studio 프로젝트 파일을 재생성하지 않습니다. 사용자는
유니티에게 메뉴의 Assets->Sync VisualStudio Project 를 통해 수동으로 Visual Studio 프로젝트 파일 재생성을 요청할 수 있습니다.
Using External Version Control Systems with Unity
Unity 는 사용자의 프로젝트의 쉬운 통합 버전 관리를 위한 Asset Server add-on 상품을 제안합니다. 사용자가 어떠한 이유로 Unity
에셋 서버를 사용할 수 없다면, Subversion, Perforce 또는 Bazaar 처럼 다른 버전 컨트롤 시스템에서 사용자의 프로젝트를 저장하는
것이 가능합니다. 그러나 그것은 사용자 프로젝트의 어떤 매뉴얼적인 초기 셋업을 필요로하고 에셋을 움직이고 다시 이름짓는 것은
Unity 내부가 아니라 사용자의 버전 컨트롤 클라이언트를 사용해서 수행되어야 합니다.
외부 버전 컨트롤은 Unity Pro 기능입니다.
사용자의 프로젝트를 체크하기 전에 사용자는 Unity 에 외부의 버전 컨트롤 시스템에서 에셋을 저장하는 것과 함께 그것을
호환성있게 만들기 위해 프로젝트 구조를 약간 변경하라고 말합니다. 이것은 어플리케이션 메뉴에서 Edit->Project Settings>Editor 를 선택하는 것에 의해 실행되고 Enable 버튼을 클릭하는 것에 의해 외부 버전 컨트롤 지원을 활성화 합니다. 이것은
Unity 에 의해 필요되어지는 부기 정보를 포함하는 Assets 디렉토리에서 모든 에셋을 위한 텍스트 파일을 생성할 것입니다. 그
파일은 그것이 결합된 에셋의 전체 이름이 되는 첫 번째 부분과 함께 .meta 파일 확장자를 가질 것입니다. 버전 컨트롤 시스템에서
에셋을 움직이고 다시 이름지을 때 사용자가 .meta 파일을 그에 따라 움직이고 다시 이름짓게 하도록 확인해야 합니다.
버전 컨트롤 시스템에서 프로젝트를 체크할 때 사용자는 적어도 시스템으로 Assets 디렉토리를 추가해야 합니다. 사용자가
프로젝트를 트랙하고 세팅을 구축하고 싶은 경우에 사용자는 또한 Library 폴더를 추가하고 이러한 파일들을 그 폴더안에 추가할
필요가 있습니다:
•
EditorBuildSettings.asset
•
InputManager.asset
•
ProjectSettings.asset
•
QualitySettings.asset
•
TagManager.asset
•
TimeManager.asset
•
AudioManager.asset
•
DynamicsManager.asset
•
NetworkManager.asset
Library 디렉토리에 위치한 어떠한 다른 파일 또는 디렉토리도 추가하지 말아야 합니다. 새로운 에셋을 생성할 때 에셋과 그
연관된 .meta 파일 둘 모두 버전 컨트롤에 추가되는지를 확인해야 합니다.
Example: Creating a new project and importing it to a Subversion repository.
첫째로, 우리가 svn://my.svn.server.com/에 서브 버전 저장소를 가지고 있고 svn://my.svn.server.com/MyUnityProject 에
새로운 프로젝트를 생성하고 싶다고 가정해 봅시다. 그 때 시스템에 초기 import 를 생성하기 위해서 이러한 스텝을 따라야 합니다:
1.
Unity 내부에 새로운 프로젝트를 생성하고 그것을 InitialUnityProject 으로 부릅니다. 사용자는 여기에 어떠한 초기
에셋도 추가할 수 있고 후에 그들을 추가할 수 있습니다.
2.
Edit->Project Settings->Editor 에서 Meta files 은 활성화 합니다.
3.
Unity 종료합니다(우리는 모든 파일이 저장되었다고 확신하기 위해 이것을 합니다).
4.
사용자의 프로젝트 폴더 except 내부에 Library 디렉토리의 내용을 삭제합니다.
o
EditorBuildSettings.asset
o
InputManager.asset
o
ProjectSettings.asset
o
QualitySettings.asset
o
TagManager.asset
o
TimeManager.asset
o
AudioManager.asset
o
DynamicsManager.asset
o
NetworkManager.asset
5.
프로젝트 폴더를 서브 버전으로 불러옵니다. 사용자가 커맨드 라인 클라이언트를 사용하고 있다면 이것은 사용자의 초기
프로젝트가 위치해 있는 곳에 디렉토리로 부터 이것처럼 행해집니다:
svn import -m"Initial project import" InitialUnityProject svn://my.svn.server.com/MyUnityProject
성공적이면 프로젝트는 서브 버전으로 불려져야 하고 사용자는 사용자가 원한다면 InitialUnityProject 를 삭제할 수
있습니다.
6.
서브 버전으로부터 프로젝트를 확인합니다
svn co svn://my.svn.server.com/MyUnityProject
그리고 라이브러리 폴더 내에서 에셋 파일들이 버전이 정해졌는지 확인합니다(Step 4).
7.
Optional: Library 디렉토리 내에서 버전이 정해지지 않은 파일을 위해 무시 필터를 셋업합니다:
svn propedit svn:ignore MyUnityProject/Library
서브 버전은 텍스트 편집기를 오픈할 것입니다. 이것들을 제외하고 라이브러리 폴더의 모든 파일을 추가합니다:
o
EditorBuildSettings.asset
o
InputManager.asset
o
ProjectSettings.asset
o
QualitySettings.asset
o
TagManager.asset
o
TimeManager.asset
o
AudioManager.asset
o
DynamicsManager.asset
o
NetworkManager.asset
8.
왼쪽 Alt 키나 또는 Option 을 누르는 동안 그것을 시작하는 것에 의해 Unity 와 함께 우리의 확인된 프로젝트를 오픈합니다.
프로젝트를 오픈하는 것은 step 4 에서 Library 디렉토리로 부터 삭제된 잃어버린 파일들을 재생성할 것입니다.
9.
마지막으로 변화를 커밋합니다. 프로젝트는 지금 셋업되어야 하고 준비되어야 합니다:
svn ci -m"Finishing project import" MyUnityProject
분석(Analytics)
Unity 에디터는 저희에게 익명으로 사용관련 데이터를 보내게 되어있습니다. 이 정보는 에디터의 질을 향상시키는데 사용되어
집니다. 이 분석은 Google Analytics 을 사용하여 수집되어 집니다. Unity 는 구글에서 제공되는 URI 를 호출하게 됩니다. URI 의
URN 은 어떤 에디터의 기능이나 이벤트가 사용되어 졌는지에 관한 자세한 사항 들을 포함하고 있습니다.
수집된 정보의 예제
아래는 Unity 가 수집하는 정보들의 예제들 입니다.
어떤 메뉴 아이템들이 사용 되어졌는가.만약 어떤 메뉴 아이템은 거의 사용되어지지 않았다면 저희는 미래에 그 메뉴 시스템을
간략화 할 수있을 것입니다.
빌드 시간.빌드가 얼마나 걸리는지 수집함으로써 저희가 정확한 코드를 최적화할 수 있게 됩니다.
Lightmap baking.빛맵(lightmap)을 베이크(bake)하는데 얼마나 걸리는지에 대한 정보는 저희가 이 분야를 최적화하기 위해 얼마의
시간을 사용해야하는지에 대한 결정을 내리는데 도움을 줄것입니다.
분석 비활성화 (Disabling Analytics)
만약 Unity 에 익명의 데이타를 보내기를 원치 않으면 분석 내용을 보내는 기능을 비활성화 하실 수 있습니다. 비활성를 위해서는
Unity Preferences General tab 에 있는 체크 박스를 해제하시면 됩니다.
Editor analytics in the preferences pane.
Check For Updates
유니티는 업데이트가 가능한지를 확인합니다. 이 확인은 유니티가 시작될 때나 사용자가 Help-> Check for Updates 를 선택했을 때
일어납니다. 이 업데이트 확인은 현재 유니티의 개정 번호(About Unity 대화 상자의 버전 이름 옆에 괄호에 나타나는 다섯 숫자)를
업데이트 서버에 보내고 그 서버는 최선 버전과 비교를 합니다. 만약 새로운 버전으 유니티가 있으면 다음의 대화상자가 보여집니다:
새로운 버전의 유니티 다운로드가 가능할 때 보여지는 대화 상자.
만약 사용 중인 버전이 최신 버전이라면 다음의 대화상자를 보여줍니다:
유니티가 최신 버전으로 업데이트 되었을 때 보여지는 대화 상자.
새로운 버전을 다운로드 받을 수 있는 사이트로 가지위해서는 Download new version 버튼을 누르세요.
Update Check Frequency
서버로 부터의 응답은 언제 다음 업데이트를 확인해야하는지에 대한 제안하는 시간 간격을 포함합니다. 이것은 유니티가
업데이트가 예상되지 않을 때 업데이트 확인을 덜 자주 하도록 하는 것을 가능하게 합니다.
Skipping Update Versions
사용자가 개발 중간이면 새로운 버전의 유니티의 업데이트를 원하지 않을 수도 있습니다. 유니티 에디터 업데이트 확인 대화 상자의
Ticking the Skip this version 버튼은 유니티가 사용자에게 업데이트에 관해 말하는 것을 막아줍니다.
Disabling the Update Check
업데이트 확인을 비 활성화 하는것은 가능하지 않습니다. 대화 상자의 Check For Updates 박스는 유니티 시작시 사용자가
업데이트(가능할 때) 알림을 받을 것인지를 제어합니다. 사용자가 Check For Updates 옵션을 선택하지 않았어도 사용자는 Help>Check 를 이용해 업데이트 여부를 확인 가능합니다.
문제 해결
이 섹션은 유니티를 사용하면서 생기는 문제들을 언급합니다. 문제를 겪고 있는 플랫폼을 선택해 주세요.
Desktop
MonoDevelop 에서 디버그 버튼이 비활성화 되어 있어요!
•
이것은 MonoDevelop 가 유니티 실행 파일을 찾을 수 없을 때 입니다. MonoDevelop 의 환결 설정에서 Unity/Debugger 섹션으로 가서
어디에 유니티 실행 파일이 있는지 입력하세요.
Mono Develop 에서 웰컴 페이지를 없앨 방법은 없나요?
•
네, 있습니다. MonoDevelop 환경 설정에서 Visual Style 섹션에 가서 "Load welcome page on startup"의 체크를 해제 하세요.
Geforce 7300GT on OSX 10.6.4
•
지연 렌더링이 비활성화 되어있는데 왜냐하면 재료가 Geforce 7300GT on OX 10.6.4 에서 보여지지 않기 때문입니다. 이것은
버그가 있는 비디오 드라이버 때문입니다.
Windows x64 에서 스크립트가 NullReferenceException 를 발생키기면 크래쉬 됩니다
•
Windows Hotfix #976038를 적용하세요.
그래픽
프레임속도 와/또는 시각적 인공물 늦추기.
•
이것은 비디오 카드의 드라이버가 최신 것이 아니면 생길 수 있습니다. 그래픽 카드 제공자에 의한 최신 공식 드라이버를 설치하세요.
그림자
그림자가 보이질 않아요!
•
그림자는 유니티 프로에서만 지원이 됩니다. 물론 Projector 같은 간단한 그림자 함수는 가능합니다.
•
그림자는 특정 그래픽 하드웨어 지원을 필요로 합니다. 좀더 많은 정보는 Shadows 를 보세요.
•
그림자가 완전히 비활성화 되지 않으면 Quality Settings 를 보세요.
•
그림자는 현재 안드로이드와 iOS 에는 지원되지 않습니다.
어떤 객체는 그림자를 내지도 받지도 않습니다
첫째, Renderer 는 자신의 그림자에 그림자 받는 것에는 Receive Shadows 를 그림자를 내는 것에는 Cast Shadows 를 가져야
합니다(둘다 기본 입니다).
다음으로 불투명한 객체만이 그림자를 내고 받을수 있습니다. 즉 내장된 Transparent 나 Particle 쉐이더를 사용하면 그림자를 볼 수
없을 것입니다. 대부분의 경우 Transparent Cutout 쉐이더에 가능합니다(펜스나 생물 객체, 등등). 만약 사용자 정의 Shaders 를
사용한다면 그 쉐이더는 pixel-lit 이고 Geometry render queue 를 사용하여야 합니다. VertexLit 쉐이더를 사용하는 객체는
그림자를 받지 않습니다(그러나 낼수는 있습니다).
마지막으로 픽셀 빛 많이 그림자를 냅니다. 만약 어떤 빛이 씬에 몇 개의 빛이 있건 항상 그림자를 내기를 원한다면 Force
Pixel 렌더 모드를 설정하세요(Light 를 보세요).
iOS
iOS 장치에서의 문제 해결
유니티 iOS 에디터에서는 문제가 없다가 실제 장치에서는 작동하지 않는 알려진 케이스들이 있습니다. 그 문제는 주로 코드나
컨텐츠 퀄리티와 관련되어 있습니다. 이 챕터에서는 가장 흔한 경우를 설명합니다.
Xcode 3.2.x fails to build application with error "libiPhone-lib.a, missing required architecture i386 in file
Undefined symbols: "Register_UnityEngine_Input_GetMouseButtonDown()", referenced from:
RegisterAllStrippedInternalCalls() in RegisterMonoModules.o
이 빌드 에러는 보통 Player Settings 에서 non-simulator SDK 가 선택되면 발생하는데 나중에 Xcode 에서는 SDK 가 시뮬레이터로
바뀝니다. 시뮬레이터 빌드를 실행하기 위해서는 Player Settings 에서 simulator SDK 를 선택해야 합니다.
Xcode 4.x fails to build application with error "No architectures to compile for (ARCHS=armv6,
VALID_ARCHS=i386)."
현재 유니티는 Xcode 4.x 에 대한 제한된 지원을 하고 있고 최종 프로그램을 빌드하려면 약간의 수동 작업의 노력이 필요합니다.
빌드하고 실행하면 유니티 iOS 가 생성한 Xcode 프로젝트를 엽니다 하지만 이것은 적절한 빌드 타겟와 적절한 목표 장치를
선택하지 못합니다. 장치에서 테스트를 위해 빌드한다면 "Unity-iPhone"과 맥에 연결된 iOS 장치를 빌드 타겟으로 선택합니다.
시뮬레이터에서 테스트를 위해 빌드한다면(주의: Player Settings 에서 적절한 SDK 가 필요합니다) "Unity-iPhone-simulator"와
적절한 시뮬레이터 장치를 선택해야합니다.
얼마의 시간이 지나면 게임이 멈춥니다. Xcode 가 상태바에 "interrupted"를 보여줍니다.
이에는 몇 가지 이유가 있을 수 있습니다. 보통 아래와 같습니다:
1.
스크립트 에러. 초기화된 변수 사용하기 등.
2.
타사의 컴파일된 라이브러리 사용하기. 그런 라이브러리는 iOS SDK 링커에서 문제를 일으키고 랜덤 크래시를 만듭니다.
3.
Serializable 스크립트 속성에 파라미터로 generic type 을 value types 과 사용할 때(like List<int>, List<SomeStruct>,
List<SomeEnum>).
4.
코드 스트리핑이 활성화 되어있을 때 반사 사용하기.
5.
native plugin interface 에서의 에러(managed code method signature 가 native code function signature 와 맞지 않음).
자세한 사항은 XCode 디버거 콘솔을 검토해 봐야 합니다. Xcode 디버거 콘솔은 Xcode 메뉴의 Run->Console 에서 접근 가능합니다.
Xcode 콘솔은 "Program received signal: “SIGBUS” 또는 EXC_BAD_ACCESS 에러를 보여줍니다.
이 메세지는 사용자 프로그램이 Null Reference Exception 을 받으면 보통 iOS 장치에서 나타납니다. 무엇이 잘못 되었는지 알아내는
두 가지 방법이 있습니다:
Managed stack traces
유니티 버전 3.4 이후로 Null Reference Exception 를 핸들하는 프로그램이 포함되어 있습니다. AOT 컴파일러는 객체 함수나 필트가
접근될 때마다 널 참조를 작은 체크를 가지고 있습니다. 이 기능은 사용자 스크립트 성능에 영향을 주고 이것이 오직 개발
빌드에서만 활성화된 이유입니다(기본 라이센스 사용자는 Build Settings 대화창에서 "development build"를 활성화 한것으로
충분합니다. 프로 라이센스 사용자는 추가로 "script debugging" 옵션을 체크해야 합니다).모든 것이 제대로 설정이 되었고 .NET
코드에서 에러가 발생하면 더 이상 EXC_BAD_ACCESS 를 하지 않습니다. 대신 .NET 익셉션 텍스트가 Xcode 콘솔에
보여집니다(또는 사용자 캐치문에 잡힙니다). 보통 결과물은:
Unhandled Exception: System.NullReferenceException: A null value was found where an object instance was required.
at DayController+$handleTimeOfDay$121+$.MoveNext () [0x0035a] in DayController.js:122
위에서는 DayController 클래스의 coroutine 처럼 작동하는 handleTimeOfDay 함수에 문제가 있습니다. 또한 이 샘플
"DayController.js:122"처럼 스크립트 코드이면 정확한 코드라인을 볼 수 있을 것입니다. 다음 코드에 해당합니다:
Instantiate(_imgwww.assetBundle.mainAsset);
보통 이것은 스크립트 코드가 WWW 클래스가 성공적으로 에셋 번들을 다운로드 했는지 적절히 체크를 하지 않고 그 필드에
접근하면 발생합니다.
Native stack traces
Native stack traces 는 에러 조사에 좀더 강력한 툴입니다. 또한 보통 이 에러가(하드웨어 메모리 액세스) 발생하면 더 이상 진행이
되지 않습니다. native stack trace 를 얻기 위해서 타입 스레드가 Xcode 디버거 콘솔을 제외한 모든 곳에 적용됩니다. 스택
트레이스를 주의 깊게 조사하세요. 아마 어디에서 에러가 일어났는지 힌트를 줄 것입니다. 아마 아래와 같은 것을 볼 것입니다:
...
Thread 1 (thread 11523):
#0 0x006267d0 in OptionsMenu_Start ()
#1 0x002e4160 in wrapper_runtime_invoke_object_runtime_invoke_void__this___object_intptr_intptr_intptr ()
#2 0x00a1dd64 in mono_jit_runtime_invoke (method=0x18b63bc, obj=0x5d10cb0, params=0x0, exc=0x2fffdd34) at
/Users/mantasp/work/unity/unity-mono/External/Mono/mono/mono/mini/mini.c:4487
#3 0x0088481c in MonoBehaviour::InvokeMethodOrCoroutineChecked ()
...
무엇보다 "Thread 1"를 위한 스택 트레이스를 찾아야 합니다. 이것은 메인 스레드 입니다. 스택 트레이스의 첫 라인은 에러가
일어나는 곳을 가르쳐줍니다. 이 예제는 NullReferenceException 이 "OptionsMenu" 스크립트의 "Start"함수 안에서 발생했음을
알려줍니다. 이 함수의 구현을 주의 깊게 보는것은 문제의 원인을 파악하는데 도움이 될 것입니다. 보통 NullReferenceExceptions 은
Start 함수에서 초기화 순서에 대한 잘못된 가정이 만들어질 때 발생합니다. 어떤 경우에는 디버거 콘솔에 부분적인 스택
트레이스가 보여집니다:
Thread 1 (thread 11523):
#0 0x0062564c in start ()
이것은 사용자 프로그램을 위한 릴리즈 빌드 중에 native symbol 이 삭제된 것을 알려줍니다. 완전한 스택 트레이스는 아래의 지시를
따라 얻을 수 있습니다:
•
Xcode 프로젝트에서 디버그 설정을 선택합니다.
•
모든 타겟을 클리어 합니다.
•
빌드하고 실행합니다.
•
위 설명처럼 스택 트레이스를 얻습니다.
EXC_BAD_ACCESS 가 외부 라이브러리가 유니티 iOS 프로그램에 링크될 때만 발생합니다.
이것은 보통 외부 라이브러리가 ARM Thumb instruction set 과 함께 컴파일될 때 발생합니다. 현재 그런 라이브러리는 유니티 iOS 와
호환되지 않습니다. 이 문제는 라이브러리를 Thumb instruction 없이 다시 컴파일해서 쉽게 해결할 수 있습니다. 라이브러리의
Xcode 프로젝트를 위한 자세한 지시:
•
Xcode 메뉴에서 "Project" -> "Edit active target"
•
"Target Info"대화 창에서 "Configuration: All Configurations"선택
•
탐색 필드에 "thumb" 입력
•
"Compile for Thumb" 설정이 나타나면 체크를 해제하고 라이브러리 리빌드 .
만약 라이브러리 소스를 볼 수 없으면 라이브러리 제공자에게 thumb 버전이 아닌 라이브러리를 요청합니다.
Xcode 콘솔이 크래쉬 직후 "WARNING -> applicationDidReceiveMemoryWarning()"를 보여줍니다.
(가금 Program received signal: �0�같은 메세지를 볼 수 있습니다.)이 경고 메세지는 많은 경우 심각한 것은 아니고 iOS 가
메모리가 적어 프로그램에 메모리를 프리할 것을 요청하는 것입니다. 보통 메일 같은 백그라운드 프로세스들이 메모리를 풀어주며
사용자 프로그램은 계속 실행될 수 있습니다. 그러나 사용자 프로그램이 계속 메모리를 사용하거나 더 원할 경우 OS 는 어느
시점에서 프로그램을 종료하기 시작하고 사용자 프로그램이 종료 될 수도 있습니다. 애플은 어떤 메모리 사용이 안전한지 문서화
되지 않았지만 경험적 관찰에 의하면 25MB 이하의 RAM(80MB: 3 세대 장치)을 이용하는 프로그램은 메모리 사용 문제를 가지지
않습니다. 40MB 의 RAM 을 사용하는 프로그램은 1-2 세대 장치에서 문제를 야기하고 장치를 재시작해야 할 수도 있습니다.
사용자가 의존해야 하는 주요 통계는 프로그램이 얼마나 많은 RAM 을 사용하는가 입니다. 사용자 프로그램의 메모리 사용은 다음
세가지 주요 부분으로 이루어 집니다:
•
응용 프로그램 코드 (OS 는 RAM 에 프로그램을 로드하고 유지할 필요가 있습니다)
•
native heap (상태, 에셋 등을 RAM 에 저장하기 위해 엔지에서 사용됨)
•
managed heap (Mono 실행시에 C#과 JavaScript 객체를 유지하기 위해 사용됨)
사용자 프로그램의 메모리 사용은 Xcode Instruments 툴 (Activity Monitor 과 Object Allocations)에서 감시될 수 있습니다.
Xcode 의 performance 툴인 Run->Start with Performance Tool->Activity Monitor 과 Run->Start with Performance
Tool->Object Allocations 에서 실행될 수 있습니다. 첫 번째 툴은 모든 프로세스의 사용자 프로그램이 사용하는 전체 RAM 양을
나타내는 실제 메모리를 포함한 통계를 보여줍니다.
주의: internal profiler 은 .NET 스크립트에 의해 할당된 힙만을 보여줍니다. 총 메모리 사용은 위에서처럼 Xcode Instruement 에서
얻을 수 있습니다. 이 숫자는 메모리에 로드 되어 7MB 를 차지하는 프로그램 바이너리, 어떤 표준 프레임워크 버퍼, 유니티 엔진 내부
상태 버서, .NET 런타임 힙(internal profiler 에서 보여주는 값) 그리고 그 밖의 값들을 포함합니다.
다른 툴은 사용자 프로그램에 의한 모든 할당과 native heap + managed heap 통계를 포함합니다(프로그램의 현재 상태를 알기 위해
Created and still living 박스를 확인하는 것을 잊지마세요). Net bytes 값을 보아야 합니다.
어떻게 메모리 사용을 낮게 유지하는지에 대한 힌트:
•
가장 강력한 iOS 스트리핑 옵션(고급 라이센스 기능)을 사용해서 프로그램 바이너리 크기를 줄이고 다양한 .NET 라이브러리
불필요한 의존성을 피하세요. 자세한 사항은 player settings 과 player size optimization 를 보세요.
•
컨텐츠 크기를 줄이세요: 텍스트에는 PVRTC 압축을 사용하고 낮은 다각형 모델을 사용하세요. 자세한 것은 reducing filesize 을
참조하세요.
•
스크립트에서 너무 많이 할당하지 마세요. internal profiler 에서 mono heap 크기와 사용을 감시하세요.
•
주의: 유니티 3.0 에서는 씬을 로딩하는 구현이 많이 바뀌었고 이제 모든 씬에셋은 미리 로드됩니다. 이것은 게임 객체를 인스턴스화
할때의 급격한 하락을 줄여줍니다. 게임 플레이 동안 에셋의 로딩과 언로딩에 관해 좀더 미세한 컨트롤을 원하면Resources.Load
/ Object.Destroy을 사용하세요.
OS 에게 얼마나 메모리가 남아 있는지 물어보는 것은 사용자 프로그램이 얼마나 잘 돌아가고 있는지 알아보는 좋은 방법인듯 합니다.
하지만 이것은 실제 그렇지 않은데 왜냐하면 OS 는 많은 동적 버퍼와 캐쉬를 이용하기 때문입니다. 항상 사용자 프로그램의 메모리
사용을 확인하고 이것을 주요 통계로 사용하세요. 그것만이 가장 믿을만한 방법일 것입니다. 그저 OS 에게 얼마나 메모리가 남았나
물어보는 것은 별 소용이 없습니다. 툴에서 그래프가 위의 변화를 어떻게 보여주는지 주의깊게 보세요. 특히 새로운 레벨이 로딩된
후에 주의하세요.
게임이 Xcode 에서는 잘 시작되었는데 수동으로 장치에서 시작될 때 첫 번째 레벨 로드에서 크래쉬합니다.
몇 가지 이유가 있을 수 있습니다. 좀더 자세한 정보를 위해 장치 로그를 볼 필요가 있습니다. 장치를 맥에 연결하고 Xcode를
싲가하고 Xcode메뉴의 Window->Organizer로 가서 Organizer의 왼쪽 툴바에서 사용자 장치를 선택하고 "Console" 탭을 클릭하고
최근 메세지를 리뷰합니다. 추가로 크래쉬 리포트를 볼 필요가 있습니다. 어떻게 크래쉬 리포트를
얻는지는:http://developer.apple.com/iphone/library/technotes/tn2008/tn2151.html.
Xcode Organizer 콘솔이 "killed by SpringBoard"를 포함합니다.
iOS 프로그램에서는 첫 번째 프레임을 렌더하고 입력을 처리하는데 걸리는 시간의 제한에 대한 것은 잘 문서화 되지 않았습니다.
사용자 프로그램이 이 제한을 넘기게 되면 SpringBoard 에 의해 종료되게 됩니다. 전형적인 경우는 프로그램이 큰 첫 번째 씬을
가졌을 때입니다. 이 문제를 피하기 위해서는 스플래쉬 화면만 보여주고 하나나 두 개의 프레임을 기다리면서 실제 씬의 로드를
시작하는 작은 초기 씬을 만들 것을 권합니다. 이것을 위한 코드 샘플:
function Start () {
yield;
Application.LoadLevel("Test");
}
Type.GetProperty() / Type.GetValue()가 장치에서 크래쉬를 야기합니다
현재 Type.GetProperty()와 Type.GetValue()는 .NET 2.0 Subset 에서만 지원합니다. Player Settings 에서 .NET API 호환
레벨을 선택합니다.
주의: Type.GetProperty()와 Type.GetValue()는 managed code stripping 과 호환되지 않을 수 있으며 사용자 정의의 스트리핑이
되지 않는 타입 리스트를 제공함으로써 스트리핑을 사용하는 타입을 제외시켜야 할수도 있습니다. 좀더 자세한 사항은 iOS player
size optimization guide 을 보세요.
게임이 다음 에러와 함께 크래쉬합니다 "ExecutionEngineException: Attempting to JIT compile method
'SometType`1<SomeValueType>:.ctor ()' while running with --aot-only."
iOS 의 Mono .NET 구현은 AOT(ahead of time compilation to native code) 기술에 기반을 둡니다. 이 기술은 자체의 한계를 가집니다.
이것은 다른 코드에의해 사용되는 그 generic 타입의 함수(값 타입이 generic 파라미터로 사용 되었을 때)만을 컴파일합니다. 그런
함수가 반사나 본래의 코드(즉 serialization 시스템)를 통해 사용이 되면 AOT 컴파일 도중에 스킵됩니다. AOT 컴파일러는 모의
함수를 스크립트 어딘가에 추가함으로써 코드를 추가하라는 것을 알려주고 없는 함수를 터치하여 미리 컴파일 되게 합니다.
void _unusedMethod()
{
var tmp = new SometType<SomeValueType>();
}
주의: 값 타입은 기본 타입, enums, structs 입니다.
System.Security.Cryptography 과 managed code stripping 의 조합이 장치에서 겪는 다양한 크래쉬
.NET 암호화 서비스는 반사에 크게 의존하므로 정적 코도 분석에 의존하는 managed code stripping 과 호환되지 않습니다. 가끔
가장 쉬운 방법은 스트리핑 프로세스에서 모든 System.Security.Crypography 네임스페이스를 제외 시키는 것입니다.
스티리핑 프로세스는 사용자 정의된 link.xml 파일을 유니티 iOS 에셋폴더에 추가함으로써 사용자 정의 할 수 있고 어떤 타입 또는
네임스페이스를 스트리핑에서 제외 시켜야 하는지 지정합니다. 좀더 자세한 사항은 iOS player size optimization guide 을 보세요.
link.xml
<linker>
<assembly fullname="mscorlib">
<namespace fullname="System.Security.Cryptography" preserve="all"/>
</assembly>
</linker>
"Ran out of trampolines of type 1/2" runtime error
이 에러는 보통 사용자가 많은 recursive generics 을 사용하면 발생 합니다. 사용자는 첫번째 두번째 타입을 더 할당하기 위해
AOT 컴파일러에게 힌트를 줍니다. 추가적인 AOT 컴파일러 명령어 라인 옵션은 PlayerSettings 의 다른 설정 옵션에서 지정될 수
있습니다. Type 1 trampolines 은 nrgctx-trampolines=ABCD 를 지정합니다. 여기서 ABCD 는 새로운 trampoline count (즉
4096)입니다. Type 2 trampolines 은 nimt-trampolines=ABCD 을 지정합니다.
Android
안드로이드 개발 문제 해결
유니티가 사용자 프로그램을 장치에 설치 실패
1.
사용자 컴퓨터가 실제로 장치를 감지하고 연결 되었는지 확인합니다. 좀 더 자세한 사항은 Publishing Builds 에 있습니다.
2.
유니티 콘솔에서 빨간 사인으로 마크 되어있는 에러를 찾으세요. 그것을 유용한 에러 메세지 일 것입니다.
사용자 프로그램이 시작 후 바로 크래쉬 합니다.
1.
NativeActivity 를 지원하지 않는 장치와 사용하려 하지 마세요.
2.
사용자가 가지고 있는 본래의 플러그인을 제거하도록 하세요.
3.
스트리핑을 비활성화 하도록 하세요.
4.
크래쉬 리포트를 얻기위해 adb logcat 를 사용합니다.
DEX 빌스 실패
이것은 아래와 같이 자신을 나타낼 에러입니다
Building DEX Failed!
G:\Unity\JavaPluginSample\Temp/StagingArea> java -Xmx1024M
-Djava.ext.dirs="G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/"
-jar "G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/dx.jar"
--dex --verbose --output=bin/classes.dex bin/classes.jar plugins
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
이것은 주로 컴퓨터에 잘못된 버전의 Java 가 설치 되었을 때 입니다. 자바를 최신 버전으로 설치하고 이것은 이 문제를 해결할
것입니다.
슬립 버튼을 누르면 게임이 종료됩니다
here에 설명된 <android:configChanges> 태그를 포함하기 위해 AndroidManifest.xml 에 있는 <activity> 태그를 바꾸세요.
예제 활동 태그는 다음과 같습니다:
<activity android:name=".AdMobTestActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
유니티 IME
입력기(IME)가 무엇인가요?
입력 방법이란 사용자가 입력 장치에서 찾을 수 없는 문자열이나 기호를 입력할 수 있게 해주는 하나의 운영체제 컴포넌트 또는
프로그램입니다. 예를 들어, 컴퓨터에서 '서양' 키보드의 사용자가 중국어, 일본어, 한국어 또는 인도 문자를 입력하는 것을 가능하게
합니다. 모바일 폰같은 많은 휴대기기에서는 라틴 문자열을 입력하기 위해서 숫자 키패드를 사용합니다.
입력 방법이란 용어는 주로 특정 언어를 입력하기위해 키보드를 사용하는 특별한 방법을 말합니다. 예를 들어 Cangjie 나 pinyin 방법
또는 죽은 키들의 사용을 말합니다.
IME 와 유니티
데스크탑!
유니티 3.x 이후부터는 엔진에 IME 가 지원되는데 이것은 모든 그래픽 사용자 인터페이스에서 ASCII 문자가 아닌 문자도 쓸수
있다는 말입니다. 이 입력 방법은 엔진과 완전히 연계되어 있어서 활성화를 위해서 아무것도 하지 않아도 됩니다. 테스트를 위해서는
키보드의 언어를 ASCII 언어가 아닌 일본어로 바꾸어 사용해 보십시오.
좀더 많은 정보와 ASCII 문자가 아닌 문자 사용시 최적화를 위해선 font properties 의 character 옵션을 선택합니다.
Note: 현재 유니티의 IME 는 맥 웹플레이어에서는 지원되지 않습니다.
iOS
이 기능은 iOS 에서 아직 지원되지 않습니다.
Android
이 기능은 아직 안드로이드 장치에서 지원되지 않습니다.
유니티 그림자
Desktop
유니티 프로는 어떤 빛에서도 실시간 shadows 를 사용하는 것이 가능합니다. 객체는 서로에게 그림자를 만들수 있으며 자기
자신에게도 ("self shadowing")에게도 그림자를 드리울 수 있습니다. 모든 Lights 의 형태는 - Directional, Spot 과 Point – 그림자를
지원합니다.
그림자를 이용하는 것은 Light 에서 Hard Shadows 또는 Soft Shadows 를 선택하는 것만큼 쉽습니다. 그러나 그림자의 최대
퀄리티와 성능을 원한다면 몇가지 고려해야 하는 것이 있습니다.
Shadow Troubleshooting 페이지는 흔한 그림자 문제들에 대한 해결책을 포함합니다.
신기하게도 최고의 그림자는 실시간이 아닌 것들 입니다. 사용자 게임의 기하와 빛이 정적이면 사용자의 3D 프로그램에서 빛맵을
미리 계산하세요. 그림자를 오프라인으로 미리 계산하는 것은 항상 실시간으로 계산하는 것보다 더 낳은 퀄리티와 성능을
보여줍니다. 이제 실시간 그림자에 대해 말해 보겠습니다...
그림자 퀄리티 고치기
유니티는 그림자를 보여주기위해 shadow maps라는 것을 사용합니다. 그림자 맵핑은 텍스쳐 기반의 접근인데 빛에서 나와 화면에
뿌려지는 "shadow textures"라 생각하면 아주 쉽습니다. 그래서 다른 보통의 텍스쳐와 마찬가지로 그림자 맵핑의 퀄리티는 다음의
두가지 요소에 주로 의존 합니다:
•
그림자 맵의 해상도(resolution) (크기). 그림자 맵이 커질수록 그림자 퀄리티는 향상됩니다.
•
그림자 filtering. Hard shadows 는 가장 가까운 그림자 맵 픽셀을 차지합니다. Soft shadows 는 몇가지 그림자 맵 픽셀의 평균을
가지는데 이것은 부드럽게 보이는 그림자를 가능하게 합니다(그러나 소프트 그림자는 렌더하기 더 힘이듭니다).
다른 Light 타입은 그림자 계산을 위해 다른 알고리즘을 사용합니다.
•
방향 빛에서 그림자 퀄리티를 위한 가장 중요한 설정은 Quality Settings 에서 찾을 수 있는 Shadow Distance 와 Shadow
Cascades 입니다. Shadow Resolution 도 중요하지만 방향 빛의 퀄리티를 위해서는 가장 먼저 그림자 거리를줄이는 일입니다. 모든
방향 빛에 대한 정보는 Directional Shadow Details 를 보세요.
•
스포트라이트와 포인트 빛에서는 Shadow Resolution 가 그림자 맵의 크기를 결정합니다. 또한 화면의 작은 부분을 커버하는
빛에서는 작은 그림자맵 해상도가 쓰입니다.
어떻게 그림자 맵 크기가 계산되는지에 대한 제세한 사항은 Shadow Size Details 를 보세요.
그림자 성능
실시간 그림자는 고 성능을 필요로므로 가끔 씩만 사용 하도록 합니다. 그림자를 렌더할 각 빛을 위해선 첫째 어떤 잠재적으로
그림자를 내는 것은 그림자 맵에서 렌더되야 하고 그럼 모든 그림자를 받는 것은 그 그림자 맵에서 렌더되야 합니다. 이것은 그림자
비추는 것은 픽셀 빛보다 비싼 작업 이지만 컴퓨터 또한 빨라지고 있지 않습니까!
Soft shadows 는 Hard shadows 를 렌더하는 것보다 비싼 작입입니다. 비용은 전적으로 그래픽 카드에 있습니다(단지 더 긴
그림자입니다). 그래서 하드 대 소프트 그림자는 CPU 나 메모리 사용에는 전혀 영향을 주지 않습니다.
Quality Settings 은 Shadow Distance 이라 불리는 설정을 포함합니다 – 이것은 그림자가 카메라에서 얼마나 멀리 그려지는가 입니다.
보통 카메라에서 500 미터 떨어진 그림자를 계산하고 보여주는 것은 말이 되지 않기 때문에 가능한 낮은 그림자 거리를 사용하세요.
이것은 성능에 도움을 줄 것입니다(그리고 방향 빛 그림자의 퀄리티를 향상 시킬 것입니다. 위를 보세요).
그림자를 위한 하드웨어 지원
내장된 그림자는 조각 프로그램(pixel shader 2.0)이 가능한 그래픽 카드를 필요로 합니다. 아래는 지원되는 카드를 보여줍니다:
•
윈도우즈:
o
ATI Radeon 9500 이상, Radeon X series, Radeon HD series.
o
NVIDIA GeForce 6xxx, 7xxx, 8xxx, 9xxx, GeForce GT, GTX series.
o
Intel GMA X3000 (965) 이상.
•
On Mac OS X:
o
Mac OS X 10.4.11 이상.
o
ATI Radeon 9500 이상, Radeon X, Radeon HD series.
o
NVIDIA GeForce FX, 6xxx, 7xxx, 8xxx, 9xxx, GT, GTX series.
o
Intel GMA 950 이상.

소프트 그림자는 드라이버 버그로 비활성화 되어있습니다(대신 하드 그림자가 사용됩니다).
주의
•
Forward rendering path 는 한 방향의 그림자 비추기만을 지원합니다. Vertex Lit 렌더링 경로는 실시간 그림자를 지원하지 않습니다.
•
Vertex-lit 빛은 그림자를 가지지 않습니다.
•
Vertex-lit 재료는 그림자를 받지 않습니다(그러나 비추기는 합니다).
•
투명한 객체는 그림자를 비추거나 받지 않습니다. 투명한 Cutout 객체는 그림자를 비추거나 받을수 있습니다.
iOS
이기능은 현재 iOS 에서는 지원되지 않습니다.
Android
이기능은 현재 안드로이드에서는 지원되지 않습니다.
Directional Shadow Details
Desktop
이 페이지는 Directional 불빛으로부터의 shadows 를 자세하게 설명합니다.
방향성 불빛들은 야외에서는 태양광이나 달빛과 같은 핵심 불빛으로 사용됩니다. 거리를 보는 것은 일 인칭 혹은 삼인칭 게임(third
person game)에서는 매우 중요합니다. 그림자들은 가장 좋은 질과 상황에 맞는 성능 사이에서의 튜닝이 필요합니다.
삼인칭 게임을 위한 근사하게 보이는 그림자 설정을 해 보겠습니다:
여기에 그림자는 매우 훌륭하게 보입니다 !
또한, Shadow Cascades 들은 4 로 설정되었습니다. Shadow Resolution 는 높음(High)으로 설정되고 빛은 Soft Shadows 로
사용했습니다.
아래의 장(chapter)들은 방향성 불빛 그림자의 각각의 특성들을 분해했습니다:
•
견고한 그림자들과 부드러운 그림자들
•
그림자 다중 단계 개수
•
그림자 거리는 매우 중요합니다!
견고한 그림자들과 부드러운 그림자들(Hard versus Soft shadows)
같은 불빛의 설정을 사용하여, Shadow Type 을 Hard Shadows 으로 바꾸면, 불빛지역과 그림자 지역의 전이는 매우 견고합니다. 즉,
100% 그림자 지역이거나 100% 불빛 지역입니다. 견고한 그림자들은 표현하기는 쉽지만 덜 현실적으로 보입니다.
거리 50 과 4 단계의 견고한 그림자
그림자 다단계 개수
방향성 불빛들을 위해서 유니티(Unity)는 다중 단계 그림자 지도 (Cascaded Shadow Maps) ("병렬 쪼개짐 그림자 지도 (Parallel
Split Shadow Maps)"라고도 불림)라고 불리는 것을 사용할 수 있습니다. 이는 특히 먼 시야 거리(viewing distance)에서 매우 좋은
그림자의 질을 제공합니다. 다중 단계 그림자들은 시야 거리를 점진적으로 더 큰 분할지역과 그리고 같은 크기를 갖는 그림자들을
사용하여 시야 거리를 분할합니다. 그 결과 관측자에 더 가까운 오브젝트들이 멀리 있는 오브젝트들보다 더 많은 그림자 지도의
픽셀들을 가지게 됩니다.
아래의 이미지들에서 그림자 픽셀들이 더 좋은 시야를 위해서 견고한 그림자들을 사용하게 될 것입니다.
다중 단계 그림자 지도 들이 사용되지 않는다면, 전체 그림자 거리(여전히 50 단위)는 그림자의 짜임새에 균일하게 덮일 것입니다.
견고한 그림자들은 다중 단계 없이 이 와 같이 보일 것입니다:
거리 50 의 다중 단계 없는 견고한 그림자
그림자 짜임새의 픽셀들은 모든 곳에서 같은 크기여야 합니다. 원 거리에서 좋게 보이지만 질은 가까운 곳에서 아주 훌륭해 보이지는
않습니다. 그림자 짜임새는 시야 거리 전체를 덮습니다. 시각화 하면 이처럼 보일 것입니다:
다중 단계 없이, 그림자 짜임새가 시야를 균일하게 덮습니다.
그림자의 다중 단계 2 가 사용되면, 전체 그림자 거리는 관측자 주위의 조그마한 덩어리와 먼 곳의 큰 덩어리로 두 개로 나누어
집니다. 다중 단계 2 가 사용된 견고한 그림자는 이와 같습니다:
거리 50 에 다중 단계 2 가 사용된 견고한 그림자들(Hard shadows)
성능의 희생으로, 가까운 곳에 더 좋은 그림자 해상도를 얻습니다.
다중 단계 2 를 사용한 두 개의 그림자 짜임새가 시야를 다른 크기를 갖는 분할들로 덮습니다.
그리고, 마지막으로 그림자 다중 단계 4 를 갖는 경우에는, 그림자 거리가 4 개의 점진적으로 더 커진 분할 구역으로 나누어집니다.
견고한 그림자들은 다중 단계 4 로 이와 같이 보입니다:
거리 50, 다중 단계 4 의 견고한 그림자들(Hard shadows). 이미 살펴본 그림입니다!
다중 단계 4 를 사용하고 네 개의 그림자 짜임새가 시야를 다른 크기의 분할 구역으로 덮습니다.
그림자 거리는 매우 중요합니다!
그림자 거리(Shadow Distance)는 방향성 불빛 그림자의 질과 성능 모두에게 매우 중요합니다. 그림자 다중 단계의 개수와
마찬가지로, 그림자 거리는 Quality Settings 에서 설정할 수 있으며, 성능이 떨어지는 하드웨어에서도 그림자의 비율을 더 쉽게 낮출
수 있습니다.
그림자들은 그림자 거리의 끝부분에서 희미해지는데, 이는 그림자 처리되지 않은 오브젝트들보다 더 먼 곳에서 희미해 집니다.
대부분의 상황에서는 그림자들은 게임에서 특정 거리보다 먼 그림자들은 잘 알아차리기 힘듭니다!
다중 단계 없는 그림자 거리 20 으로 설정된 견고한 그림자들은 아래의 그림과 같습니다. 그림자들은 원 거리에서 희미해 지지만,
그림자의 질은 다중 처리 없는 거리 50 에서의 그림자들보다는 훨씬 좋습니다.
다중 단계 없는 거리 20 에서의 견고한 그림자
반면, 그림자 거리를 너무 높게 잡으면, 그림자들은 좋게 보이지는 않습니다. 거리를 100 으로 설정했을 때 성능은 줄어들었고, 질도
크게 납득 가지 않는 수준입니다. 그 장면에서 어떠한 오브젝트들도 50 미터보다 더 멀리 있는 것은 없습니다!
거리 100 의 다중 단계 없는 견고한 그림자. 이런(Ouch!)!
다중 단계를 사용한 그림자 지도들이 거리 비율조정에 훨씬 좋습니다. 예를 들어, 다중 단계 4 의 카메라 앞의 300 유닛 들을 덮는
부드러운 그림자들은 아래 그림과 같습니다. 이 페이지의 위에서 보다는 더 나쁘지만, 거리를 6 배 증가한 것 보다는 더 나빠
보이지는 않습니다(물론 이 장면에서 높은 그림자 거리는 그다지 이치에 맞는 것은 아닙니다).
거리 300 의 다중 단계 4 의 부드러운 그림자들
iOS
이 기능은 iOS 타겟 들로는 지원되지 않습니다.
Android
이 기능은 안드로이드(Android) 타겟 들로는 지원되지 않습니다.
그림자 문제해결
이 페이지는 shadow 문제에 대한 해결책을 나열합니다.
Desktop
그림자가 보이지 않아요!
•
그림지난 Unity Pro 에만 있는 기능으로 프로가 아니면 그림자를 가질수 없습니다. 물론 Projector 와 같은 간단한 그림자 함수는
사용가능 합니다.
•
그림자 또한 특정 그래픽 하드웨어를 필요로합니다. 좀더 자세한 사항은 Shadows 를 보세요.
•
Quality Settings 에서 그림자가 완전히 비활성화 되지 않았나 확인하세요.
•
현재 iOS 와 안드로이드 모바일 플랫폼에서는 그림자가 지원되지 않습니다.
어떤 객체들이 그림자가 보이지 않거나 받지도 않아요.
첫째, Renderer 는 그림자를 자신이 받게하기 위해서는 Receive Shadows 이 on 으로 되어있어야 합니다. 그리고 다른 객체에
그림자가 보이게 하기위해서는 Cast Shadows 가 on 으로 되어있어야 합니다 (둘 모두 기본값은 on 입니다).
다음으로 불투명한 객체만 그림자를 만들고 받을 수 있습니다. 즉 Transparent 나 Particle 그림자를 사용하면 그림자를 볼 수 없을
것입니다. 대부분의 경우 이것은 Transparent Cutout 그림자 (펜스나 식물 등의 객체)에 가능한 일입니다. 만약 사용자가 사용자
정의된 그림자를 사용한다면 그것은 픽셀이 켜져 있어야 하며 Geometry render queue 를 이용합니다. VertexLit 그림자를 사용한
객체는 그림자를 받지 않습니다(그러나 그림자를 만들수는 있습니다).
마지막으로 Forward rendering path 에서는 가장 밝은 방향 빛만 그림자를 만들수 있습니다. 만약 사용자가 그림자를 만들 수 있는
여러 빛을 가지고 싶다면 Deferred Lighting 렌더링 경로를 사용하여야 합니다.
iOS
현재 iOS 플랫폼에서는 지원되지 않습니다.
Android
현재 안드로이드 플랫폼에서는 지원되지 않습니다.
Shadow Size Computation
Desktop
유니티는 shadow map 크기를 아래와 같은 방법으로 계산합니다:
첫째로 화면에 빛의 "coverage box" 가 계산 됩니다. 이것은 빛이 비추는 화면의 다음을 위한 사각형 입니다:
•
전체 화면의 방향성을 가진 빛.
•
화면에 뿌려지는 빛의 피라미드의 반사되는 사각형의 지점(Spot) 빛.
•
화면에 뿌려지는 빛의 구에서 반사되는 사각형의 점(Point) 빛.
그리고 이 상자의 가로, 세로, 높이의 큰 값이 선택되고 pixel size 를 부릅니다.
"High" 그림자 해상도, 그림자 맵의 크기 그리고:
•
방향 빛(Directional) 빛: NextPowerOfTwo( pixel size * 1.9 ), 2048 보다 크지 않게.
•
지점 빛(Spot) 빛: NextPowerOfTwo( pixel size ), 1024 보다 크지 않게.
•
점 빛(Point) 빛: NextPowerOfTwo( pixel size * 0.5 ), 512 보다 크지 않게.
그래픽 카드가 512MB 이상의 메모리를 가지고 있을 때는 그림자 맵의 최고 한도가 증가 합니다 (방향은 4096, 지점은 2048, 점
빛은 1024).
"중간" 그림자 해상도에서는 그림자 맵 크기가 "높은" 해상도에서보다 두배 작습니다. "낮은" 해상도에서는 네배 더 작습니다.
점 빛의 작은 한계는 그것이 그림자를 위해서 cubemap 을 사용하기 때문입니다. 즉, cubemap 의 여섯면은 비디오 메모리에
존재해야만 합니다. 그것은 잠재적인 그림자 주조기가 cubemap 의 여섯면이 렌더되야 하기 때문에 꽤 렌더하기 비쌉니다.
메모리 한계에 다가갔을 때의 그림자 크기 계산
비디오 메모리의 한계에 다다랐을 때, 유니티는 위에서 계산된 그림자맵 해상도를 자동으로 낮춥니다.
보통 화면(backbuffer, frontbuffer, depth buffer)을 위한 메모리는 비디오 메모리에 존재하여야 하며 텍스쳐 렌더도 비디오 메모리에
존재하여야 합니다. 유니티는 이 두가지를 그림자 맵의 메모리 이용을 결정하는데 사용합니다. 위에서 계산된 그림자 맵의
크기에따라 배치가 될때 그 크기는 (TotalVideoMemory - ScreenMemory - RenderTextureMemory) / 3 에 맞도록 크기가 줄어들
것입니다.
모든 보통의 텍스쳐, 꼭지점 데이터 그리고 다른 그래픽 객체가 비디오 메모리에서 스왑될 수 있다고 가정하면 그림자 맵에 의해
사용될수 있는 최대 VRAM 은 (TotalVideoMemory-ScreenMemory-RenderTextureMemory)입니다. 그러나 화면과 텍스쳐 렌더에
사용되는 메모리의 정확한 크기는 결정될 수 없으며 어떤 객체는 스왑되어 나올 수 없으며 모든 텍스쳐가 지속적으로 스왑되어
들어오고 나간다면 최악의 성능을 보여줄 것입니다. 그리서 유니티는 그림자 맵이 "보통 사용 가능한" 비디오 메모리의 삼분의 일
이상을 사용할 수 없게하며 이것을 실제 잘 작동합니다.
iOS
현재 안드로이드 플랫폼에서는 지원되지 않습니다.
Android
This is currently not supported on the Android Platform.
통합 그래픽 카드 최적화
Desktop
다각형 개수의 중요성
요즘 대부분의 그래픽카드에서는 다각형은 개수는 그렇게중요하지 않습니다. 보통 객체의 수와 프레임 속도가 더욱더 중요합니다.
불행히도 대부분의 오래된 칩 (Intel 945 / GMA 950 와 비슷한 종류)에서는 그렇지 않습니다. 얼마나 중요한지는 꼭지점 쉐이더 또는
빛의 복잡도 그리고 CPU 의 속도(맞습니다, 대부분의 통합 카드는 꼭지점의 변환과 빛을 CPU 에서 합니다)에 따라 달라집니다.
Big Bang Brain Games은 1-2 꼭지점 빛을 사용하고 픽셀 빛(특히 VertexLit rendering path)을 사용하지 않는 화면에서 절대
25000 개 이상의 삼각형을 넘지 않습니다. 퀄리티 설정은 프레임 속도가 떨어질때 자동으로 성능을 높이는데 사용되곤 했습니다.
그래서 고성능 컴퓨터에서는 픽셀 빛이 활성화된 높은 퀄리티 설정이 사용되었습니다.
속도를 늦추는 것은 복잡한 꼭지점 쉐이더와 많은 다각형을 이요한 객체들을 여러번 그리는 것입니다. 이 말은:
•
가능한 VertexLit rendering path 를 이용하세요. 이것은 얼마나 많은 빛이 존재하건 각 객체를 한번씩만 그립니다.
•
빛을 사용하지 않도록 노력하세요. 꼭지점 빛마저도 말입니다. 사용자의 기하가 움직인다거나 빛이 움직이면 빛의 사용이 맞는
것이지만 그렇지 않으면 Lightmapper 를 이용해서 조명을 굽고 이것은 더 빠르고 보기 좋게 돌아갈 것입니다.
•
기하를 최적화 하세요(아래 섹션을 보세요).
•
Rendering Statistics 윈도우와 Profiler 를 사용하세요!
모델 기하 최적화
모델의 기하를 최적화할때 두가지 기본 룰이 있습니다:
•
필요하지 않으면 과도한 양의 면(face)를 사용하지 마세요.
•
UV 맵핑 이음매와 하드한 변의 개수를 가능한 낮추세요.
그래픽 하드웨어가 처리해야하는 실제 꼭저점의 수가 3D 프로그램에서 보여지는 수와는 같지 않음에 주의하세요. 모델링
프로그램은 보통 기하 꼭지점 개수를 보여줍니다. 즉 모델을 만드는데 점의 개수입니다.
하지만 그래픽 카드에서는 어떤 꼭지점은 몇개의 점으로 구별되야 합니다. 꼭지점이 여러개의 법선(이것은 하드한 변에 있습니다)을
가지고 있거나 여러개의 UV 좌표를 가지거나 여러개의 꼭지점 색상을 가지면 이 꼭지점은 나뉘어 져야 합니다. 그래서 유니티에서
보는 꼭지점의 수는 거의 항상 3D 프로그램에서 보여지는 수와 다릅니다.
빛 굽기
빛을 빛맵이나 꼭지점 색상으로 구우세요. 유니티는 훌륭한 내장된 Lightmapper 을 가지고 있고 또한 여러 3D 모델링 패키지에 있는
빛맵을 구울수 있습니다.
빛맵 환경을 만드는 과정은 유니티에서 단순히 빛을 위치시키는 것보다 조금더 걸릴 뿐입니다. 그러나:
•
훨씬 빠른 속도로 실행 됩니다. 특히 많은 빛을 가졌을 때 그렇습니다.
•
전체적 조명을 구울 수 있으므로 훨씬 좋아 보입니다.
차세대 게임 조차도 아직 빛맵핑에 많이 의존하고 있습니다. 보통 빛맵 환경을 사용하며 하나 또는 두개의 실시간 동적 빛을
사용합니다.
Web Player Streaming
Desktop
웹 플레이어 스트리밍은 엔드 유저에게 멋진 웹 게임 체험을 제공하는데 대단히 중요합니다. 웹 게임의 아이디어는 플레이어를 진행
바를 보며 기다리게 하기 보다는 최대한 신속하게 게임을 시작할 수 있게 하고 사용자의 콘텐츠를 거의 즉시 볼 수 있게 해 주는 데
있습니다. 이것은 아주 가능한 이야기이며, 이제부터 그 방법을 설명 하겠습니다.
포탈에 조율하기(Tuning for Portals)
이 섹션에서는 게임 포탈에 출시하는 것에 초점을 맞추겠습니다. 스트리밍은 모든 콘텐츠에 유용하며 이는 다른 많은 상황에도
적용될 수 있습니다.온라인 게임 포탈에서 플레이어는 1MB 정도의 데이터만 다운 받으면 어떤 형태의 게임이 시작 하리라고 예상을
합니다. 이런 형태의 게임을 제공하지 않으면 포탈에서 사용자의 게임을 받아 줄 가능성은 매우 희박합니다. 플레이어의 입장에서는
게임이 빨리 시작하기를 원합니다. 아니면 플레이어는 시간을 낭비하고 창을 닫을 가능성도 있습니다.128 킬로 비트의 케이블
접속에서 사용자는 초당 16KB 혹은 분당 1MB 의 데이터를 다운받을 수 있습니다. 이것은 온라인 포탈이 타깃으로 하는 낮은 사양의
대역폭입니다. 이 게임은 아래와 같은 스트림에서 설정 될 경우 최적이 될 것입니다:
1.
50KB(4 초)로 로고와 메뉴 디스플레이에
2.
KB 로 사용자가 작은 연습 레벨의 게임을 하거나 혹은 메뉴에서 뭔가 재미있는 상호작용을 할 수 있게 해 줍니다(20 초)
3.
800 KB(50 초)로 사용하여 초기의 작은 레벨의 게임을 하게 해 줍니다(50 초)
4.
1-5 MB 이내에 전체 게임을 다운 로드 받을 수 있게 해 줍니다(1~5 분)
항상 기억해야 할 중요한 포인트는 낮은 접속 속도에서 기다리는 플레이어 입니다. 플레이어를 절대로 기다리게 하지 마십시오.
이제, 사용자의 웹 플레이어가 현재 10MB 이라도 실망하지 마십시오. 이를 최적화 하는 것은 어려운 일처럼 보이겠지만 조금만
노력을 기울이면 사용자의 게임을 이런 방법으로 구성하는 작업은 일반적으로 아주 쉽게 이루어 질 수 있습니다. 위의 각 단계를
일종의 개별 장면(scene)으로 생각해 보십시오. 사용자가 게임을 만들었다면, 이미 어려운 부분은 완료를 한 것입니다. 일부 장면을
이러한 로딩 개념으로 재구성 하는 것은 이에 비교하면 식은 죽 먹기에 해당 합니다!
콘솔 로그를 열면 (Console window(Desktop Platforms)안에 Open Editor Log 버튼; 메뉴 OSX 안에 Help -> Open Editor console
log), 각 개별 장면 파일의 크기를 볼 수 있습니다:
***Player size statistics***
Level 0 'Main Menu' uses 95.0 KB compressed.
Level 1 'Character Builder' uses 111.5 KB compressed.
Level 2 'Level 1' uses 592.0 KB compressed.
Level 3 'Level 2' uses 2.2 MB compressed.
Level 4 'Level 3' uses 2.3 MB compressed.
Total compressed size 5.3 MB. Total decompressed size 9.9 MB.
게임은 좀 더 최적화를 실행 할 수 있습니다! 더 자세한 정보를 보려면 reducing file size page 을 참조하십시오.
가장 중요 단계들
1.
메뉴를 우선 로딩 하십시오. 동영상화 된 메뉴를 보여주는 것도 시간이 지나는 것을 인식하지 못하게 하는 좋은 방법이므로
다운 로딩이 더 진행 될 수 있게 해 줍니다.
2.
초기 레벨을 짧게 하고 에셋을 많이 사용하지 마십시오. 이렇게 하면, 초기 레벨이 재빨리 로딩 되게 할 수 있고, 플레이어가
이 게임이 1,2 분 집중하는 동안 백그라운드에서 모든 에셋의 다운로드를 완료할 수 있습니다. 왜 연습 레벨의 게임을 두어
사용자가 게임 컨트롤을 배우게 하지 않느냐고요? 고해상도의 텍스처나 오브젝트를 로딩하거나 모든 적들이 초기레벨에
있을 이유가 없습니다. 가장 폴리의 수가 (poly-count)가 낮은 것을 사용하십시오. 그렇다 해도 사용자는 웹 플레이어의
입장을 항상 염두에 두고 사용자 게임을 디자인 하여야 한다는 것을 의미합니다.
3.
게임 초기에 모든 음악이 필요할 이유가 없습니다. 음악을 외부에 두고WWW 클래스를 통해 로딩하시기 바랍니다.
유니티는 고품질의 codec, Ogg Vorbis의 오디오를 압축합니다. 그러나 압축이 되었을 때에도, 오디오는 많은 공간을
차지하고, 사용자가 3MB 내에 맞추어야 할 경우 5 분 분량의 음악이 있다면 이 세상 어떠한 압축 기술도 사용자를 도와 줄
수가 없습니다. 모종의 희생이 필요합니다. 짧은 트랙의 음악을 룹으로 반복하며 추가로 음악을 다운 받을 수 있습니다.
플레이가 첫 레벨에 접속 했을 때 추가 음악을 로딩하십시오.
4.
해당 들여오기 설정(Import Settings)을 사용하여 사용자의 텍스처를 최적화 하십시오. 음악을 외부화 하고 나면, 텍스처가
게임의 90% 이상을 손쉽게 차지하게 됩니다. 일반적인 텍스처 사이즈는 웹 배치에는 너무 거대합니다. 작은 브라우저
윈도우에서는 경우에 따라서는 대형 텍스처라도 시각적 만족을 전혀 추가해 주지 못합니다. 사용자의 텍스처 사이즈가
필요한 만큼만 커져야 하며 (여기서 더 희생을 준비하여야 합니다). 텍스처 해상도를 반감하면 실제 텍스처 사이즈는 4 분의
1 이 됩니다. 그리고 물론 모든 텍스처는 DXT 로 압축이 되어야 합니다.
5.
일반적으로 사용자 웹 플레이어의 크기를 줄이십시오. 유니티가 파일 사이즈를 최적화 하는데 사용할 수 있는 유틸리티
프로그램에 대하여 설명하는 매뉴얼 페이지가 here 에 있습니다. 비록 유니티가 최첨단의 LZMA-기반 압축기술을 사용하여
게임 데이터를 보통 비압축 데이터의 반에서 1/3 의 사이까지 압축해 주지만, 사용자는 할 수 있는 모든 것을 시도할 필요가
있습니다.
6.
T Resources.Load 의 사용을 피하십시오. Resources.Load 는 한편으로는 무척 편리할 수 있지만, 사용자가
Resources.Load 을 사용하면 유니티가 언제 그것들이 처음 쓰일 지를 주문할 수 없을 것입니다. 왜냐하면 아무 스크립트나
그 Resource 를 로딩하려고 시도할 수 있기 때문입니다. 사용자는 어떤 레벨에서 First Streamed Level With
Resources 속성을 사용하여 Edit->Project Settings->Player 에서 Resources.Load 을 통하여 로딩될 수 있는 모든 에셋이
포함 될 지를 정할 수 있습니다. 사용자는 Resources.Load 에셋을 가능한 늦게 사용하거나 아주 사용을 하지 않아야 합니다.
스트리밍 웹 플레이어의 발행
유니티에서 스트리밍은 레벨을 기반으로 하고, 이것을 설정하는 손쉬운 작업 흐름이 있습니다. 내부적으로는, 유니티가 에셋을
추적하고 최적의 압축 데이터 파일로 정리하고, 그것을 사용하는 초기 장면(scene)에 배열하는 등의 굳은 일을 다 수행합니다.
사용자는 단순히 빌드설정(Build Settings)의 첫 레벨이 가능한 적은 수의 에셋을 사용하게만 하면 됩니다. 이것은 자연스럽게 "menu
level"이 되지만 최상의 웹 체험을 위해서는 사용자는 첫 번째 실제 게임 레벨에 플레이어가 하는 게임이 작아야 함을 꼭 기억하여야
합니다.
유니티에서 스트리밍을 사용하려면 빌드설정(Build Settings)에서 Web Player Streamed 을 선택하십시오. 그러면 해당 콘텐츠는 그
초기 레벨에 사용되어야 하는 모든 에셋이 로딩되자 마자 자동으로 실행 됩니다. 그 메뉴 레벨을 50-100 KB 정도 내로 유지하십시오.
해당 스트림은 가능한 한 빨리 로딩하려고 하고 그 자리에서 바로 압축해제 됩니다. 사용자가 빌드 동안/후에 Console 을 보면 그
크기를 알 수 있습니다.
사용자는 레벨 별로 스트림의 진행을 질의할 수 있으며, 한 레벨이 사용 가능해지면 로딩이 가능해 집니다. 진행 바를 디스플레이
하려면GetStreamProgressForLevel 사용하고, 모든 데이터가 사용 가능하여 특정 레벨이 로딩할 수 있는지
확인하려면CanStreamedLevelBeLoaded을 사용하십시오.
이런 형태의 스트리밍은 물론 직선형이며, 대부분의 경우 게임이 작동하는 방식과 일치합니다. 때로는 그것만으로는 충분하지
않습니다. 그러므로 유니티는 WWW 클래스를 사용하여 .unity3d file 하나를 수동으로 로딩 할 수 있는 API 들을 사용자에게
제공합니다. 비디오와 오디오도 역시 스트리밍 될 수 있으며, 해당 무비가 먼저 다운로드 되지 않고도 거의 즉시 재생될 수 있습니다.
마지막으로 테스처들도WWW 클래스를 통하여 쉽게 다운 받을 수 있고, 사용자 게임에서 필요한 여타의 모든 텍스트나 바이너리
데이터의 경우도 그러합니다.
Web Player Deployment
Desktop
Web Player 를 빌딩할 때 유니티는 플레이어 데이터 파일 옆에 HTML 파일을 자동으로 생성합니다. 이것은 웹 플레이어 데이터
파일을 불러오기 위한 기본 HTML 코드를 포함합니다.
사이트의 디자인에 맞게 또는 다른 HTML 콘텐츠를 추가하기 등의 이유로 생성된 HTML 파일을 바꿀 수 있습니다. 다음의
페이지들은 이와 과련된 내용을 자세히 다룹니다:
•
유니티 웹 플레이어 콘텐츠를 로드하기 위한 HTML 코드
•
유니티 오브젝트 이해하기
•
유니티 웹 플레이어 로딩 화면 커스터마이징
•
웹플레이어 행동방식(Behavior) 태그
•
유니티 웹 플레이어와 브라우져 커뮤니케이션
•
웹 플레이어 템플릿 사용하기
유니티 컨텐츠를 로드하기 위한 HTML 코드
Desktop
유니티 컨텐츠는 유니티 웹 플레이어플러그인에의해 브라우저에 로드 됩니다. HTML 코드는 플러그인과 직접 대화하지 않고
UnityObject 라는 스크립트를 통해 합니다. 이 스크립트의 주요 업무는 유저를 다양한 브라우저와 플랫폼 특정 이슈들로부터
보호함으로써 유니티 컨텐츠를 아주 간단한 작업에 삽입하는 것입니다. 이것은 또한 쉬운 웹 플레이어 설치를 가능하게 합니다.
웹플레이어를 빌드할 때 생성되는 HTLM 파일은 보통 요구되는 모든 기능을 포함합니다. 대부분의 경우 사용자는 그 HTLM 파일을
수정할 필요가 없습니다. 나머지에서는 파일 내부적으로 어떻게 동작하는지 설명합니다.
UnityObject 스크립트는 상요전에 로드되어야 합니다. 이것은 <head>섹션에도 이루어집니다.
<script type="text/javascript" src="http://webplayer.unity3d.com/download_webplayer-3.x/3.0/uo/UnityObject.js"></script>
이제 글로벌 unityObject 변수는 다양한 유니티 관련 작업을 할 수 있습니다. 가장 중요한 작업은 유니티 컨텐츠를 삽입하는
것입니다. 이것은 몇개의 파라미터를 받아들이는 embedUnity 함수를 불러 수행할 수 있습니다. 첫번째 것은 유니티 컨텐츠에 의해
교체될 HTML 요소의 아이디를 나타냅니다. 이것은 어떤 HTLM 요소도 될 수 있는데 <div>가 가장 흔합니다. 이것을 유니티가
있어야할 임시 장소라 생각할 수 있습니다. 두번재 파라미터는 보여질 웹플레이어 파일 경로를 나타냅니다. 다음의 두 파라미터는 웹
플레이어 컨텐츠를 보여줄 넓이와 높이를 나타냅니다. 값은 픽셀 값(예: 600, "450")이나 비율 값(예: "50%", "100%")으로 줄수
있습니다.
unityObject.embedUnity("unityPlayer", "WebPlayer.unity3d", 600, 450);
마지막으로 HTML 자리 표시자는 <body>센션안에 위치합니다. 이것은 <div id="unityPlayer" />처럼 간단할 수 있습니다.
그러나 최대 호환을 위해 브라우저가 자바스크립트를 지원하지 않거나 자리 표시자가 UnityObject 로 교체되지 않았으면 경고
메세지를 주는 것이 좋습니다.
<div id="unityPlayer">
<div class="missing">
<a href="http://unity3d.com/webplayer/" title="Unity Web Player. Install now!">
<img alt="Unity Web Player. Install now!"
src="http://webplayer.unity3d.com/installation/getunity.png" width="193" height="63" />
</a>
</div>
</div>
Working with UnityObject
Desktop
UnityObject 는 유니티 컨텐츠를 HTML 에 삽입해서 간략화하는 자바 스크립트 입니다. 이것은 유니티 Web Player 플러그인을
감지하는 기능, 웹 플레이러 설치를 시작, 유니티 컨텐츠를 삽입하는 기능이 있습니다. HTML 파일과 함께 UnityObject.js 파일을
웹서버에 올리는 것도 가능하지만 그것을 http://webplayer.unity3d.com/download_webplayer3.x/3.0/uo/UnityObject.js 에 있는 유니티 서버로 부터 직접 로드하는 것이 가장 좋습니다. 이런 방법으로 사용자는 항상 최신
버전의 UnityObject 를 참조할 수 있습니다. 유니티 서버에 있는 UnityObject.js 파일은 그것을 작게 만들고 트래픽을 줄이기위해
작게 만들어져 있다는 것을 유의하세요. 소스코드를 살펴보고 싶으면 윈도우즈의 Data\Resources 폴더 또는 Mac OS X 의
Contents/Resources 폴더 에서 원본 파일을 찾을수 있습니다. 기본적으로 UnityObject 는 저희가 설치 타입이나 변환 비율을
식별하는데 도움을 주는 GoogleAnalytics 에 익명의 데이터를 보냅니다.
Functions
embedUnity
HTML 에 유니티 컨텐츠를 삽입하세요.
Parameters:
•
id - 유니티 컨텐츠에 의해 교체될 HTML 요소.
•
src - 웹 플레이어 데이터 파일의 경로. 상대적 또는 절대 경로일 수 있습니다.
•
width - 유니티 컨텐츠의 넓이. 픽셀 값으로 정의되며(i 즉 600, "450") 또는 비율 값으로 정의됨(즉 "50%", "100%").
•
height - 유니티 컨텐츠의 높이. 픽셀 값으로 정의되며(즉 600, "450") 또는 비율 값으로 정의됨(즉 "50%", "100%").
•
params - Optional. 파라이터 리스트를 가직고 있는 객체. 가능한 값은 Customizing the Unity Web Player loading screen 와
Customizing the Unity Web Player's Behavior 를 보세요.
•
attributes - Optional. 속성 리스트를 가지고 있는 객체. 이것은 브라우저에 따라 <object> 또는 <embed> 태그에 추가됩니다.
•
callback - Optional. 웹 플레이어가 로드될 때 불리는함수. 함수는 다음의 속성을 가지는 하나의 인자를 받아야 합니다:
o
success - 작업이 성공 했는지 알려주는 Boolean 값.
o
id - 로드된 웹 플레이어 객체 식별자(placeholder 와 같음).
o
ref - 로드된 웹 플레이어 객체.
주의:
이 함수는 보통 작업이 끝나기전에 리턴을 합니다. 그러므로 웹 플레이어 객체에 즉시 접근하는 것은 안전하지 않습니다. 완료를
알리기위해 콜백 함수가 제공 됩니다. 또 다르게는 getObjectById 를 null 값을 리턴하지 않을 때까지 반복적으로 콜 하세요.
예:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Unity Web Player | Example</title>
<script type="text/javascript"
src="http://webplayer.unity3d.com/download_webplayer/3.0/uo/UnityObject.js"></script>
<script type="text/javascript">
<!--
if (typeof unityObject != "undefined") {
unityObject.embedUnity("unityPlayer", "Example.unity3d", 600, 450, null, null, unityLoaded);
}
function unityLoaded(result) {
if (result.success) {
var unity = result.ref;
var version = unity.GetUnityVersion("3.x.x");
alert("Unity Web Player loaded!\nId: " + result.id + "\nVersion: " + version);
}
else {
alert("Please install Unity Web Player!");
}
}
-->
</script>
</head>
<body>
<!-- This will be replaced by Unity content. -->
<div id="unityPlayer">Unity content can't be played. Make sure you are using compatible browser with
JavaScript enabled.</div>
</body>
</html>
getObjectById
웹 플레이어 객체를 받아 옵니다.
Parameters:
•
id - 웹 플레이어 객체 식별자.
•
callback - Optional. 웹 플레이어가 로드될 때 불리는함수. 함수는 다음의 속성을 가지는 하나의 인자를 받아야 합니다.
웹 플레이어 객체 또는 웹 플레이어가 로드 되지 않았을 때 null 값을 리턴합니다.
예:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Unity Web Player | Example</title>
<script type="text/javascript"
src="http://webplayer.unity3d.com/download_webplayer/3.0/uo/UnityObject.js"></script>
<script type="text/javascript">
<!--
if (typeof unityObject != "undefined") {
unityObject.embedUnity("unityPlayer", "Example.unity3d", 600, 450, null, null, function(result)
{
if (result.success) {
var versionButton = document.getElementById("versionButton");
versionButton.disabled = false;
}
});
}
function versionButtonClick() {
var unity = unityObject.getObjectById("unityPlayer");
var version = unity.GetUnityVersion("3.x.x");
alert(version);
}
-->
</script>
</head>
<body>
<!-- This will be replaced by Unity content. -->
<div id="unityPlayer">Unity content can't be played. Make sure you are using compatible browser with
JavaScript enabled.</div>
<div>
<input id="versionButton" type="button" value="Version" disabled="disabled"
onclick="versionButtonClick();" />
</div>
</body>
</html>
enableFullInstall
완전한 웹 플레이어가 있지 않으면 설치 합니다. 보통 작은 부분의 웹 플레이어가 설치되어 있고 나머지 파일은 자동으로 나중에
다운로드 됩니다. 기본 값은 false 입니다.
Parameters:
•
value - 기능을 활성/비활성화 시키는 Boolean 값.
enableAutoInstall
웹 플레이어가 있지 않으면 자동으로 설치를 시작합니다. 어떤 플랫폼은 이 기능을 지원하지 않습니다. 기본 값은 false 입니다.
Parameters:
•
value - 기능을 활성/비활성화 시키는 Boolean 값.
enableJavaInstall
자바 기반의 설치를 활성화 합니다. 어떤 플랫폼은 이 기능을 지원하지 않습니다. 기본 값은 true 입니다.
Parameters:
•
value - 기능을 활성/비활성화 시키는 Boolean 값.
enableClickOnceInstall
ClickOnce 기반의 설치를 활성화 합니다. 어떤 플랫폼은 이 기능을 지원하지 않습니다. 기본 값은 true 입니다.
Parameters:
•
value - 기능을 활성/비활성화 시키는 Boolean 값.
enableGoogleAnalytics
유니티에게 웹 플레이어 설치를 알립니다. 이것은 웹 플레이어가 이미 설치되어 있으면 아무것도 하지 않습니다. 기본 값은
true 입니다.
Parameters:
•
value - 기능을 활성/비활성화 시키는 Boolean 값.
addLoadEvent
웹 페이지가 로드될 때 불리는 함수로 등록합니다.
Parameters:
•
event - 웹 페이지가 로드될 때 불리는 함수. 이 함수는 파라미터를 가지지 않습니다.
addDomLoadEvent
웹 페이지의 DOM 이 로드될 때 불리는 함수로 등록합니다.
Parameters:
•
event - 웹 페이지가 로드될 때 불리는 함수. 이 함수는 파라미터를 가지지 않습니다.
Customizing the Unity Web Player loading screen
Desktop
기본적으로 Unity Web Player 는 작은 Unity 로고를 보여주고 웹 플레이어 컨텐츠가 로딩되는 동안 진행 바를 보여줍니다. 로고와
진행 바 디스플레이를 포함해서 로딩하는 씬의 외관을 사용자가 정의하는 것이 가능합니다.
로더 이미지를 변경하는 것은 Unity Pro 에서만 가능하다는 것을 참고하세요.
Unity 웹 플레이어 로딩 스크린의 외관을 사용자 정의하기 위해 사용될 수 있는 6 개의 선택적인 파라미터가 있습니다. 그러한
선택적인 파라미터는 다음과 같습니다 :
•
backgroundcolor: 로딩되는 동안에 웹 플레이어 컨텐츠 디스플레이 영역의 배경색, 기본색은 흰색입니다.
•
bordercolor: 로딩되는 동안에 웹 플레이어 컨텐츠 디스플레이 영역 주변에 그려지는 픽셀 한 개짜리 경계선의 색상, 기본색은
흰색입니다.
•
textcolor: 에러 메세지 텍스트의 색상 (예를 들어 데이터 파일이 로딩되는 데 실패했을 때). 기본색은 검정 또는 흰색입니다
(배경색에 따라서).
•
logoimage: 사용자 정의 로고 이미지로의 경로, 로고 이미지는 로딩되는 동안에 웹 플레이어 컨텐츠 디스플레이 영역의 가운데에
그려집니다.
•
progressbarimage: 로딩되는 동안 진행바에 의해 사용되는 사용자 정의 이미지로의 경로. 진행 바 이미지의 너비는 완료된 로딩
파일의 양에 기반해서 클립됩니다. 그러므로 그것은 0 픽셀 너비에서 시작해서 로딩이 완료될 때 그것의 실제 너비로 움직입니다.
진행 바는 로고 이미지 아래에 그려집니다.
•
progressframeimage: 로딩되는 동안 진행바를 프레임하기 위해 사용되는 사용자 정의 이미로의 경로.
제공되는 모든 색상 값들은 6 자리 숫자의 16 진법 색상입니다 (예, FFFFFF, 020F16 등). 제공된 이미지 경로는 상대적이거나 또는
절대적인 링크일 수 있고 모든 이미지 파일은 RGB (투명함 없는) 또는 RGBA (투명함을 가지는) 8-bit/channel PNG 파일이어야
합니다. 마지막으로 progressframeimage 와 progressbarimage 는 같은 높이여야 합니다.
Unity 웹 플레이어 로딩 스크린의 외관을 사용자 정의하는 예제 스크립트가 있습니다. 배경색은 흐린 회색 (A0A0A0)이고 경계 색은
검정(000000), 텍스트 색은 흰색(FFFFFF)이고 로더 이미지는 MyLogo.png, MyProgressBar.png 그리고
MyProgressFrame.png 입니다. 모든 파라미터는 하나의 params 오브젝트로 그룹되어지고 unityObject.embedUnity 메서드로
전달됩니다.
var params = {
backgroundcolor: "A0A0A0",
bordercolor: "000000",
textcolor: "FFFFFF",
logoimage: "MyLogo.png",
progressbarimage: "MyProgressBar.png",
progressframeimage: "MyProgressFrame.png"
};
unityObject.embedUnity("unityPlayer", "WebPlayer.unity3d", 600, 450, params);
Customizing the Unity Web Player's Behavior
Desktop
유니티 Web Player 는 개발자가 쉽게 행동을 몇가지 다른 방법으로 컨트롤하게 하기위해 몇가지 선택적인 파라미터 사용하는 것을
가능하게 합니다:
•
disableContextMenu: 이 파라미터는 유저가 컨텐트에서 오른쪽 또는 컨트롤 클릭했을 때 유니티 웹 플레이어가 컨텍스트 메뉴를
보여주는지 마는지를 제어 합니다. 이것을 true 로 하는것은 컨텍스트 메뉴가 나타나는 것을 막아주고 컨텐츠가 마우스 오른쪽
클릭의 행동을 이용하는 것을 가능하게 합니다. 컨텍스트 메뉴를 활성화하기 위해서는 이 파라미터를 포함하지 마세요.
•
disableExternalCall: 이 파라미터는 유니티 웹 플레이어가 컨텐츠가 브라우저 기반의 자바스크립트와 통신하는것을 허락하는
지를 제어합니다. 이것을 true 로하는 것은 브러우저 통신을 막아서 컨텐츠가 브라우져에서 자바 스크립트를 부르거나 실행할 수
없게합니다. 기본 값은 false 입니다.
•
disableFullscreen: 이 파라미터는 유니티 웹 플레이어가 컨텐츠를 풀 스크린으로 보는 것을 허락하는지 않하는지를 제어합니다.
여기 유니티 웹 플레이어의 행동을 한정하는 예시 스크립트가 있습니다. 컨텍스트 메뉴는 보이지 않을 것입니다. 오직 하나의
파라미터가 있지만 이것은 params 객체안에 위치해야하며 unityObject.embedUnity 함수에 전달되어야 합니다.
var params = {
disableContextMenu: true
};
unityObject.embedUnity("unityPlayer", "WebPlayer.unity3d", 600, 450, params);
위 예에서 disableExternalCall 와 disableFullscreen 모두 정의 되지 않았으므로 그 기본 값이 사용되는 것을 알 수 있습니다.
Unity Web Player and browser communication
Desktop
Unity Web Player 컨텐츠를 포함하는 HTLM 페이지는 그 컨텐츠와 통신할 수 있고 그 반대의 경우도 그렇습니다. 기본적으로
두가지 통신 방향이 존재합니다:
•
웹 페이지가 유니티 웹 플레이어 컨텐츠 안의 함수를 콜 합니다.
•
유니티 웹 플레이어 컨텐츠가 웹 페이지의 함수를 콜 합니다.
각각의 이런 통신의 방향은 다음에서 좀더 자세히 설명합니다.
Calling Unity web player content functions from the web page
유니티 웹 플레이어 객체는 SendMessage()라는 함수를 가지는데 이것은 유니티 웹 플레이어 안의 함수를 부르기위해 웹 페이지로
부터 불려지는 함수 입니다. 이 함수는 유니티 스크립팅 API에 있는 GameObject.SendMessage 함수와 아주 비슷합니다. 웹
페이지에서 불려지면 객체 이름, 함수 이름 그리고 하나의 인자를 넘겨주고 SendMessage()가 주어진 게임 객체안의 주어진 함수를
부릅니다.
유니티 웹 플레이어의 SendMessage()함수를 부르기 위해서 사용자는 첫째로 유니티 웹 플레이어 객체에 대한 참조를 얻어야합니다.
사용자는 unityObject.getObjectById() 함수를 이용해 그 객체의 참조를 얻을 수 있습니다. 여기유니티 웹 플레이어 컨텐츠와
UnityContent 의 아이디 값에서 SendMessage() 함수를 실행 시키는 자바 스크립트 함수 예가 있습니다. 차례로 SendMessage()는
MyObject 라는 게임 객체의 MyFunction() 라는 함수를 부르고 스트링을 인자로 하여 넘겨줍니다:
<script type="text/javascript" language="javascript">
<!--
function SaySomethingToUnity()
{
var unity = unityObject.getObjectById("UnityContent");
unity.SendMessage("MyObject", "MyFunction", "Hello from a web page!");
}
-->
</script>
사용자가 MyObject 라는 이름의 GameObject 에 스크립트를 첨부해야하고 그 스크립트는 MyFunction 이라는 함수를 구현해야하는
유니티 웹 플레이어 컨텐츠의 내부:
function MyFunction(param : String)
{
Debug.Log(param);
}
주의: 만약 함수가 인자를 가지지 않으면 빈 스트링 ("") 이 인자로 넘어와야 함에 주의하세요.
하나의 스트링, 정수 또는 float 인자는 SendMessage() 사용시 반드시 넘겨져야 하며 부르는 쪽에서는 그 파라미터가 필요합니다.
사용자가 그것이 필요가 없으면 간단히 0 또는 다른 기본 값을 넘겨주고 유니티 쪽에서는 그것을 무시합니다. 게다가 이름에 의해
명시된 그 게임 객체는 경로 이름의 형식으로 주어질 수 있습니다. 예를 들어, /MyObject/SomeChild 에서 SomeChild 는 MyObject 의
자식이어야 하고 MyObject 는 이름 앞의 ‘/’때문에 루트 레벨 이어야만 합니다.
Calling web page functions from Unity web player content
유니티 웹 플레이어 컨텐츠안에서 웹 페이지 함수를 부르기 위해서 사용자는 Application.ExternalCall()함수를 사용해야
합니다. 그 함수를 사용함으로써 사용자는 웹 페이지에 정의된 어떤 자바 스크립트 함수도 부를수 있고, 어떤 개수의 파라미터도
넘길 수 있습니다. 여기웹 페이제 안의 스트링 데이터를 인자로 넘겨주는 SayHello()라고 불리는 함수를 부르기 위해
Application.ExternalCall() 함수를 사용하는 유니티 스크립트의 예가 있습니다:
Application.ExternalCall( "SayHello", "The game says hello!" );
웹 페이지는 SayHello() 함수를 정의할 필요가 있습니다. 예를 들어:
<script type="text/javascript" language="javascript">
<!--
function SayHello( arg )
{
// show the message
alert( arg );
}
-->
</script>
Executing arbitrary browser code from Unity web player content
사용자는 삽입하는 웹페이지에 함수를 정의할 필요도 없습니다. 대신 사용자는웹 플레이어 컨텐츠로 부터 임의의 브라우저 코드를
실행하기 위해 Application.ExternalEval() 함수를 사용할 수 있습니다.
다음의 예제는 웹 플레이어 컨텐츠에 삽입된 페이지가 특정 호스트(unity3d.com)에서 가져왔는지 확인하는 예제 입니다. 가져오지
않았다면 다른 URL 로 리다이렉트 할 것입니다. 이 테크닉은 사용자의 웹 플레이어 컨텐츠의 딥 링킹을 방지하는데 사용될 수
있습니다:
Application.ExternalEval(
"if(document.location.host != 'unity3d.com') { document.location='http://unity3d.com'; }"
);
Using web player templates
Desktop
빠른 개발과 사용자 웹 플레이어의 의도된 세팅과의 테스트를 쉽게하기 위해 유니티는 다양한 템플릿과 사용자 정의 템플릿을
지원합니다.
템플릿은 특별한 태그를 지닌 인덱스 파일(이것은 간단히 html 파일로서의 php 파일일 수 있습니다)과 선택적인 미리보기 이미지를
포함하는 폴더 입니다. 폴더 이름은 템플릿 이름을 따르며 어떤 리소스도 포함할 수 있는데 예를 들어 하위 폴더, 이미자, 자바
스크립트, 서버 스크립트 등 입니다.
모든 프로젝트에서 접근 가능한 내장된 템플릿은 유니티 에디터의 Resources 폴더안의 WebPlayerTemplates 폴더에 위치하며
사용자 정의 템플릿은 사용자 프로젝트 에셋 폴더의 WebPlayerTemplates 라는 이름의 폴더에서 선택되어 집니다.
템플릿은 플레이서 세팅에서 선택가능 합니다. 사용자는 그곳에 각 미리보기(미리보기가 없을 때는 기본값 )와 리스트된 모든 가능한
템플릿을 찾을 수 있습니다. 어떤 템플릿은 템플릿 셀렉터 아래에서 텍스트 필드에서 즉시 변경 가능한 추가적인 속성을 가지고
있습니다.
템플릿 인덱스 파일 태그 번역 테이블:
Tag
Meaning
%UNITY_WEB_NAME%
웹 플레이어의 이름.
%UNITY_WIDTH%
웹 플레이어의 넓이.
%UNITY_HEIGHT%
웹 플레이어의 높이.
%UNITY_WEB_PATH%
unity3d 파일의 경로.
%UNITY_UNITYOBJECT_LOCAL%
로컬 UnityObject.js 파일의 경로.
%UNITY_UNITYOBJECT_URL%
unity3d.com 에 있는 UnityObject.js 의 URL.
%UNITY_BETA_WARNING%
유니티 베타 빌드 경고 메세지의 위치.
%UNITY_CUSTOM_SOME_TAG%
사용자 정의 템플릿 태그. 플레이어 세팅에서 설정할 수 있습니다.