블로그 이미지
Every unexpected event is a path to learning for you.

카테고리

분류 전체보기 (2106)
Unity3D (470)
Programming (453)
Unreal (2)
Gamebryo (56)
Tip & Tech (162)
협업 (26)
3DS Max (3)
Game (12)
Utility (101)
Etc (88)
Link (29)
Portfolio (18)
Subject (90)
iPhone (30)
Android (2)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (1)
Memories (16)
Interest (36)
Thinking (34)
한글 (23)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (16)
Exercise (3)
나만의 맛집 (2)
냥이 (7)
육아 (2)
Total1,099,602
Today111
Yesterday326
Statistics Graph

달력

« » 2017.10
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

공지사항

태그목록

Tistory Cumulus Flash tag cloud by BLUEnLIVE requires Flash Player 9 or better.

Edit -> Project Settings -> Player 들어가서 


Resolution and Presentation 에서 

Display Resolution dialog 에서 

[Disabled] = 실행시 설정창 비활성화 
[Enabled] = 실행시 설정창 활성화 
[Hidden By Default] = 평소에는 비활성화 Shift 누르면서 프로그램 실행시키면 설정창 활성화 입니다. 

참고 
http://openwiki.kr/unity/class-playersettings




저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by blueasa

댓글을 달아 주세요

문서들을 여기 저기 따로 공유하려느 번거로워서 유니티 최적화 관련 문서들을 모아두었습니다. 정리는 두서 없이 했고,다만 출처가 유니티 크루인지 아닌지로만 분류하였습니다. 추가적으로 발견하는 대로 지속적으로 갱신 할 예정입니다.


From Unity


from Developers


출처 : http://ozlael.tistory.com/32

저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by blueasa

댓글을 달아 주세요

Unity3d 50가지 팁

Unity3D/Tips / 2013.02.05 18:26

출처 원문

http://devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/

 

 

팁들에 대해서

이 팁들은 모든 프로젝트에 적용 가능하지는 않습니다.

  • 이것들은 3~20명의 인원으로 구성된 작은팀의 프로젝트 경험을 기반으로 합니다.
  • 구조, 재사용성, 명확성, 기타 등등 의 비용은 팀 크기와 프로젝트의 크기에 따라 비용 지불 여부가 결정 됩니다.
  • 많은 팁들은 취향의 문제 입니다.
    (하지만 여기에 나온 여러 팁들은 우열을 가리기 어려울 정도로 좋은 기술들 입니다.)
  • 몇개의 팁은 공식 Unity 개발에 위배 되는 것들입니다. 예를 들면, 몇개의 특수한 인스턴스를 위한 프리팹의 사용은 매우 Unity 에서 싫어하는 방식으로, 비용 또한 상당히 높습니다(이렇게 라도 prefab 들을 사용하는게 나을 때도 있습니다).  그러나 나는 이런 팁들이 미친 짓 같아 보여도 가끔 좋은 결과를 가지고 오는 경우도 보곤 합니다.

Process


1. 자산을 여러 버전으로 나누지 말라. 항상 모든 자산은 오직 한 버전으로 있어야 한다. 만약 절대경로로 프리팹, 씬, 또는 메쉬 등을 분기 하여 만드는 경우 옳은 버전이다. "잘못된" 분기는 임시적 이름으로, 예를들면 밑줄 두개를 접두로 붙이는 경우다. __MainScene_Backup. 프리팹을 분기 하는 경우 분명하게 이름을 명시하는게 안전하게 생성하는 방법이다. (Prefabs 섹션을 참고)

원문

2. 버전 컨트롤을 사용할 경우 각 팀 구성원들은 테스트를 위해 체크 아웃한 프로젝트의 두번째 복사본이 있어야 한다. 변경 후, 두번째 복사본은 clean copy 및 update 를 하고 test 를 해야 한다. 모든 사람들은 clean copy 상태에서 변경을 해야 합니다.

원문

3. 레벨 수정을 위한 외부 레벨 툴을 사용하는걸 고려하라. Unity 는 완벽한 레벨 에디터가 아니다. 예로, 우리는 3D tile 기반의 게임을 위해 레벨 빌드를 TuDee 를 사용하여 만들었으며, 우리는 tile 친화적인 툴을 통해 도움을 받았다 (그리드 가 붙는, 그리고 90 도 로 여러번 회전, 2d 뷰, 빠른 선택). XML 파일을 통한 prefab 초기화는 간단합니다. Guerrilla Tool Development 에 자세한 아이디어가 있습니다.

원문

4. 레벨 저장을 scene 대신 XML 으로 하는걸 고려하라. 이건 훌륭한 기술이다:

  • 이렇게 만들면 각각의 scene 을 다시 만드는게 불필요해 집니다.
  • 이렇게 만들면 보다 빠르게 로딩 합니다(대부분의 객체가 scene 에서 공유되는 경우)
  • 이렇게 만들면 scene 을 합치는게 쉬워집니다.(Unity 의 새로운 text 기반 scene 은 너무 많은 데이터를 포함하고 있어 합치는게 비현실적으로 보입니다)
  • 이렇게 만들면 데이터 레벨 수준에서 관리를 할 수 있습니다.
당신은 여전히 Unity 를 레벨 에디터 로 사용 할 수 있습니다(필요성을 못 느낄경우). 네가 데이터 , 에디터와 레벨 로드 를 실시간으로 처리, 에디터로 부터 레벨 저장을 해야 할 경우 몇몇의 코드는 직렬화 와 역직렬화를 필요로 하게 된다. 너는 아마 또한 객체간 참조를 유지하기 위해 Unity 의 id system 을 모방 해야 할 것입니다.

원문

5. 일반적인 커스텀 inspector 코드를 작성하는 걸 고려하라. 커스텀 inspector 를 작성하는건 매우 간단하나, Unity 의 시스템은 많은 단점을 가지고 있다.

  • 상속을 활용한 방식을 지원하지 않습니다.
  • 당신이 정의 하는 inspector 컴포넌트는 필드 타입 수준에서 구성이 안되며, 오로지 클래스 타입 레벨만 지원합니다. 예 로, 만약 모든 게임 오브젝트가 SomeCoolType 필드타입 이고, inspector 에서 다르게 렌더링 하려 할 경우,당신은 모든 클래스들에 대해서 inspector 를 작성해야 합니다.

당신은 기본적으로 inspector 시스템을 다시 구현함으로써 이러한 문제를 해결 할 수 있습니다. reflection의 몇가지 기술을 사용하여 해결할 수 있으며, 자세한 방법은 문서의 끝에 나와 있습니다.

원문


Scene Organisation

6. scene 폴더를 빈 게임 오브젝트 의 이름으로 사용하라. 당신의 scene 에서 찾고자 하는 오브젝트를 쉽게 찾을수 있도록 구성 할 수 있습니다.

원문

7. 관리하는 prefab 과 폴더 (빈 게임 오브젝트) 를 0 0 0 에 넣습니다. 만약 위치를 명시하지 않은 채 오브젝트의 위치를 사용 하면, 아마 원점에 있을겁니다. 그 방법은, 실행 중 로컬과 월드 공간간의 문제를 줄여줄 수 있으며, 코드는 일반적으로 간단합니다.

원본

8. GUI 컴포넌트의 offset 사용을 최소화 하라. Offset 은 항상 자신의 부모 Component 에서 레이아웃 Component 를 사용해야 합니다. 그들은 조부모(부모의부모)의 위치에 의존해서는 안됩니다. Offset 을 올바르게 표시하기 위해서는 서로를 취소 할 수 없습니다 . 이런 일을 방지하기 위해 기본적으로:

부모 컨테이너가 임의의 위치로  (100, -50) 이고, 자식의 위치가  (10, 10) 이기를 희망 할 경우, 위치 정의를 (90, 60) [relative to parent] 으로 하면 된다.

이 에러는 컨테이너가 invisible 상태일때 공통으로 발생하며, 또는 시각적 표현이 없는 경우에 해당합니다.

원문

9. 당신의 월드 바닥을 y = 0 으로 하라. 이와 같이 하면 오브젝트를 바닥에 생성하는게 쉬워지며, 게임 로직, AI, 물리 등을 2D 공간(이게 적절할 경우)으로 월드에 적용할 수 있습니다.

원문

10. 모든 scene 을 게임 실행 가능하게 만듭니다. 이건 대폭적으로 테스트 시간을 줄일 수 있습니다. 모든 scene 을 실행 가능하게 만들려면 두가지 고려사항이 있습니다:

첫번째로, 이전에 로드해야 하는 scene 의 데이터가 필요로 하는데 사용 할 수 없는 경우, 임시 데이터 를 제공 할 수 있도록 해야 합니다.

두번째로, 생성한 오브젝트는 다음의 scene 과 scene 을 불러오는 사이에 계속 되어야 한다.

myObject = FindMyObjectInScene();
 
if (myObjet == null)
{
   myObject = SpawnMyObject();
}

원문


Art

11. 케릭터와 서있는 오브젝트는 pivot 기반이여 하며, center 중심이어선 안된다 . 
이런식 으로 만들면 보다 쉽게 케릭터와 오브젝트를 바닥에 올려놓을 수 있습니다 . 이것은 또한 게임 로직, AI 와 물리 등이 필요로 하는 경우에 3D 환경에서 2D 같이 제작 할 경우 쉽게 만들 수 있습니다.

원문

12. 제작하는 모든 메시의 바라보는 방향을 일치 합니다(+Z 또는 -Z). 케릭터와 다른 오브젝트들의 메시는 바라보는 방향이 다르게 적용이 됩니다. 바라보는 방향을 통일 시키면 많은 알고리즘들을 쉽게 적용 할 수 있습니다.

원문

13. 시작시 스케일의 규모를 정하도록 한다. 만든 작업물을 임포트 할때 스케일 크기를 1로 하게 되면 그것의 트랜스폼 스케일은 1 1 1 이 된다. 스케일의 비교를 쉽게 하기 위해서 참조 오브젝트(Unity 상자)를 사용 합니다. 게임에 적합한 Unity 단위 비율을 선택하고, 정한것에 충실하도록 합니다.

원문

14. GUI 컴포넌트와 파티클을 수동으로 생성 해야 할 경우 2개의 삼각형으로 된 평면을 사용 합니다. 평면을 Z+ 방향으로 하는게 빌보드와 GUI 를 만드는데 쉽게 합니다.

원문

15. 테스트 작업물 만들기 및 사용

  • 스카이 박스들을 위한 사각형 표기.
  • 그리드(격자).
  • shader 테스트를 위한 다양한 평면 색상: 흰색, 검은색, 50% 회색, 적색, 녹색, 청색, 마젠타, 노랑, 청록색.
  • shader 테스트를 위한 그라데이션: 검은색 에서 흰색, 적색에서 녹색, 적색에서 청색, 녹색에서 청색.
  • 검은색과 흰색으로 된 체커보드(체커판).
  • 부드럽고 거친 노멀맵.
  • 빠른 테스트 scene 설정을 위한 라이팅 을 갖춤(프리팹).

원문

Prefabs

16. 모든 것에 프리팹을 사용하도록 한다.   당신의 scene 에 게임 오브젝트만 있는 경우에는 프리팹이 폴더에 있을 필요는 없습니다. 심지어 한번만 사용 하더라도 고유 객체를 프리팹으로 해야합니다. scene 을 바꾸지 않는 경우 만든것을 수정하는걸 편하게 작업할 수 있습니다. (또 다른 장점은 EZGUI 를 사용하는 경우 신뢰 할만한 스프라이트 아틀라스 를 구축할 수 있습니다.).

원문

17. 특수화된 프리팹은 사용해도 좋지만; 특수화 된 인스턴스는 사용하지 말라. 만약 다신이 두개의 적 타입을 가지고 있는 경우, 그리고 그것들이 프로퍼티만 다른 경우, 속성에 대해 별도의 프리팹을 만들고, 그것을 링크 합니다. 이렇게 하는게 가능한 경우는

  • 한 곳에서 각각의 타입을 변경 할 경우
  • scene 을 변경하지 않고 변경 할 경우

당신이 너무 많은 적 타입을 가지고 있을지라도, 특수화는 여전히 에디터의 인스턴스를 만들어서는 안됩니다. 한가지 대안책은 절차를 따르거나 또는 모든 적들을 기준의 파일 / 프리팹을 사용하는 겁니다. 적들을 구분하는걸 사용하여 하나의 적을 쓰러트리거나, 적의 위치 또는 플레이어 진행 기반의 알고리즘을 사용합니다.

원문

18. 프리팹과 프리팹의 링크는 되나; 인스턴스와 인스턴스 간의 링크는 안된다. scene 에 프리팹을 끌어놓을 때 프리팹의 연결이 유지 됩니다; 인스턴스에는 링크가 없습니다. 프리팹을 연결할 때마다 scene 의 설정을 줄여 주는게 가능해지며, scene 을 변경할 경우도 줄여줄 수 있습니다.

원문

19. 가능하다면, 인스턴스간의 연결 설정은 자동으로 하라. 만약 당신이 인스턴스간의 링크를 필요로 한다면, 프로그래밍적으로 링크를 설정 합니다. 예를 들어, Player 프리팹 자체를GameManager 을 시작함과 동시에 등록 할 수 있으며, 또는 GameManager 가 시작 할때 Player 프리팹 인스턴스를 찾을 수 있습니다.

만약 당신이 프리팹에 다른 스크립트를 추가 하길 원한다면 루트에 다른 메시를 넣어선 안됩니다. 당신이 메시로 부터 프리팹을 만들려고 한다면, 첫번째 메시의 부모는 비어있는 게임 오브젝트 이어야 하며, 그것은 루트 이어야 합니다. 스크립트를 루트에 넣게 되면, 메시 노드가 아니게 됩니다. 그 방법은 당신이 inspector 에서 설정한 모든 값을 잃어버릴일 없이 다른 메쉬와 메시를 대체하기 훨씬 쉬울 것 입니다.

하위 프리팹의 대안으로 연결된 프리팹을 사용합니다. Unity 는 하위 프리팹을 허용하지 않으며, 하위 프리팹 간의 관계가 명확하지 않기 때문에 팀에서 작업 할 때 기존의 타사 솔루션은 위험 할 수 있습니다.

원문

20. 분기 프리팹에 대해서 안전한 절차를 사용하도록 하라. 설명은 Player 프리팹 예제를 통해서 합니다.

프리팹을 바꾸는거에 대해 많은 문제에 대한 절차는:

  1. 복제된 Player 프리팹이 있습니다.
  2. 복제된 거에 대한 이름을 __Player_Backup 로 변경합니다.
  3. Player prefab 으로 생성한걸 바꿉니다.
  4. 작업이 진행 될 경우 __Player_Backup 를 지웁니다

복제후 Player_New 으로 이름을 바꺼선 안되며, 생성된걸 바꺼선 안됩니다!

일부는 상황이 더 복잡합니다. 예를 들어, 특정 변화는 두 사람을 포함 할 수 있으며, 두사람이 위의 과정을 따라하면서 작업을 완료하면 작업한 scene 을 망가질 수 있습니다. If it is quick enough, still follow the process above 그래도 여전히 필요로 하는경우, 위의 절차를 따르십시오. 바꾸는데 시간이 오래 걸릴경우, 다음의 절차를 따라야 할 수 있습니다:

  1. 사람 1:
    1. Player 프리팹을 복제 합니다.
    2. 이름을 __Player_WithNewFeature 나 __Player_ForPerson2 로 바꿉니다.
    3. 복제된 걸로 변경을 하고, 커밋을 하여 [사람 2] 에게 제공합니다.
  2. 사람 2:
    1. 새로운 프리팹으로 변경 생성 합니다.
    2. Player 프리팹을 복제하고, __Player_Backup 이라고 부릅니다. 
    3. __Player_WithNewFeature 인스턴스를 scene 으로 드래그 합니다.
    4. 오리지날 Player 프리팹을 인스턴스에 드래그 합니다.
    5. 작업이 진행 될 경우 __Player_Backup 와 __Player_WithNewFeature 를 지웁니다.

원문

Extensions and MonoBehaviourBase

21. 기본 mono behaviour 을 확장하고, 당신의 컴포넌트를 그것으로부터 모두 파생하라. 

이렇게 하면 몇가지 일반적인 기능을 구현 할 수 있으며, 이러한 유형의 호출에 안전하고 복잡한 호출이 가능해 집니다.(예로 무작위 호출)

원문

22. Invoke 를 위해 안전한 메서드를 정의 하며, StartCoroutine 과 Instantiate 가 있다.

Task delegate 를 정의하고, 문자열 이름에 의존하지 않는 방법을 정의 하는데 사용합니다.
예를 들면:

public void Invoke(Task task, float time)
{
   Invoke(task.Method.Name, time);
}

원문

23. 공유 인터페이스를 사용하여 컴포넌트를 함께 작동하도록 확장을 사용 합니다. 가끔 특정 인터페이스의 구현된 컴포넌트를 얻어오는데 편리하거나, 앞의 언급한 컴포넌트를 가지고 오브젝트를 찾는데 편합니다.

아래에 구현된 내용은 typeof 대신에 generic 버전의 함수들로 사용되고 있습니다. generic 버전은 인터페이스와 함께 작동하지 않지만, typeof 는 가능합니다. 아래의 방법은 generic 메소드를 이용하여 래핑합니다.

//Defined in the common base class for all mono behaviours
public I GetInterfaceComponent<I>() where I : class
{
   return GetComponent(typeof(I)) as I;
}
 
public static List<I> FindObjectsOfInterface<I>() where I : class
{
   MonoBehaviour[] monoBehaviours = FindObjectsOfType<MonoBehaviour>();
   List<I> list = new List<I>();
 
   foreach(MonoBehaviour behaviour in monoBehaviours)
   {
      I component = behaviour.GetComponent(typeof(I)) as I;
 
      if(component != null)
      {
         list.Add(component);
      }
   }
 
   return list;
}

원문

24. 구문보다 편리하게 사용하기 위해 확장을 사용합니다. 예를 들면:

public static class CSTransform 
{
   public static void SetX(this Transform transform, float x)
   {
      Vector3 newPosition = 
         new Vector3(x, transform.position.y, transform.position.z);
 
      transform.position = newPosition;
   }
   ...
}

원문

25. 방어적인 GetComponent 를 대안으로 사용 하라. Sometimes forcing component dependencies (through RequiredComponent) can be a pain. 때때로 강제적인 컴포넌트 의존(RequiredComponent 유발)은 고통이 될 수 있습니다. 예를들어, it makes it difficult to change components in the inspector 그것은 어려운 inspector 의 구성요소를 변경 할 수 있습니다(base type 이 같은 경우). As an alternative, the following extension of GameObject can be used when a component is required to print out an error message when it is not found. 대안으로, 확장된 GameObject 를 찾을때 컴포넌트가 발견되지 않은 경우 오류 메세지를 출력 하면 된다.

public static T GetSafeComponent<T>(this GameObject obj) where T : MonoBehaviour
{
   T component = obj.GetComponent<T>();
 
   if(component == null)
   {
      Debug.LogError("Expected to find component of type " 
         + typeof(T) + " but found none", obj);
   }
 
   return component;
}

원문

Idioms

26. 비슷한 일에 다른 해결책을 사용하지 마십시오. 대부분의 경우 일을 할때마다 하나 이상의 해결책이 있습니다. 이러한 경우, 프로젝트에 한가지 방법을 선택하고 진행 할 수 있습니다. 여기에 이유가 있습니다:

  • 몇가지 해결책이 함께 잘 작동하지 않습니다. 한가지 해결챌을 사용하면 다른 해결책에 적합하지 않으며 한 방향으로 디자인을 강요 합니다.
  • 몇가지 해결책을 사용하는게 어디로 가야 하는지 팀 멤버를 이해 시킵니다. 이것은 구조와 코드를 이해하기 쉽게 합니다. 실수를 하기 더 쉽도록 유도가 됩니다.

해결책 그룹들의 예시:

  • Coroutines vs. state machines.
  • 하위 프리팹들 vs. 연결된(링크) 프리팹들 vs. 전지 전능한 프리팹들.
  • 데이터 분리 전략.
  • 2D 게임에서 상태를 위해 스프라이트를 사용 하는 방법.
  • 프리팹 구조화.
  • Spawn 전략.
  • 개체를 찾을 수 있는 방법: 타입 vs. 이름 vs. 태그 vs. 레이어 vs. 레퍼런스(링크).
  • 그룹 개체들을 찾는 방법: 타입 vs. 이름 vs. 태그 vs. 레이어 vs. 레퍼런스(링크) 배열
  • 오브젝트의 그룹들 찾기 vs 자체 등록 (싱글톤 객체?)
  • 실행 순서 제어 (Unity 를 이용하여 실행 순서 제어 vs. yield 로직 vs. Awake / Start 와 Update / Late Update 의존 vs. 수동 메소드 vs. 모든 주문 아키텍쳐)
  • 개체 / 위치 / 타겟 의 선택과 인 게임의 마우스: 선택 관리자 vs 로컬 자체 관리
  • scene 변화와 데이터 간의 유지: PlayerPrefs 를 통해, 또는 새로운 scene 이 로드 될때 지워지지 않은 객체.
  • 애니메이션 결합 방법 (블렌딩, 더하거나 레이어링(계층관리)).

원문

Time

27. 쉽게 일시 중지 하기 위해 당신만의 Time class 를 유지 하라. Wrap Time.DeltaTime 와 Time.TimeSinceLevelLoad 은 계정 별 일시 중지와 시간 scale 이 가능합니다. 이것을 사용하는데는 훈련이 필요로 하지만, 많은 부분에 대해 쉽게 제작 가능하며, 특히 다른 Time 의 일을 실행 하기 편합니다. (예로 interface 애니메이션과 게임 애니메이션 등)

원문

Spawning Objects

28. 게임이 실행 될 때 생성되는 개체가 계층 구조를 더럽히게 하지 말라. Set their parents to a scene object to make it easier to find stuff when the game is running. 
게임이 실행 중 일때 개체를 쉽게 찾을 수 있도록 scene 개체에 부모를 설정 합니다. 비어있는 게임 오브젝트를 사용하거나 behaviour 가 없는 싱글톤을 이용하여 만들면 코드에 접근하기 쉽습니다. 이 오브젝트를  DynamicObjects 라고 부릅니다.

원문

Class Design

29. 편의를 위해 싱글톤 을 사용하라. 다음 클래스는 자동으로 싱글톤 을 상속하는 클래스를 만들 것 입니다:

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
   protected static T instance;
 
   /**
      Returns the instance of this singleton.
   */
   public static T Instance
   {
      get
      {
         if(instance == null)
         {
            instance = (T) FindObjectOfType(typeof(T));
 
            if (instance == null)
            {
               Debug.LogError("An instance of " + typeof(T) + 
                  " is needed in the scene, but there is none.");
            }
         }
 
         return instance;
      }
   }
}

싱글톤은 관리자에 유용하며, ParticleManager 또는 AudioManager 또는  GUIManager 등이 있습니다.

  • 고유한 프리팹의 인스턴스를 위한 싱글톤은 사용하는걸 피하는고 관리하지 않는게 좋습니다(Player 같은). 이 원칙을 준수하지 않으면 상속 계층 구조를 복잡하게 하며, 그리고 특정 유형의 변경을 힘들게 합니다. 오히려 GameManager 에서 참조를 유지하는게 좋습니다.(또는 다른 전지 전능한 클래스 ;-))
  • 종종 클래스 외부에서 사용되는 public 변수 와 메소드 에 대한 static 속성과 메서드를 사용합니다. GameManager.Instance.player 대신에  GameManager.Player 으로 작성이 가능합니다.

원문

30. component 들을 들어, inspector 에 변화를 주지 말아야 할 변수는 공개 하지 않습니다. 그렇지 않으면 그것은 무엇을 하는지 알수 없게 되여 디자이너가 변경을 해버리게 됩니다. 이런 경우 두줄 이나 네줄의 언더스코어를 접두로 변수 이름에 붙이면 수정을 꺼리게 될 것이다.
(역자 : 이런 경우 [HideInspector] 를 변수 상위에 붙이면 아예 노출이 일어나지 않습니다)

public float __aVariable;

원문

31. 게임 로직에서 인터페이스를 분리하여 제공합니다. 이것은 기본적으로 MVC 패턴 입니다.

모든 입력 컨트롤러는 호출되여 알려 해당 컴포넌트에 명령을 제공해야 합니다. 컨트롤러 로직을 예로, 컨트롤러는 플레이어의 상태에 따라 제공할 명령을 결정 할 수 있습니다. 그러나 이것은 안좋습니다 (예로 컨트롤러를 더 추가하는 경우 중복된 로직으로 불릴 가능성이 있습니다). 대신에, 플레이어 객체는 앞으로 이동을 할 경우에 통지 해야만 하며,  현재 상태(예를 들어 느려졌거나 아니면 기절)에 따라 속도를 설정하고 Player 의 방향을 업데이트 합니다. 컨트롤러는 자신의 상태에 관한 일을 해야 합니다(컨트롤러는 플레이어가 상태를 바꾸려고 할때 상태가 바뀐 상태인지 알수가 없습니다; 따라서, 컨트롤러는 전혀 플레이어의 상태를 알수 없습니다). 또 다른 예는 무기의 변화 입니다. 할 수 있는 옳은 방법은 GUI 가 플레이어의 SwitchWeapon 을 호출 하는 방법입니다. GUI 는 transform 과 부모와 모든 요소에 대해서 조작해선 안됩니다.

모든 인터페이스 컴포넌트는 데이터를 유지해야하고 자신의 상태에 관한 처리를 합니다. 예로, 맵을 표시하거나, GUI 는 플레이어의 움직임에 따라 표시 할수 있도록 계산을 합니다. 그러나, 이것이 게임 상태 데이터 이면, GUI 에 속해서는 안됩니다. GUI 는 단지 게임 상태 데이터를 표시해야 하며, 데이터는 다른곳에 유지해야 합니다. map 데이터는 다른곳에서 유지해야 합니다(예를 들어, GameManager 에서).

게임플레이 오브젝트는 GUI 에 대해서 아는게 거의 없습니다. 한가지 예외는 일시 정지 행동으로, Time.timeScale 을 통해 전체적으로 제어 합니다(물론 이는 좋은 생각은 아닙니다.. 보기에는). 게임플레이 오브젝트는 게임이 멈춘 상태일 때 알아야 합니다. 하지만 그게 전부 입니다. 따라서 게임 플레이 오브젝트로 부터 GUI 컴포넌트를 연결할 필요는 없습니다.

일반적으로, 당신이 GUI 클래스들을 모두 지울 경우에도, 게임은 여전히 컴파일 되야 합니다.

당신은 또한 GUI 와 input 을 재 구현시 새로운 게임 로직을 작성할 필요가 없어야 합니다.

원문

32. 별도의 상태와 Bookkeeping. Bookkeeping 변수는 빠르게 또는 편리하게 사용하기 위함이며, 그리고 현재 상태로부터 복구하는걸 가능하게 해준다. 이렇게 분리하면, 당신은 더 쉽게 적용 가능하다.

  • 게임 상태 저장, 그리고
  • 게임 상태 디버그

한가지 방법은 각각의 게임 로직 클래스를 위해 SaveData 클래스를 정의 하는 것이다.

[Serializable]
PlayerSaveData
{
   public float health; //public for serialisation, not exposed in inspector
} 
 
Player
{
   //... bookkeeping variables
 
   //Don’t expose state in inspector. State is not tweakable.
   private PlayerSaveData playerSaveData; 
}

원문

33. 별도의 특성화 구성.

동일한 메시들로 두개의 적을 고려 하는데, 벨런스 값이 다르다.(예를 들어 다른 힘과 다른 스피드를 가지고 있는경우). 별도의 데이터에 대해 여러가지 방법이 있습니다. 이중에 하나는 내가 원하는 것일거라 생각하며, 오브젝트가 생성될 때나, 게임이 저장될 때 입니다.

(Tweakable 들은 상태 데이터가 아니나 구성 데이터로, 그래서 저장할 필요가 없습니다. 개체가 로드 되거나 생성되는경우, tweakable 들은 별도로 자동으로 로드 됩니다.)

  • 각각의 게임 클래스에 템플릿 클래스를 정의합니다. 예로, 적인 경우 우리는 또한 EnemyTemplate 라고 정의 합니다. 모든 차별화된 tweakable 들은 EnemyTemplate 에 저장합니다.
  • 게임 로직 클래스 에는, 변수나 템플릿 타입을 정의 합니다.
  • 적 프리팹을 만들고, 두개의 템플릿 프리팹 WeakEnemyTemplate, andStrongEnemyTemplate 을 만듭니다.
  • 로딩하거나 오브젝트를 생성하면, 정식 템플릿에 템플릿 변수를 설정 합니다.

이 방법은 매우 정교한 방법이 될 수 있습니다. (그리고 때로는 불필요하게 복잡하므로 주의!)

예를 들어, generic 다형성을 사용하기 위해, 우리는 아마 이런식으로 정의 하는게 좋을겁니다:

public class BaseTemplate
{
   ...
}
 
public class ActorTemplate : BaseTemplate
{
   ...
}
 
public class Entity<EntityTemplateType> where EntityTemplateType : BaseTemplate
{
   EntityTemplateType template;
   ...
}
 
public class Actor : Entity <ActorTemplate>
{
   ...
}

원문

34. 표시 텍스트 이외에 다른 용도로 문자열을 사용하지 마시오. 특히, 개체 나 프리팹의 식별을 위해서 문자열을 사용하지 않습니다. 한가지 어쩔수 없는 예외는 애니메이션 으로, 일반적으로 자신의 문자열 이름으로 접근 할수 있습니다.

원문

35. Avoid using public index-coupled arrays 공개된 인덱스 결합 배열을 사용하지 마시오. 예로 무기 배열, 총알 배열, 파티클 배열 을 정의 하지 않는 것으로, 이런 경우에 대해서 좋은 방법은 아래와 같습니다:
(역자 : 배열의 인덱스를 직접적으로 사용하는걸 줄이라는 의미 인거 같습니다)

public void SelectWeapon(int index)
{ 
   currentWeaponIndex = index;
   Player.SwitchWeapon(weapons[currentWeapon]);
}
 
public void Shoot()
{
   Fire(bullets[currentWeapon]);
   FireParticles(particles[currentWeapon]);   
}

이런 코드를 많이 사용 하지 않는 문제는, inspector 에 설정 할 때 실수를 할 가능성이 있기 때문 입니다.

오히려, 세 변수를 캡슐화 하는 클래스를 정의하고 그 배열을 확인 하십시오.

[Serializable]
public class Weapon
{
   public GameObject prefab;
   public ParticleSystem particles;
   public Bullet bullet;
}

이 코드는 보기에 단정해 보이나, 매우 중요하며, inspector 에 데이터를 셋팅할 때 실수하기 어렵습니다.

원문

36. 시퀀스 이외의 다른 구조에 대한 배열을 사용하지 마시오. 예로, 플레이어가 세개의 공격 타입을 가지고 있다고 칩시다. 각각 현재 무기를 사용하지만 서로 다른 포탄과 다른 동작을 생성합니다.

당신은 아마 배열을 사용해 세개의 총알을 발사 하려하며, 이러한 로직을 사용할 것입니다:

public void FireAttack()
{
   /// behaviour
   Fire(bullets[0]);
}
 
public void IceAttack()
{
   /// behaviour
   Fire(bullets[1]);
}
 
public void WindAttack()
{
   /// behaviour
   Fire(bullets[2]);
}

Enums 을 사용하면 좀 더 나은 코드가 될 수 있습니다...

public void WindAttack()
{
   /// behaviour
   Fire(bullets[WeaponType.Wind]);
}

그러나 inspector 에서는 안됩니다.

그것은 별도의 변수를 사용하는 것이 좋기 때문에 어떤 콘텐츠를 넣어도 이름으로 도움말이 될 수 있습니다. 타입이 단정 지어질때 클래스를 만듭니다.
[Serializable]

public class Bullets
{
   public Bullet FireBullet;
   public Bullet IceBullet;
   public Bullet WindBullet;
}

Fire 를 설정하면 Ice 와 Wind 데이터는 없다고 가정합니다.

원문

37. serializable 클래스의 그룹 데이터는 가까운거 끼리 모아 inspector 로 만들어야 한다 . 어떤 엔티티는 수십개의 조절할게 있을수 있습니다.  이 경우 inspector 에 연결될 변수를 찾는게 악몽이 될 수 있습니다. 더 쉽게 만들기 위해, 다음의 단계를 따르십시오: 

  • 변수의 그룹에 대한 별도의 클래스를 정의 합니다. 
    그것들을 public 및 serializable 합니다.
  • 기본 클래스에서, 위와 같이 정의된 각각의 유형의 public 변수를 정의 합니다.
  • 변수를 Awake 나 Start 에서 초기화 하면 안되며; 그것들은 serializable 이기 때문에, Unity 에서 잘 처리 해줄 것입니다.
  • 당신은 정의된 변수가 연결되기 전에 초기화를 지정하는게 가능하다 

inspector 의 접을 수 있는 공간의 그룹 변수들은, 관리를 쉽게 합니다.
 

[Serializable]
public class MovementProperties //Not a MonoBehaviour!
{
   public float movementSpeed;
   public float turnSpeed = 1; //default provided
}
 
public class HealthProperties //Not a MonoBehaviour!
{
   public float maxHealth;
   public float regenerationRate;
}
 
public class Player : MonoBehaviour
{
   public MovementProperties movementProeprties;
   public HealthPorperties healthProeprties;
}

원문

Text

38. 스토리 텍스트가 많은 경우, 파일에 넣도록 합니다. inspector 의 에디팅 할수 있는 영역으로 두지 마십시오. 이것은 Unity 에디터를 열지 않고도 변경을 쉽게 해줄 것이며, 특히 scene 을 저장하지 않고도 가능할 것입니다.

원문

39. 당신이 로컬라이징을 할 계획이 있다면, 하나의 지역에 모든 문자열을 분리합니다. 
이 작업을 수행하는 방법에는 여러가지가 있습니다. 한가지 방법은 예를 들어, 기본값을 영어로 설정하고, 각 문자열에 대한 공개 문자열 필드에 텍스트 클래스를 정의 하는 것입니다. 다른 언어는 하위 클래스를 두고 언어에 맞추어 다시 초기화 하는 것입니다.

더 정교한 기법은 (텍스트의 길이가 길고 / 길거나 언어의 갯수가 많은 경우 적절합니다)sheet 로부터 읽어오고 선택된 언어로부터 기본이 되는 문자열을 선택해서 로직에 제공 하는 것입니다.

원문

Testing and Debugging

40. 물리, 애니메이션, 그리고 AI 를 디버깅하기 위해 그래픽 logger를 구현 합니다. 이건 상당히 빠르게 디버깅 할 수 있게 합니다. 여기에 자세한 정보가 있습니다 here.

원문

41. HTML logger를 정의 합니다.  몇가지 경우에 대해서, logging 은 매우 유용 합니다. 
구문 분석(컬러 코드, 멀티 뷰, 스크린샷 기록)을 하게 되면 로그를 디버깅 하는게 훨씬 쾌적 할 수 있습니다. 여기에 자세한 정보가 있습니다 here.

원문

42. 당신의 FPS counter 를 구현합니다. 예. Unity 의 FBS counter 가 정말 제대로 측정할지도 모르나, 그것은 프레임 레이트가 아닙니다. 직관과 육안 검사와 일치 할 수 있도록 자신의 것을 구현 합니다.

원문

43. Implement shortcuts for taking screen shots 스크린샷을 이용해 바로가기를 구현 합니다.  많은 버그는 비쥬얼이며, 그리고 당신은 사진을 찍어두면 보고가 좀 더 쉬워집니다. 이상적인 시스템은 스크린샷을 덮어씌우지 않도록 PlayerPrefs 의 카운터를 유지 해야 합니다. 스크린샷은 실수로 사람들이 저장소에 커밋하는걸 방지하기 위해 프로젝트 폴더 외부에 저장해야 합니다.

원문

44. 플레이어의 월드 위치를 출력하기 위한 바로가기를 구현 합니다. 이것은 월드의 특정 장소에서 발생하는 버그의 위치를 리포트를 하기 쉬워질 것이며, 이는 번갈아 가면서도 쉽게 디버깅 할 수 있습니다.

원문

45. 테스트를 쉽게 만들기 위한 디버그 옵션을 구현합니다. 몇가지 예를 들면:

  • 모든 아이템 언락
  • 적 제거
  • GUI 끄기
  • 플레이어 무적
  • 모든 게임 플레이 불가.

원문

46. 충분히 작은 팀의 경우, 디버그 옵션을 사용하여 각 팀의 구성원을 위한 prefab 을 만듭니다. 파일에 사용자 ID 를 넣고: 게임이 실행 될 때 읽어집니다. 이 이유는:

  • 팀 구성원은 사고로 자신의 디버그 옵션을 커밋 하고 모두에게 영향을 미치기 않기 위함입니다.
  • 디버그 옵션을 바꾸는 것은 scene 을 바꾸는게 아니기 때문입니다.

원문

47. 모든 게임 플레이 요소와 scene 을 유지 합니다. 예로, 모든 적이 있는 scene, 당신이 상호 작용 할수 있는 모든 개체, 그외 등등. 너무 오래 게임을 하지 않고 기능을 테스트 할 수 있도록 합니다.

원문

48. 디버그 바로 가기 키를 위한 상수를 정의하고, 한 곳에서 보관 합니다. 디버그 키는 일반적으로 (또는 편리한) 게임 입력이 처리 되는 위치에서 같이 처리 되지는 않습니다. 바로 가기 키의 충돌을 방지 하기 위해 중앙 위치에 상수를 정의 합니다. 대안으로 디버그 함수인지 아닌지 상관없이 한 곳에 모든 키를 처리 하는 겁니다. (단점은 이 클래스는 이 개체에 대해서 참조를 추가로 해야 할 수도 있습니다)

원문

Documentation

49. 설치를 문서화 합니다. 대부분의 코드는 문서에 있어야 하며, 하지만 이러한 것은 코드 외부에서 문서화 해야합니다. 디자이너가 설정하기 위한 코드를 선별하여 만드는것은 시간 낭비 입니다. 문서 설정이 효율이 극대화 됩니다 (만약 문서가 최신이라면).

다음 사항을 문서화 합니다:

  • 레이어 사용 (충돌, 컬링, raycasting – essentially, 어떤 항목에 어떤걸 해야)
  • 태그 사용.
  • 레이어를 위한 GUI 깊이 (무엇을 통해서 표시해야)
  • scene 설치
  • Idiom 설정
  • 프리팹 구조
  • 애니메이션 레이어

원문

Naming Standard and Folder Structure

50. 문서화 규칙 및 폴더 구조를 따르시오. 일관성 규칙 및 폴더 구조는 쉽게 찾고자 하는걸 찾을 수 있으며, 일이 무엇인지 파악 할 수 있습니다.

당신은 아마도 자신의 규칙 및 폴더 구조를 생성 할 수 있습니다. 다음의 예는 한가지 입니다.

원문

Naming General Principles

  1. 무언가를 호출 합니다. bird 는 Bird 를 호출 합니다. 
  2. 이름을 선택 할 때는 확연하고 기억될 수 있는 이름으로 선택합니다. 만약 당신이 마야 게임을 만든다고 해서, 레벨 이름을 QuetzalcoatisReturn 로 해서는 안됩니다.
  3. 일관성을 유지 하십시오. 이름을 선택할때, 기준에 충실해야 합니다.
  4. Use Pascal case, like this: ComplicatedVerySpecificObject. Do not use spaces, underscores, or hyphens, with one exception (see Naming Different Aspects of the Same Thing).
    이와같이 파스칼 케이스를 사용합니다: ComplicatedVerySpecificObject. 공간( ), 언더바(_), 또는 하이푼(-), 한가지 예외와 함께 (같은 일에 다른 이름을 보게 될 경우)
  5. 버전 번호를 사용하지 말고, 또는 단어로 진행 상태를 표시 하지 마십시오 (WIPfinal).
  6. Do not use abbreviations: DVamp@W should be DarkVampire@Walk.
    약어를 사용하지 마십시오: DVamp@W 는 DarkVampire@Walk .으로 표기 합니다
  7. 디자인 문서의 용어를 사용합니다: 사망 을 문서상 호출 하려면 Die 애니메이션을 부릅니다. DarkVampire@Die, 를 부르며 DarkVampire@Death 는 안됩니다.
  8. 구체적인 설명은 왼쪽에 표기 합니다: DarkVampire 는 좋은 방법이며 VampireDark 는 안좋은 방법입니다. PauseButton는 좋은 방법이며 ButtonPaused는 안좋은 방법입니다. 이것을 예로 들면, 모든 버튼이 단어 버튼으로 시작하면 inspector 에서 일시 정지 버튼을 찾기 쉬워집니다. [많은 사람들이 다른 방법을 더 선호하며, 때문에 시각적으로 보다 더 확실히 그룹화를 하여 생성합니다. 이름이 있지만 그룹화를 위한게 아니며, 폴더를 위한것 입니다. 이름이 안정적으로 빠르게 자리 잡고 할 수 있도록 동일한 유형의 객체를 구분하는 것 입니다.]
  9. 일부 이름은 순서를 형성합니다. 이름에 숫자를 사용하며, 예로 PathNode0,PathNode1 가 있습니다. 항상 시작은 1이 아닌 0으로 시작합니다.
  10. 순서를 필요로 하지 않는 일에 번호를 사용하지 마십시오. 예로 Bird0Bird1,Bird2 는 FlamingoEagleSwallow 라고 표기합니다.
  11. 임시 객체는 이중으로 접두사에 언더바를 넣습니다 __Player_Backup.

원문

Naming Different Aspects of the Same Thing

언더바와 핵심 이름을 사용하여, 해당 상태에 "세부" 내용 설명합니다. 예로 들면:

  • GUI 버튼 상태는 EnterButton_Active, EnterButton_Inactive
  • 텍스쳐는 DarkVampire_Diffuse, DarkVampire_Normalmap
  • 스카이 박스는 JungleSky_Top, JungleSky_North
  • LOD 그룹은 DarkVampire_LOD0, DarkVampire_LOD1

단지 다른 유형의 항목 구분이 규칙을 사용하면 안되며, 예로  Rock_Small, Rock_Large 를 SmallRock, LargeRock 으로 사용 하는 경우 입니다.

원문

Structure

당신의 scene 의 구성, 프로젝트 폴더, 그리고 스크립트 폴더는 유사한 패턴을 가져야 합니다.

원문

Folder Structure

Materials
GUI
Effects
Meshes
   Actors
      DarkVampire
      LightVampire
      ...
   Structures
      Buildings
      ...
   Props
      Plants
      ...
   ...
Plugins
Prefabs
   Actors
   Items
   ...
Resources
   Actors
   Items
   ...
Scenes
   GUI
   Levels
   TestScenes
Scripts
Textures
GUI
Effects
...

Scene Structure

Cameras
Dynamic Objects
Gameplay
   Actors
   Items
   ...
GUI
   HUD
   PauseMenu
   ...
Management
Lights
World
   Ground
   Props
   Structure
   ...

Scripts Folder Structure

ThirdParty
   ...
MyGenericScripts
   Debug
   Extensions
   Framework
   Graphics
   IO
   Math
   ...
MyGameScripts
   Debug
   Gameplay
      Actors
      Items
      ...
   Framework
   Graphics
   GUI
   ...

How to Re-implement Inspector Drawing

1. 당신의 모든 에디터를 위한 기본 클래스를 정의

BaseEditor<T> : Editor 
where T : MonoBehaviour
{
   override public void OnInspectorGUI()
   {
      T data = (T) target;
 
      GUIContent label = new GUIContent();
      label.text = "Properties"; //
 
      DrawDefaultInspectors(label, data);
 
      if(GUI.changed)
      {         
         EditorUtility.SetDirty(target);
      }
   }
}

2. reflection 과 recursion 를 사용하여 draw 컴포넌트에 reflection 을 사용

public static void DrawDefaultInspectors<T>(GUIContent label, T target)
   where T : new()
{
   EditorGUILayout.Separator();
   Type type = typeof(T);      
   FieldInfo[] fields = type.GetFields();
   EditorGUI.indentLevel++;
 
   foreach(FieldInfo field in fields)
   {
      if(field.IsPublic)
      {
         if(field.FieldType == typeof(int))
         {
            field.SetValue(target, EditorGUILayout.IntField(
            MakeLabel(field), (int) field.GetValue(target)));
         }   
         else if(field.FieldType == typeof(float))
         {
            field.SetValue(target, EditorGUILayout.FloatField(
            MakeLabel(field), (float) field.GetValue(target)));
         }
 
         ///etc. for other primitive types
 
         else if(field.FieldType.IsClass)
         {
            Type[] parmTypes = new Type[]{ field.FieldType};
 
            string methodName = "DrawDefaultInspectors";
 
            MethodInfo drawMethod = 
               typeof(CSEditorGUILayout).GetMethod(methodName);
 
            if(drawMethod == null)
            {
               Debug.LogError("No method found: " + methodName);
            }
 
            bool foldOut = true;
 
            drawMethod.MakeGenericMethod(parmTypes).Invoke(null, 
               new object[]
               {
                  MakeLabel(field),
                  field.GetValue(target)
               });
         }      
         else
         {
            Debug.LogError(
               "DrawDefaultInspectors does not support fields of type " +
               field.FieldType);
         }
      }         
   }
 
   EditorGUI.indentLevel--;
}

위 method 는다음과 같은 헬퍼를 사용한다:

private static GUIContent MakeLabel(FieldInfo field)
{
   GUIContent guiContent = new GUIContent();      
   guiContent.text = field.Name.SplitCamelCase();      
   object[] descriptions = 
      field.GetCustomAttributes(typeof(DescriptionAttribute), true);
 
   if(descriptions.Length > 0)
   {
      //just use the first one.
      guiContent.tooltip = 
         (descriptions[0] as DescriptionAttribute).Description;
   }
 
   return guiContent;
}

이 inspector 에 툴팁을 생성하기 위해 클래스 코드에 주석을 사용합니다.

3. Define new Custom Editors

불행하게도, 당신은 여전히 각각의 MonoBehaviour 를 위한 클래스를 정의 해야 합니다. 다행히도, 이러한 정의는 비어 있을것이며; 모든 실제 작업은 기본 클래스에 의해 이루어 집니다.

[CustomEditor(typeof(MyClass))]
public class MyClassEditor : BaseEditor<MyClass>
{}

이론적으로 이 단계는 자동일 수 있지만, 난 아직 시도 해보지 않았습니다.


[출처] Unity3d 50가지 팁|작성자 다크엔젤

저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by blueasa

댓글을 달아 주세요


- 유니티 설정 바꾸기


1. 자신의 유니티 프로젝트를 엽니다.


2. 상단 메뉴에 Edit - Project Settings - Editor 를 누릅니다.




3. 그러면 오른쪽 Inspector창에 Editor Settings가 뜨는데

    Version Control 항목이 있습니다. 거기서 Disable을 Meta Files로 바꿔줍니다.


    스샷에서 빼먹은 부분이 있는데 Inspector창 맨 아래에 Asset Srialization Mode를 Force 

    Text로 바꿔주시기 바랍니다.




4. 프로젝트를 저장 하시고, Unity를 끕니다.




여기까지 따라 하셨다면 이제 SVN설정을 합시다.


SVN 체크아웃된 경로 안에 프로젝트 폴더가 복사되어 있다고 가정하고 쓰겠습니다.


중요한것은 프로젝트 경로명에 한글이 들어가서는 절대로 안됩니다.


- SVN 설정하기


1. 프로젝트 폴더에서 무시목록을 추가합니다.


obj

Temp

*.suo

*.user

*.pidb

*.userprefs


2. 프로젝트 폴더 안에 Library 폴더에서 무시목록을 추가합니다.


cache

metadata

previews

ScriptAssemblies

assetDatabase3

AssetImportState

assetservercachev3

AssetServerCacheV3

AssetVersioning.db

AudioManager.asset

BuildPlayer.prefs

BuildSettings.asset

DynamicsManager.asset

EditorSettings.asset

EditorUserBuildSettings.asset

expandedItems

FailedAssetImports.txt

guidmapper

InspectorExpandedItems.asset

MonoManager.asset

NetworkManager.asset

ScriptMapper

unity default resources

unity editor resources


2. 프로젝트 폴더 안에 Library 폴더를 무시목록에 추가합니다.

(위에 추가하는거나 Library폴더 전체 무시나 같더군요)


3. 커밋합니다.




- SmartSVN에서 설정하기 (회사에서 SmartSVN을 사용하기 때문에 SmartSVN에 대한 설명도 적겠습니다.)


1. SmartSVN을 켭니다.


2. 해당 프로젝트를 SVN 경로에 복사합니다.



3. Assets 폴더를 오른쪽 클릭후 Add 누르고 OK를 누릅니다.



4. ProjectSettings 폴더를 오른쪽 클릭후 Add 누르고 OK를 누릅니다.



5. 해당 프로젝트에 오른쪽 클릭후 Properties - Ignore Patterns를 누릅니다.



6. 위에 무시목록을 복사해서 붙여넣은 후 OK를 누릅니다. (Depth는 기본상태로 둡니다)



7. 해당 프로젝트에 Library 폴더에 오른쪽 클릭 후 Add 를 누릅니다. (OK버튼 바로 누르지 않도록 주의)



8. Add 팝업창에서 Depth를 Only this directory로 변경 후 OK를 누릅니다.



9. 해당 프로젝트에 Library 폴더에 오른쪽 클릭 후 Properties - Ignore Patterns를 누릅니다.



10. 위의 무시목록을 복사해서 붙여넣은 후 Depth를 Immediate children (files and directories)를 선택한 뒤 OK를 누릅니다.



11. Library 폴더에 전체 선택후 Add를 누릅니다.




그냥 Library 폴더를 무시목록 추가하고 OK 누르시면 됩니다.


12. 커밋합니다.


출처 : http://sekainonaka.tistory.com/170

저작자 표시 비영리 동일 조건 변경 허락
신고

'협업 > SVN' 카테고리의 다른 글

Unity SVN 연동  (0) 2014.04.11
Unity3D SVN 연동 방법  (0) 2014.01.03
Unity3D SVN 연동방법  (0) 2012.12.25
Posted by blueasa

댓글을 달아 주세요

유니티를 안드로이드 버전으로 빌드하기 위해서 테스트를 해봤다.


내 폰은 아이폰이라 넣으면서 하진 못하고, 우선 apk 파일 만들기까지 해 봄..


아래는 안드로이드 빌드하기 위해 준비한 것 들.. 생각외로 간단하다..


1) 아래 링크로 가서 안드로이드 SDK를 설치한다.

    (http://developer.android.com/sdk/index.html)


2) JDK가 없으면 1) 설치 중에 JDK 설치하라고 뜬다. 아래 링크로 가서 Java SE를 받아서 설치해 주자..

    참고로 V7 버전이 빌드가 잘 안된다는 글이 있어서 V6으로 깔았다. 아래 링크에 두 버전 다 있음.. 선택..

    그리고, 윈도가 64bit(x64)라고 해서 64bit(x64)를 깔면 안됨.. 32bit(x86)로 깔라고 한다..

    (http://www.oracle.com/technetwork/java/javase/downloads/index.html)


3) 위 두 파일이 모두 설치되고 나면, 유니티의 'Edit-Preferences.-External Tools-Android SDK Location'으로 가서 폴더를 지정해 준다.(폴더 선택하러 들어가면 해당 폴더는 알아서 찾는 것 같다. 우측의 블럭된 폴더명을 삭제하고 그냥 '폴더 선택'을 누르면 된다.)


4) 'Android SDK Location' 셋팅을 하고 나서 'File-Build Settings-Platform'을 Android로 맞춘다.


5) 'File-Build Settings' 아래 Player 'Settings..' 를 누르면 Inspector 창에 이런저런 정보가 나오는데 아래와 같이 셋팅한다.

   (셋팅 설명은 있는데 정확히 무슨 옵션이고 뭘 위한건지 체크는 하지 못했다. 디폴트로 해보기도 해야될 것 같다.)

OtherSetting을 누르고

Identification 에서 Bundle Identifier 가 있는데 com.회사이름.플젝이름 이런식으로 고쳐서 써줌니다.

예) com.ABC.Project1

그리고 Minimum Api Level 에 현재 빌드할 폰의 안드로이드 버전에 맞게 설정합니다.

현재 폰의 버전보다 적은 버전해도 상관없음

Configuration 에서 Devices Level 을 ARMv6 with VFP 로 바꾸시고(Unity 4.x  버전에서는 ARMv7밖에 없으니 ARMv7로 하세요)

Graphics Level 을 OpenGL ES 1.x 로 바꿉니다.

그리고 Resolution and Presentation 을 누르고

Default Orientation 으로 어플의 뭐 가로세로 방향 을 고정시킬수있습니다.

Status Bar에 Status Bar Hidden은 핸드폰의 상단 바를 보이느냐 마느냐를 설정하는 것입니다.


6) 다하고나서 'File-Build Settings-Build' 를 하면 apk 파일이 생성된다.


7) 알아서 폰에 넣고 설치를..



참조 : http://cookzy.tistory.com/698

참조 : http://blog.naver.com/nameisljk/110136124090

저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by blueasa

댓글을 달아 주세요

  1. 2013.03.10 13:35 신고 ㄳㄳ  댓글주소  수정/삭제  댓글쓰기

    감사합니다!!!!

  2. 2013.04.04 05:52 신고 부엉이  댓글주소  수정/삭제  댓글쓰기

    Error building Player: UnityException: Couldn't find Android device
    No Android devices found. If you are sure that device is attached then it might be USB driver problem, for details please check Android SDK Setup section in Unity Manual.

    이 에러 이유 아시나요???

    • 2013.04.04 09:30 신고 blueasa  댓글주소  수정/삭제

      안드로이드 디바이스를 찾지 못한다는 에러네요.
      컴퓨터가 안드로이드 폰을 제대로 인식못했거나, USB 자체 문제거나, 안드로이드 SDK가 제대로 안깔렸거나 했을 가능성이 있습니다.
      체크를 한 번 해보셔야 될 것 같아요.

  3. 2013.04.05 00:55 신고 부엉이  댓글주소  수정/삭제  댓글쓰기

    컴퓨터에 apk 파일을 받을순 없는건가요 ?
    실행말고요

  4. 2013.04.05 01:08 신고 부엉이  댓글주소  수정/삭제  댓글쓰기

    그 usb 문제라는것은 무슨소린가요??
    usb 이용한적이 없는데.

    • 2013.04.05 10:25 신고 blueasa  댓글주소  수정/삭제

      Build and Run은 폰을 usb에 연결한 상태로 하는거라..
      이 경우에 usb가 문제있을경우에도 안될 수도 있다는 것 뿐입니다.
      Build만 했다면 그 문제보단 sdk가 제대로 안깔렸거나 해서 인식을 못하는 상태일 가능성이 큽니다.

  5. 2013.04.05 01:11 신고 부엉이  댓글주소  수정/삭제  댓글쓰기

    안드로이드 빌드해서
    컴퓨터에 apk파일이 깔리는지만 확인하려 하는데
    필요한게 더 잇나요 ???

    • 2013.04.05 10:28 신고 blueasa  댓글주소  수정/삭제

      Build를 하면 apk파일은 생성되지만 apk파일은 안드로이드 폰에서의 설치파일로 알고 있습니다.
      PC에서는 압축파일로 취급받는걸로 압니다만..
      깔진 못하는걸로 알고 있습니다.
      안드로이드 폰으로 옮겨서 깔아보셔야 하지 않을까 싶네요.

  6. 2013.04.05 03:36 신고 부엉이  댓글주소  수정/삭제  댓글쓰기

    이상하게 전 디바이스 레벨에 ARMv7 뿐이없던데 왜그런건가요???
    귀찮게 해서 죄송합니다

    • 2013.04.05 10:36 신고 blueasa  댓글주소  수정/삭제

      위 설명은 Unity 3.x 버전 기준입니다.
      Unity 4.x 이상으로 버전업 되면서 ARMv6 옵션이 사라졌더라구요.
      그냥 ARMv7로 하시면 됩니다. :)

  7. 2013.04.07 08:35 신고 부엉이  댓글주소  수정/삭제  댓글쓰기

    인식을 못할경우엔 어떻게 해야하죠 ???
    재설치를 해야하나요??

    • 2013.04.07 14:56 신고 blueasa  댓글주소  수정/삭제

      부엉이님과 같은 에러를 제가 본 경우는 Android SDK가 잘못깔렸거나(32비트를 깔아야되는데 64비트를 깔았다거나..), 깔렸는데 Andoid SDK Location 설정이 잘못됐거나..이클립스에서 업데이트 식으로 깔았다면 이클립스 업데이트에서 중단됐다거나(다운하다가 알아서 중지돼 버리는 경우가 자주 있었습니다.) 하는 경우였습니다.
      예상으론 SDK쪽이 문제일 가능성이 있으니 유니티를 재설치는 하지 않으셔도 될거라 생각합니다.
      문제가 언능 해결되길 바랄게요~ =_=

  8. 2013.04.10 03:39 신고 부엉이  댓글주소  수정/삭제  댓글쓰기

    안드로이드 디바이스를 찾지 못한다는데
    sdk를 아무리 재설치 해도 않되네요 ㅠㅠ
    usb 문제인가 해서 보니 usb는 잘되고 ㅜㅜ

    • 2013.04.11 02:23 신고 blueasa  댓글주소  수정/삭제

      음..
      재설치해도 안된다면 제 생각으로 우선 체크해야 될 게..
      - sdk가 x86(32bit)인지 체크해 보시구요.
      - sdk 설치 후, Android SDK Location이 맞는지 확인해 보셔야 될 것 같습니다. 폴더 위치가 다를 수 있으니 android-sdk 폴더를 찾아보세요. =ㅅ=

  9. 2013.04.11 10:48 신고 부엉이  댓글주소  수정/삭제  댓글쓰기

    adt-bundle-windows-x86-20130219 제가 다운받은게 이거인데 일단
    32bit는 맞는데 이 파일 맞나요??

    • 2013.04.12 04:35 신고 blueasa  댓글주소  수정/삭제

      제가 깐 건 Java Platform, Standard Edition에 Java SE 6 Update 43의 JDK 입니다.
      DOWNLOAD로 가보시면 실제 파일명은
      Windows x86 69.76 MB jdk-6u43-windows-i586.exe
      입니다.
      아직 JDK가 제대로 안깔린게 아닌가 싶네요.

  10. 2013.04.11 10:50 신고 부엉이  댓글주소  수정/삭제  댓글쓰기

    Location 확인은 어떻게 해야하나요?

  11. 2013.09.22 16:23 신고 lee taehee  댓글주소  수정/삭제  댓글쓰기

    진째 개감사 ㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜ님 밥먹을래요 저랑??? ㅜㅜㅜㅜ

1. MonoBehaviour 
  모든 스크립트가 상속받는 기본 클래스입니다.
 (Javascript 는 무조건 MonoBehaviour 를 상속받고 C#, Boo 의 경우 명시적으로 상속받아야 합니다.
  C#, Boo 에서 단순 데이터 보관용 클래스, 전역으로 동작하는 매니저 클래스같은 건 상속받지 않고 쓸 수 있습니다.)
  MonoBehaviour 는 Behaviour 클래스를 상속받고 Behaviour 는 Component 를 상속받습니다.
  즉 MonoBehaviour 를 상속받은 클래스는 게임 오브젝트에 component 로 붙일 수 있다는 뜻입니다.(붙일 수 있다는 건 모두 알고 계시죠? ㅎㅎ)
Behaviour 클래스는 enable/disable 가능합니다.
때문에 MonoBehaviour 도 역시 켜고 끌 수 있습니다.
(스크립트를 Inspector 에 붙이면 앞에 체크박스가 나오죠? 그겁니다.)
레퍼런스를 보면 MonoBehaviour,  Behaviour, script 라는 명칭을 혼재해서 쓰는데 혼란을 줄 수 있으니, 앞으로 모두 '스크립트'로 통칭하도록 하겠습니다.

2. 앞에 On 이 붙지 않는 함수

 1) Update

  Update 함수는 스크립트가 켜져 있을 때(enabled 상태일 때) 매 프레임마다 호출됩니다.
  Update 함수는 스크립트에서 가장 빈번하게 사용되는 함수입니다.
  지나간 시간을 알고 싶으면, Time.deltaTime 을 사용하면 됩니다.
  이 함수는 스크립트가 켜져 있을 때만 불립니다.

 2) LateUpdate

   LateUpdate 함수는 스크립트가 켜져 있을 때 매 프레임마다 호출됩니다.
   LateUpdate 함수는 모든 Update 함수가 호출된 후 호출됩니다.
   이것은 스크립트의 실행 순서를 정하는 것에 도움이 됩니다.
   예를 들어 따라다니는 카메라는 언제나 LateUpdate 를 구현해야 하는데, 그 이유는 이 카메라가 따라가는 오브젝트들은
   Update 함수 안에서 움직일 가능성이 있기 때문입니다. 이 함수는 스크립트가 켜져 있을 때만 불립니다.

 3) FixedUpdate

   FixedUpdate 함수는 스크립트가 켜져 있을 때 매 프레임마다 호출됩니다.
   FixedUpdate 함수는 Rigidbody 를 다룰 때 Update 대신에 사용됩니다.
   예를 들어 rigidbody에 일정한 힘을 가할 때, FixedUpdate를 구현하여 매 fixed frame 마다 힘을 가해주어야 합니다.
   ※ FixedUpdate 는 매 프레임마다 호출되지만 한 프레임에 여러번 호출될 수도 있습니다. ??
   

더보기


   

 // 매 프레임마다 rigid body 에 위로 향하는 힘을 가해준다.
 // 즉 이 예는 등가속 운동입니다. (Vector3.down 하면 중력을 받는 것과 동일하다는 뜻입니다.)
function FixedUpdate()
 {
     rigidbody.AddForce(Vector3.up);
 }

 

4) Awake

  Awake 함수는 스크립트 객체가 로딩될 때 호출됩니다.
  Awake 함수는 게임이 시작하기 전에 변수나 게임 상태를 초기화하기 위해 사용합니다.
  Awake 함수는 스크립트 객체의 라이프타임 동안 단 한번만 호출됩니다.
  Awake 함수는 모든 오브젝트가 초기화된 후 호출되기 때문에, 다른 오브젝트에 메시지를 날리거나 GameObject.FindWithTag 같은 함수를 안전하게 사용할 수 있습니다.
이런 이유로 Awake 함수에서 스크립트를 레퍼런싱한 후, Start 함수에서 필요한 정보를 넘겨받거나 넘겨줄 수 있습니다.
Awake 함수는 언제나 Start 함수 전에 호출됩니다. 이것은 스크립트의 초기화 순서를 정할 수 있게 합니다.
Awake 함수는 coroutine 으로 동작할 수 없습니다.

 5) Start

  Start 함수는 Update 함수가 처음 호출될 때 Update 함수 직전에 호출됩니다.
  Start 함수는 스크립트가 동작하는 라이프타임 동안 단 한번만 호출됩니다.
  Awake 함수와의 차이는 Start 함수는 스크립트가 켜져있을 때만 호출된다는 것입니다.
  이것은 정말로 필요할 때까지 초기화 코드 실행을 연기시킬 수 있습니다.
  Awake 함수는 언제나 Start 함수가 호출되기 전에 호출됩니다. 이것은 스크립트의 초기화 순서를 정할 수 있게 합니다.
  Start 함수는 모든 스크립트 객체의 Awake 함수가 호출된 후에 호출됩니다.

 6) Reset

  기본값으로 리셋합니다.
  Reset 함수는 유저가 Inspector의 context menu 에서 Reset 버튼을 눌렀을 때나, 게임 오브젝트에 스크립트를 처음 붙였을 때 호출됩니다. 이 함수는 에디터 모드에서만 호출됩니다.
Reset은 Inspector에 초기 값을 설정할 때 가장 자주 사용하는 함수입니다.

 
 7 ) Awake, Start, Update, LateUpdate 순서도

'A,  B, C 라는 게임 오브젝트가 있고, A, B 에 스크립트가 하나씩 붙어있습니다. B는 스크립트가 비활성화 되어 있습니다.'
 라는 상황을 가정하겠습니다.

 1. 게임이 로딩되면 우선 A, B, C 모든 게임 오브젝트가 초기화 됩니다.
 
 2. 이후 A, B 에 붙어있는 스크립트의 Awake 함수가 호출됩니다.
   (이 상황에서도 이미 A, B, C 게임 오브젝트와 구성 컴포넌트는 모두 메모리에 들어있는 상태이므로 null 체크 
   이런 거 없이 안심하고 데이터 전달 등을 할 수 있습니다.)

 3. 이후 A 의 Update 함수가 호출되려고 합니다. B 는 스크립트가 비활성화 상태이기 때문에 동작하지 않습니다.

 4. A 의 Update 함수가 호출되려고 하는데, 이번이 첫번째 호출이네요! 우선 Start 가 호출됩니다.

 5. A 의 Start 가 호출되었으니 Update 가 호출됩니다. 앞으로 매 프레임마다 호출되겠네요.

 6. A 의 LateUpdate 도 호출됩니다. 역시 앞으로 매 프레임마다 호출됩니다.

 - 여기서 B의 스크립트를 활성화시켰습니다.

 7. B 의 Update 함수도 호출되기 시작합니다. 제일 처음 Update 호출될 때 역시 Start 가 우선 한 번 호출됩니다.

 8. A, B 의 Update 함수가 모두 호출된 후 A, B 의 LateUpdate 가 호출됩니다.

 - 여기서 C에 스크립트 컴포넌트를 붙였습니다.

 9. C 에 스크립트가 붙자 C의 Awake 가 호출됩니다.

 10. A, B, C 의 Update 차례. C의 경우 처음 Update 호출이라서 그전에 Start 함수가 우선 호출됩니다.

 11. A, B, C 의 LateUpdate 차례. A, B, C 의 모든 Update가 끝나면 호출되기 시작합니다.


 


3. On~ 계열 함수

 1) OnMouse~ 함수군

  마우스와 GUIElement, Collider 사이의 인터랙션에 관련한 함수 집합입니다.
  게임 오브젝트가 Ignore Raycast 레이어에 속해있으면 호출되지 않습니다. (내부적으로 Raycast 를 하는 듯.)
  이 함수들은 co-routine 으로 사용할 수 있습니다. (yield 사용 가능.)
  이 이벤트는 GUIElement, Collider 에 붙어있는 모든 스크립트에 전달됩니다.

  OnMouseEnter - 마우스가 처음 오브젝트 위로 올라왔을 때 호출.
  OnMouseOver - 마우스가 오브젝트 위에 있을 경우 매 프레임마다 호출.
  OnMouseExit - 마우스가 처음 오브젝트 밖으로 나갔을 때 호출.
  OnMouseDown - 오브젝트 위에서 마우스 버튼을 눌렀을 때 호출.
  OnMouseUp - 오브젝트 위에서 마우스 버튼을 땠을 때 호출. 눌렀을 때의 오브젝트와 같은 오브젝트일 때만 호출됨.
  OnMouseDrag - 오브젝트 위에서 마우스 버튼을 누른 상태로 있을 때 매 프레임마다 호출.

  여기서 Drag 는 일반적으로 생각하는 드래그가 아니라 그냥 꾸욱 누르고 있는 상태를 나타냅니다. 
 (물론 그 상태로 마우스를 움직이면 드래그지만..)
  그리고 오브젝트 위에 마우스를 올려놓고 누르고 있으면 Over와 Drag 가 매 프레임마다 호출됩니다. 
  Drag 호출된다고 Over 호출 안된다거나 하는 거 없습니다. *ㅅ*

  스크립트가 enable / disable 과 상관없이 호출됩니다.
  즉 Inspector 에서 체크박스를 해제해도 스크립트가 붙어있다면 무조건 호출됩니다.
  앞으로 '스크립트가 켜져있을 때만 호출된다.' 는 말이 없으면 기본적으로 비활성화 상태에서도 호출된다고 생각하세요.

 2) OnTrigger~(other : Collider), OnCollision~(collisionInfo : Collision) 함수

  OnTrigger~, OnCollision~ 은 모두 충돌 관련 함수입니다.
  충돌이 일어나려면 두 오브젝트 모두 Collider 를 가져야 하고 둘 중 하나는 Rigidbody 를 가져야 합니다.
  그리고 Rigidbody 를 가진 쪽이 움직여서 서로 만날 경우만 이벤트가 일어납니다. 물론 둘 다 움직이고 있어도 됩니다.
  (그러니까 Rigidbody 를 가진 녀석은 가만히 있는데 그냥 Collider 가 아무리 와서 들이박아도 아무런 일도 생기지 않는다는 겁니다. ==> 중요한것입니다.)

  Trigger 는 Inspector 창에서 Collider 의 Is Trigger 속성이 켜져있을 때 발생합니다.
  Trigger 가 켜져있을 때는 Collision 관련 함수는 호출되지 않습니다.
  Trigger 가 켜져있을 때는 두 오브젝트 사이에 물리 계산이 이루어지지 않습니다.
   그래서 Trigger 는 단순한 '영역' 으로 이해하는 것이 좋습니다.

  Collision 은 두 오브젝트 중 적어도 하나가 Inspector 창에서 Rigidbody 의 Is Kinematic 속성이 꺼져있을 때 발생합니다.
   (Is Kinematic 이 켜져있으면 이 오브젝트는 내부 물리연산을 하지 않기 때문에 부딪쳐도 그냥 뚫고 지나갑니다.)
  두 오브젝트 모두 Kinematic 속성이 켜져있으면 어느 쪽이 움직여서 겹치더라도 물리 연산이 이루어지지 않기 때문에 
  충돌 함수가 호출되지 않습니다.

  Trigger 는 함수의 파라메터로 Collider 변수가 들어옵니다. 이것은 자신과 접촉한 오브젝트의 Collider 입니다.
  Collision 은 함수의 파라메터로 Collision 변수가 들어옵니다. 이것은 접촉에 대한 여러가지 정보를 담고 있는 클래스입니다.

  relativeVelocity - 두 오브젝트의 상대 속도입니다. 충격량이라는 느낌일까요? (읽기 전용)
  rigidbody - 자신과 접촉한 Rigidbody 입니다. 
                  만약 상대가 Rigidbody 가 없는 Collider 라면 이 값은 null 입니다. (읽기 전용)
  collider - 자신과 접촉한 Collider 입니다. (읽기 전용)
  transform - 자신과 접촉한 오브젝트의 Transform 정보입니다. (읽기 전용) 
  gameObject - 자신과 접촉한 오브젝트입니다. (읽기 전용)
  contacts - 물리 엔진에서 연산한 접촉 포인트 정보입니다. ContactPoint 의 배열입니다.

두 종류 모두 ~Enter, ~Stay, ~Exit 함수를 제공합니다.

Enter 는 접촉을 시작했을 때 호출,
Stay 는 접촉 중일 때 매 프레임마다 호출,
Exit 는 접촉이 끝났을 때 호출됩니다.

두 함수군 모두 yield 사용 가능합니다.


 * Mesh Collider 관련해 추가 설명 

기본 도형으로 이루어진 Collider 이외에 실제 모델같은 Mesh Collider 를 붙일 수도 있습니다. (알고 계시겠죠? ㅎ)
그런데 기본적으로 Mesh Collider 는 다른 Mesh Collider 와 충돌 계산이 이루어지지 않습니다.
아마 계산이 오래 걸리기 때문에 막아놓은 것으로 보입니다. 기본 도형은 대체로 방정식 몇번 풀면 체크 끝나지만, Mesh 는... 모든 폴리곤을 순회하면서 체크해야 하니까요.
그래도 하고 싶은 사람을 위해 준비된 Inspector 창의 Mesh Collider 의 Convex 속성을 켜면 다른 Mesh Collider 와 충돌 계산을 합니다. 단, Convex 속성을 켜기 위해서는 Mesh Collider 의 폴리곤 개수가 255개를 넘으면 안됩니다.
이런 제한이 있습니다~ 간단한 게임이나 계산 파워가 부족한 iphone 게임을 만들 때는 굳이 Mesh Collider 쓸 필요는 없을 것 같습니다.

3) OnControllerColliderHit(hit:ControllerColliderHit)
 CharacterController 가 Move 함수로 이동하는 도중 다른 Collider 와 충돌했을 때 호출됩니다.
 (CharacterController 가 붙어있는 gameObject 를 Translate 로 움직여서 충돌할 때는 호출되지 않습니다. 
  무조건 CharacterController 의 Move 함수로 움직일 때만 호출됩니다.)
CharacterController 는 이전 충돌 함수 때처럼 따로 Rigidbody, Collider 가 필요없습니다.

4) OnJointBreak(breakForce:float)
게임 오브젝트에 붙어있는 조인트가 끊어질 때 호출됩니다.
조인트에 설정된 breakForce 보다 높은 힘이 가해지면 조인트는 끊어집니다.
조인트가 끊어질 때 주어진 힘이 파라메터로 들어옵니다.
조인트가 끊어지고 OnJointBreak 가 호출된 후 조인트는 자동적으로 게임 오브젝트에서 지워집니다.

5) OnParticleCollision(other:GameObject)
파티클이 Collider 와 충돌했을 때 호출됩니다.
WorldParticleCollider 와 충돌한 Collider 에 붙어있는 모든 스크립트에 호출됩니다.
Inspector 창에서 WorldParticleCollider 의 sendCollisionMessage 속성을 켜야지 호출됩니다.
 (즉, 기본적으로 WorldParticleCollider 가 붙어있어야 합니다.)
Collider 는 따로 Rigidbody 일 필요 없습니다. yield 사용 가능합니다.

6) OnBecameVisible / OnBecameInvisible
 renderer 가 어떤 카메라에 보이기 시작할 때, 보이지 않기 시작할 때 호출됩니다.

레퍼런스 설명은 위와 같은데, '어떤' 카메라라는 것은 여러대의 카메라가 있을 때 그 중 하나라도 보이기 시작하면 Visible, 모두 보이지 않을 때 Invisible 이라는 것이며, 단, 카메라가 있어도 비활성화 상태이거나 화면에 보이지 않을 경우 (즉 View Port Rect 의 width, height 가 0일 때) 는 '어떤' 카메라에 포함되지 않습니다.
오브젝트의 renderer 컴포넌트를 꺼도 마찬가지로 Invisible 입니다.

그러니까 단순히 말해서  어쨌든 화면에 보이기만 하면 Visible, 안보이면 Invisible 입니다.

renderer 에 붙어있는 모든 스크립트에 호출됩니다.
화면에 보일 때만 스크립트가 처리되도록 할 때 유용합니다.
yield 사용 가능합니다.

 // 화면에 보일 때만 스크립트 활성화.
function OnBecameVisible ()
 {
     enabled = true;
 }
 function OnBecameInvisible()
 {
     enabled = false;
 }


주의점이 있습니다. 툴에서 작업할 때 Scene View 에도 동일하게 동작합니다.
Game View 에서 안보여도 Scene View 에서 보이고 있는 상태라면 Invisible 호출이 안됩니다.

7) OnLevelWasLoaded(level:int)
새로운 레벨(scene)이 로딩되었을 때 호출됩니다.
level 파라메터는 로딩된 레벨의 인덱스를 나타냅니다.
메뉴 File - Build Settings... 에서 레벨과 인덱스를 설정할 수 있습니다.
yield 사용 가능합니다.
레퍼런스에는 적혀있지 않지만 해당 장면의 모든 스크립트에서 호출되는 것 같습니다.

8) OnEnable/OnDisable
스크립트가 켜지거나 꺼졌을 때 호출됩니다.
추가로 OnDisable 의 경우 스크립트가 붙은 게임 오브젝트가 제거될 때도 호출되므로 파괴자로 사용할 수 있습니다.
툴에서 플래이 모드 중에 스크립트를 편집할 경우, 편집이 끝난 후 스크립트가 다시 로딩되면서 OnDisable, OnEnable 이 순차적으로 호출됩니다.
참고로 툴에서 플래이 중 스크립트를 고쳤을 때 고쳐진 스크립트의 Awake, Start 는 호출되지 않습니다.
그리고 OnEnable 은 Awake 함수 바로 다음에 호출됩니다. (켜져있을 경우)

9) OnGUI
 GUI 를 그리거나 이벤트를 처리하기 위해 호출됩니다.
이벤트 처리도 맡고있기 때문에 한 프레임에 여러번 호출될 수 있습니다. (한 이벤트에 한 번) 스크립트가 꺼져있으면 호출되지 않습니다.
OnGUI 함수 안에서 Event.current 를 사용하면 현재 처리하고 있는 이벤트 내용을 알 수 있습니다.
이 때 사용되는 Event 클래스의 내용은 다음과 같습니다.

 type - 이벤트의 타입. (http://unity3d.com/support/documentation/scriptReference/EventType.html)
 mousePosition - 마우스 위치. (Vector2)
 delta - 지난번 처리한 이벤트와 현재 마우스 위치의 차이. (Vector2)
 button - 어떤 마우스 버튼이 눌려졌는지. (int) (0:왼쪽, 1:오른쪽, 2:가운데)
 clickCount - 마우스 클릭 횟수. (int)
 character - 키보드로 입력한 문자. (char)
 commandName - 단축키로 입력된 명령. (string) ("Copy", "Cut", "Paste", "Delete"... 툴에서만 호출.)
 keyCode - 키보드로 입력한 가공되지 않은 키코드.(http://unity3d.com/support/documentation/scriptReference/KeyCode.html)
 shift - 쉬프트 눌려져 있는지.
 control - 컨트롤 눌려져 있는지.
 alt - 알트 눌려져 있는지.
 command - Command(맥)/Windows(윈도우) 키 눌려져 있는지.
 capsLock - CapsLock 켜져있는지.
 numeric - 키패드 입력인지.
 functionKey - 펑션키 입력인지.
 isKey - 키보드 이벤트인지.
 isMouse - 마우스 이벤트인지.

Event 클래스의 기타 함수는 영역이 애매해서 따로 설명하지 않습니다. (http://unity3d.com/support/documentation/scriptReference/Event.html)

10)  OnApplicationPause(pause:bool)
플레이어가 정지/재개될 때 모든 스크립트에서 호출됩니다. yield 사용 가능합니다.

11) OnApplicationQuit 
어플리케이션이 종료되기 직전에 모든 스크립트에서 호출됩니다.

12) OnDrawGizmos 
게임 오브젝트에 기즈모를 추가합니다.
이 기즈모는 선택할 때 사용할 수 있고 언제나 그려집니다.

13) OnDrawGizmosSelected 
게임 오브젝트가 선택되었을 때 기즈모를 그리고 싶을 때 구현합니다. 이 기즈모는 선택에 사용할 수 없습니다.
Gizmos 클래스는 http://unity3d.com/support/documentation/scriptReference/Gizmos.html 에서 사용법을 확인할 수 있습니다.

혹 기즈모가 뭔지 모르시는 분은..
툴의 Scene 뷰에 빛이나 카메라의 위치를 볼 수 있게 해 주는 아이콘이 기즈모입니다.
눈에 보이지 않지만 위치 설정이 필요할 때, 중요한 오브젝트를 보기 좋게 표현하기 위해.. 기타 여러가지 이유로 사용할 수 있습니다. 실제 어플리케이션에는 표시되지 않지만 툴로 작업할 때 여러모로 편하게 해 줍니다.
공동 작업할 때 자주 사용하면 좋을 거라 생각합니다.

4. 렌더링에 관련한 고급 기능

 1) OnPreCull
  
카메라에서 장면을 컬링하기 전에 호출됩니다. 여기서 컬링이란 프러스텀 컬링입니다. (후면 컬링 아님)
  카메라에 붙어있는 스크립트에만 호출됩니다. 
  카메라의 속성을 바꾸고 싶을 때, 이 함수 안에서 하면 좋습니다.
  이 함수가 호출된 후 실제 프러스텀 컬링을 하고 각 오브젝트가 화면에 그려질지 그려지지 않을지 정해집니다.

 2) OnPreRender
  카메라가 장면을 렌더링하기 전에 호출됩니다.
  카메라에 붙어있는 스크립트에만 호출됩니다.
  yield 사용 가능합니다.

 3) OnPostRender
  카메라가 장면을 렌더링한 후 호출됩니다.
  카메라에 붙어있는 스크립트에만 호출됩니다.
  yield 사용 가능합니다.
  이 함수는 해당 카메라가 모든 오브젝트를 렌더링한 후 호출됩니다.
  만약 '모든' 카메라와 GUI가 렌더링된 후 무언가를 하고 싶으면 WaitForEndOfFrame coroutine 을 사용하면 됩니다.

 4) OnWillRenderObject()
  해당 오브젝트를 렌더링하는 카메라마다 한 번 호출됩니다.
  (세 대의 카메라가 하나의 오브젝트를 보고 있으면 그 오브젝트에 붙어있는 스크립트에서 세 번 불린다는 뜻.)
  (툴에서 작업할 때는 Scene View 카메라도 들어갑니다.)
  이 함수는 렌더링하기 전, 컬링 중에 호출됩니다.
  Camera.current 를 사용하면 현재 어떤 카메라가 렌더링할 것인지 알 수 있습니다.

 5) OnRenderObject(queueIndex:int)
  오브젝트가 렌더링될 때 호출됩니다. queueIndex 는 해당 오브젝트를 렌더링할 때 사용하는 렌더 큐의 값입니다.
  RenderBeforeQueues 속성으로 특정한 렌더링 큐에서 동작하도록 설정할 수 있습니다.
  이 함수도 OnWillRenderObject 함수처럼 각 카메라가 그릴 때마다 한 번 호출됩니다.

 6) OnRenderImage(source:RenderTexture, destination:RenderTexture)
  모든 렌더링이 끝난 후 호출됩니다. 카메라에 붙어있는 모든 스크립트에서 호출됩니다.
  포스트 프로세스 효과를 줄 때 사용합니다. (Pro 전용)
  source 는 렌더링이 끝난 화면이며 destination 텍스쳐에 결과물을 그려주면 됩니다.
  카메라에 여러 이미지 필터가 붙어있을 경우 순차적으로 진행됩니다.


게임의 경우 때깔내는데 가장 중요한 포스트 프로세싱 부분이 Pro 전용으로 빠져있습니다.
(그러고 보니 free 에서 렌더 타겟이 사용 불가였으니 당연히 이것도 사용이 불가능하겠네요.)
여기 있는 함수들은 제가 사용해 본 적이 없고, 지금 당장 특별히 어떻게 쓰면 좋을지 잘 모르는 관계로 특별한 부연 설명 없이 레퍼런스를 옮겨적기만 했습니다.

참고로 3.0 부터 이쪽 함수들은 스크립트가 꺼져있으면 동작하지 않는다고 합니다.

5. 네트워킹 관련 함수
점점 써 본적이 없는 함수만 나와서 정말 난감하네요;;;

 1) OnPlayerConnected(player:NetworkPlayer)
   새 유저가 성공적으로 접속했을 경우 서버에서 호출됩니다.

 2) OnServerInitialized
   Network.InitializeServer 를 호출한 후 완료되었을 때 서버에서 호출됩니다.

 3) OnConnectedToServer
   서버에 성공적으로 접속했을 경우 클라이언트에서 호출됩니다.

 4) OnPlayerDisconnected(player:NetworkPlayer)
   유저의 접속이 끊겼을 경우 서버에서 호출됩니다.

 5) OnDisconnectedFromServer(mode:NetworkDisconnection) 
  서버와 접속이 끊기거나 접속을 종료했을 때 클라이언트에서 호출됩니다.

 6) OnFailedToConnect(error:NetworkConnectionError)
  접속 시도가 실패했을 때 클라이언트에서 호출됩니다.

 7) OnFailedToConnectToMasterServer(error:NetworkConnectionError)
  서버나 클라이언트에서 마스터 서버로의 접속에 문제가 있을 경우 호출됩니다.

 8) OnMasterServerEvent(msEvent:MasterServerEvent)
  서버나 클라이언트로 마스터 서버에서 보낸 이벤트를 받았을 때 호출됩니다.

 9) OnNetworkInstantiate(info:NetworkMessageInfo)
  Network.Instantiate 함수로 네트워크를 통해 게임 오브젝트가 생성되었을 때 해당 오브젝트에서 호출됩니다.
  네트워크 상에서 새 게임 오브젝트가 생성되었을 때 다른 사람이 생성했는지 내가 생성했는지에 따라 오브젝트에 특별한 
  처리를 할 때 유용합니다.

 10) OnSerializeNetworkView(stream:BitStream, info:NetworkMessageInfo)
  네트워크 상에서 전달되는 변수들(variables in a script watched by a network view)의 동기화 처리를 커스터마이징할 
  때 사용합니다..
  이 함수는 직렬화된 값 (즉 BitStream으로 바뀐 정보)을 전달할 것인지 받을 것인지에 대해서 자동으로 판단합니다.
 (이 오브젝트를 소유권에 따라서 처리됩니다. 소유자는 보내고 나머지는 받고.)



출처 : http://kimseunghyun76.tistory.com/194

저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by blueasa
TAG 유니티

댓글을 달아 주세요

따로 솔루션을 열 때는 활성화가 되던데, 유니티에서 스크립트 파일을 더블클릭하면 Visual Assist(이하 VAX)가 비활성화 돼 있어서 해결방법이 없나 하고 찾아봤다.


완전한 해결책은 아니지만, VS를 켜놓는 한은 계속 유지되니 이 방법으로 우선 살아도 될 것 같다.


1) 유니티에서 스크립트 더블클릭해서 VS로 오픈(External Script Editor를 VS2010으로 변경 해놓은 상태)한다.


2) 열어보면 VAX가 활성화가 안돼 있다.


3) Assets-Sync MonoDevelop Project 클릭


4) 열려있던 VS2010 창을 클릭해보면 '리로드' 하라고 뜬다.


5) '리로드' 하면 VAX가 활성화 돼있다.


6) 이후 VS창을 끌 때까진 VAX가 활성화 상태다.(VS를 끄면 위 방법대로 다시 실행하면 됨)




참조 : http://answers.unity3d.com/questions/138135/issues-using-visual-assist-x-with-visual-studio-20.html


저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by blueasa

댓글을 달아 주세요

  1. 2012.10.24 10:05 신고 Phoenix  댓글주소  수정/삭제  댓글쓰기

    참 좋은 팁이네요. 잘 보고 갑니다. VS2012에서도 잘 되는군요. VAX가 안돼서 잘 안쓰더랬는데..이제부턴 이걸로 해야겠군요. 고맙습니다.

    • 2012.10.24 11:12 신고 blueasa  댓글주소  수정/삭제

      저도 VAX 때문에 VS를 쓰려고 했는데 정작 안먹히니 답답해서 찾아봤는데 어느정도 해결방법이 있길래 적용해보고 잘돼서 올려놨습니다.
      글 올린지 하루만에 도움받는 분이 생기니 즐겁네요. :)

    • 2012.10.24 13:50 신고 Phoenix  댓글주소  수정/삭제

      VS에서 디버깅하는 방법도 좀 가르쳐 주세요.
      VS가 익숙돼서 쓰기는 좋은데 디버깅을 할 수가 없네요.
      따라 나온 Mono처럼 프로세스에 연결하는 기능을 써봤는데 브레이크가 안걸리네요. Mono처럼 디버깅도 할 수 있는 방법은 없나요?
      돈을 내면서까지 UniyVS를 쓸 필요는 없을 거 같고 해서..

    • 2012.10.24 15:54 신고 blueasa  댓글주소  수정/삭제

      아쉽게도 UnityVS 외엔 저도 아직 VS에서 디버깅 가능한 방법은 못봤습니다.
      UnityVS 크랙이나 평가판을 받을 수 있으면 써보고 괜찮으면 살까 싶은데 전혀 구할수가 없네요..
      돌아다니다가 보니 다른분이 VS를 쓰시면서 디버깅용으로 MonoDevelop을 혼용하시는 분이 있었습니다.
      http://kongpill.tistory.com/entry/unity-3d-visual-studio-2010
      위 링크를 한번 보세요.
      저도 UnityVS를 안사면 위 방법대로 해야하지 않을까 싶습니다. =ㅅ=

    • 2012.10.24 16:47 신고 Phoenix  댓글주소  수정/삭제

      그렇지 않아도 지금 그렇게 쓰는 중이었는데
      정녕 그렇게밖엔 쓸 수가...ㅎ
      일일이 성의있게 답변해 주셔서 감사합니다.

    • 2012.10.24 22:41 신고 blueasa  댓글주소  수정/삭제

      아니에요. 같은 내용으로 이야기 할 수 있는건 좋은 거죠. :)
      혹시나 UnityVS 쓰시게 되면 후기 부탁 드립니다. *-_-*
      평 좋으면 사도 되는데 그닥 정보가 없으니.. 선뜻 사기 뭐하네요. ㅎㅎ

유니티3D에서 text 파일 읽고/쓰는 소스코드 몇가지를 올립니다. 
이거 잘 안되서 저는 엄청 혼났거든요. 
아래 소스들 중 골라서 사용해보세요. 

1. c#코드, FileInfo 클래스 사용하는게 특징이네요. 
파일 읽기는 부분만 있습니다. 

using System; 
using System.IO; 

public class LineReader : MonoBehaviour 

    protected FileInfo theSourceFile = null; 
    protected StreamReader reader = null; 
    protected string text = " "; // assigned to allow first line to be read below 

    void Start () { 
        theSourceFile = new FileInfo ("Test.txt"); 
        reader = theSourceFile.OpenText(); 
    } 
    
    void Update () { 
        if (text != null) { 
            text = reader.ReadLine(); 
            //Console.WriteLine(text); 
            print (text); 
        } 
    } 


******* 
2. javascript 코드, 
파일 읽고/쓰는 함수가 다 있습니다. 
읽을 때 File 클래스를 사용합니다. 

import System.IO; 
var filePath = "/Users/ResetOfDirectoryPath/testWrite.txt"; 

function Update() { 
if (Input.GetKeyDown("r")) { 
WriteFile(filePath); 

if (Input.GetKeyDown("f")) { 
ReadFile(filePath); 



function WriteFile(filepathIncludingFileName : String) 

var sw : StreamWriter = new StreamWriter(filepathIncludingFileName); 
sw.WriteLine("Line to write"); 
sw.WriteLine("Another Line"); 
sw.Flush(); 
sw.Close(); 


function ReadFile(filepathIncludingFileName : String) { 
sr = new File.OpenText(filepathIncludingFileName); 

input = ""; 
while (true) { 
input = sr.ReadLine(); 
if (input == null) { break; } 
Debug.Log("line="+input); 

sr.Close(); 


****** 
3. javascript 코드, 파일 읽기는 부분만인데 
읽을 때 StreamReader 클래스를 이용합니다. 

import System.IO; 
var fileName = "foo.txt"; 
function Start () 

    var sr = new StreamReader(Application.dataPath + "/" + fileName); 
    var fileContents = sr.ReadToEnd(); 
    sr.Close(); 
    var lines = fileContents.Split("\n"[0]); 
    for (line in lines) { 
        print (line); 
    } 


***** 
4. 기타 
이 부분은 저도 테스트를 못했습니다. 
var pathToFile = "path/to/example.txt"; 
var url = "file://" + pathToFile; 
yiel download = new WWW(url); 
text = download.data; 

**** 
여기 나온 코드들은 unity3d 포럼에 나와있는 코드들인데 개발 시에 사용하려고 복사해뒀던 것들입니다.



출처 : http://www.applclub.com/bbs/board.php?bo_table=F&wr_id=1170&sca=%B0%AD%C1%C2%2F%C6%C1

저작자 표시 비영리 동일 조건 변경 허락
신고

'Unity3D' 카테고리의 다른 글

Inspector에 다차원 배열 값 셋팅하기(for C#)  (0) 2012.10.24
Unity3D Scripting Overview  (0) 2012.10.24
text 파일 Read/Write 하는 소스 몇가지  (0) 2012.10.22
에셋 서버 Scene Merge 관련..  (0) 2012.10.19
유니티 관련  (0) 2012.10.17
Transform Custom Editor  (0) 2012.10.15
Posted by blueasa

댓글을 달아 주세요

1) 유니티 실행 아이콘 우클릭-속성-대상


2) 커맨드라인으로 '-projectPath' 추가.

    (예:"C:\Program Files (x86)\Unity\Editor\Unity.exe" -projectPath)


3) '확인' 버튼


4) 실행

저작자 표시 비영리 동일 조건 변경 허락
신고
Posted by blueasa

댓글을 달아 주세요

새벽코딩반 (2012/02/22) 삭제 채택

3.5 부터는 씬머지를 하실 수 있습니다. Edit->Project Settings-> Editor에 가셔서 Asset Serialization 부분을 Force Text로 설정해주시면 됩니다.


라고 써있네요.


수정해봐야 겠습니다.


참조 : http://sizx.blog.me/100155808518


출처 : http://korea.unity3d.com/board/?db=qnalist&no=264&mari_mode=view@view

저작자 표시 비영리 동일 조건 변경 허락
신고

'Unity3D' 카테고리의 다른 글

Unity3D Scripting Overview  (0) 2012.10.24
text 파일 Read/Write 하는 소스 몇가지  (0) 2012.10.22
에셋 서버 Scene Merge 관련..  (0) 2012.10.19
유니티 관련  (0) 2012.10.17
Transform Custom Editor  (0) 2012.10.15
Gizmos로 카메라 프러스텀 보이게 하기  (0) 2012.10.15
Posted by blueasa

댓글을 달아 주세요