'Unity Engine'에 해당되는 글 11건

  1. 2020.01.29 C# Unity - Serializable Dictionary 1
  2. 2019.06.20 [NGUI] Infinite ScrollView (AT) 1
  3. 2018.12.23 #04.C# Job System_02
  4. 2018.12.22 #04.C# Job System_01
  5. 2018.12.21 #03.JobSequenceManager
  6. 2018.12.21 NGUI #02.UIPanel
  7. 2018.12.20 #02.JobRepeatManager - 03
  8. 2018.12.20 #02.JobRepeatManager - 02
  9. 2018.12.19 #02.JobRepeatManager - 01
  10. 2018.12.18 NGUI #01.UIRoot
posted by REDFORCE 2020. 1. 29. 13:55

Serializable Dictionary

 

Unity에서 TextMeshPro로 풀링 되어있는 HUD System을 만들다가 구조를 Dictionary로 잡게 되었는데 한가지 문제가 있었다. Unity 상에서 Dictionary 같은 경우엔 시리얼라이즈를 해도 에디터 상에 노출이 안되는 문제였다.

그러나 필요에 의해 Inspector에 노출이 되었으면 하는 KeyValuePair 형태의 Dictionary 구조가 필요할 때가 지금처럼 간혹 발생할 수 있는데 결국 구글링하며 찾아보다가 만들게 되었다.

 

 

 

'Unity Engine > Unity3D Engine' 카테고리의 다른 글

#04.C# Job System_02  (0) 2018.12.23
#04.C# Job System_01  (0) 2018.12.22
#03.JobSequenceManager  (0) 2018.12.21
#02.JobRepeatManager - 03  (0) 2018.12.20
#02.JobRepeatManager - 02  (0) 2018.12.20
posted by REDFORCE 2019. 6. 20. 15:59

최근 회사에서 채팅UI의 구조 개선에 대한 이슈가 발생하여 만들어두었던 채팅창을 모두 갈아엎게 되었다.

기존의 채팅 UI구조는 채팅메세지가 들어올 때마다 Instantiate ( ) 가 수행되어 말풍선 UI가 계속해서 쌓이는 구조였다.

 

물론 처음 개발 당시엔 채팅메세지가 엄청나게 쏟아지는 경우를 고려하여 말풍선이 쌓이는 갯수를 최대 200개 까지로 제한하여 그 이상 메세지가 쌓일 시엔 가장 오래 된 메세지를 삭제하고 새로 생성하는 형태로 구현했었다.

(Mobile : Android/iOS) Astrokings(아스트로킹즈)

워낙 게임이 채팅이 많이 오가는 게임이 아니라서 (개인적으론 그렇게 생각한다..) 딱히 위 설계대로 구현한 당시엔 큰 문제나 이슈는 없었다.


그러나 오랫동안 접속상태를 유지한 채, 채팅창을 한번도 키지않고 있다가 새로운 메세지가 많이 쌓인 상태에서 채팅창을 킬 시 200개의 메세지를 모두 갱신하느라 하드웨어에 따라 다르지만 약 3~10초 이상의 딜레이가 걸리는 문제로 결국 인해 최적화 이슈가 발생했다.

 

이 문제를 어떻게 해결할까 하다가 결국 Infinite ScrollView의 필요성을 느끼게 되었고, 여러가지 InfiniteScrollView에 대한 Reference를 찾아보고 적용해보았지만 가장 큰 문제가 있었다.

 

구글, 스택오버플로우 등 다양한 곳에서 찾아본 Infinite ScrollView는 100% Grid 형태의 모든 스크롤 항목이 동일한 크기임을 전제로 하여 만들어져 있었다. 그러나 필자가 필요로 하는 Infinite ScrollView의 경우 채팅창의 말풍선들이 내용에 따라 가변적으로 크기가 변하는 조건이 있어서 사람들이 흔히 쓰는 방식으로는 구현할 수가 없었다.

 

결국...NGUI의 UITable 의 Reposition 기능과 더불어 ScrollView의 기능을 자동으로 수행해줄 수 있는 Infinite ScrollView

를 따로 만들게 되었다.

 

[AT] Infinite ScrollView

혹시나 필자가 만들어둔 ScrollView를 사용할 사람들을 위해 주의사항을 몇가지 작성해둔다.

 

1. 각 스크롤 되는 아이템 항목은 가변적으로 늘어나되, 가변으로 아이템의 크기가 변경되는 사항은 NGUI Anchor를 이용한다는 전제로 구현되어 있다.

2. Prefab으로 연결 시킬 Item의 크기에 따라 자동으로 내부의 Pooling이 결정 된다.

3. 여러개의 Column을 지원하지만, 1 Column 체제로 사용하는 것을 추천한다.

4. 필자는 Vertical 기능만 있으면 되서 Horizontal 은 구현하지 않았다. (Horizontal 부분은 구조만 잡혀있다)

5. SetFocus 기능을 이용하면 해당 아이템을 기준으로 Refresh 된다. (Panel 이 Spring 되는 것이 아니다)

6. Position 계산의 Pivot은 Top이 기준이다.

7. Default 설정 값은 가급적 그대로 두고 사용하길 추천한다 (One Direction, Flat, Horizontal 등. 미완성 내용이 많다)

8. Prepare Size 는 Pool에서 미리 잡아두는 예비 Item 사이즈이다. (2~4정도면 적절, Column 갯수가 늘어난다면 문제가 발생할 수 있다)

 

결국 Pooling 형태의 Infinite ScrollView로 변경한 결과, 오래 된 내용이 있을지라도 Instantiate ( ) 를 하지 않고 현재 보여질 내용만 갱신하게 되어 속도와 메모리 측면에서 상당히 좋은 결과를 얻을 수 있었다.

 

다만 단점은 갱신 되는 Item의 크기와 예비 갯수에 따라 스크롤이 매끄럽게 계속해서 이어가다가 끊기는 현상이 다분히 발생할 수 있다.

 

 

아래는 원본 Infinite ScrollView Class Code이다.

 

'Unity Engine > NGUI' 카테고리의 다른 글

NGUI #02.UIPanel  (0) 2018.12.21
NGUI #01.UIRoot  (0) 2018.12.18
posted by REDFORCE 2018. 12. 23. 00:46

본 글은 Unity 2018.2.1f1 을 기반으로 작성되었습니다.


관련 글 링크 목록 

 #04.C# Job System_01

 #04.C# Job System_02



Unity C# Job System 메뉴얼

https://docs.unity3d.com/kr/2018.1/Manual/JobSystem.html


---------------------



01번 글에 이어서, 사실 Job System을 이해하기전에 개념적으로 알아두어야 할 내용이 하나 더 있습니다.


혹시나 C# Job Sytsem 메뉴얼을 먼저 전부 읽어보았다면 본 내용은 스킵하셔도 됩니다.



멀티 쓰레딩 이라는 것을 공부해보셨다면 아마 "경쟁" 이라는 게 무슨 뜻인지 알 것입니다.

간단히 설명하면 


어떤 int count; 라는 변수를 점유(접근 및 사용)하기 위해 

어떤 스레드가 count = 10; 이라는 작업을 하려고 하지만. 

동 시간대에 다른 스레드가 count = 99; 라고 작업을 하기 위해 


두 스레드간에 자원을 선점하기 위해 레이스에 빠져드는 것을 "경쟁" 이라고 합니다.


Job System은 이런 메모리 선점에 대해서 세이프한 공유 메모리 유형을 제공합니다.

그것이 바로 NativeContainer 입니다.


NativeContainer를 사용하면 이런 제한점을 극복 할 수 있습니다.


NativeContainer 란 무엇입니까?

 - NativeContainer는 네이티브 메모리에 비교적 안전한 C# Wrapper 를 제공하여 관리되는
값 형식 입니다.

 - NavtiveContainer를 사용하면 Job을 통해 사본으로 작업하는 대신 주 스레드와 공유 된 데이터에 접근 할 수 있습니다.


기본 NativeContainer는 NativeArray<T> 가 있습니다.


그러나 Unity - ECS(Entity Component System) 에서는 아래 4가지의 NativeContainer를 제공합니다.

(주의! Unity Package - Unity.Collections를 필요로 합니다.)


  • NativeList - List<T> 와 유사합니다.
  • NativeHashMap - Dictinonary<K, T>와 유사합니다.
  • NativeMultiHashMap - Dictinonary<K, T>와 유사하지만 동일한 Key를 등록할 수 있습니다.
  • NativeQueue - Queue<T>와 유사합니다. (FIFO 선입선출 구조)


자세한 Unity - ECS에 대해서는 추후 ECS 편에서 다루도록 하겠습니다.



개념적인 이론 글은 여기까지 적고, 다음 글에서 이제 실제 Job System을 사용하는 예제를 적어보도록 하겠습니다.


'Unity Engine > Unity3D Engine' 카테고리의 다른 글

C# Unity - Serializable Dictionary  (1) 2020.01.29
#04.C# Job System_01  (0) 2018.12.22
#03.JobSequenceManager  (0) 2018.12.21
#02.JobRepeatManager - 03  (0) 2018.12.20
#02.JobRepeatManager - 02  (0) 2018.12.20
posted by REDFORCE 2018. 12. 22. 22:37

이번에는 최근 삽질과 연구 끝에 마무리한 C# Job System과 ECS에 대해서 적어보려 합니다.


아직 한글로 된 블로그 중에는 C# JobSystem과 ECS에 대해서 제대로 정리하거나 적어둔

블로그를 못 본것 같은데, 좋은 자료가 있다면 저도 알려주세요.


----------------------


본 글은 Unity 2018.2.1f1 을 기반으로 작성되었습니다.


관련 글 링크 목록

 #04. C# Job System_01

 #04. C# Job System_02


----------------------


먼저 C# Job System을 왜 만들었고, 어떻게 만들어졌으며 어떻게 쓰는지

차례대로 설명하도록 하겠습니다.


Unity C# Job System 메뉴얼

- https://docs.unity3d.com/kr/2018.1/Manual/JobSystem.html



1. C# Job System 


(개념적인 설명은 적기 귀찮으므로 메뉴얼 문서를 그대로 가져왔습니다)



잡 시스템이란?

잡 시스템(job system)은 스레드를 대신하여 을 만들어 멀티스레드 코드를 관리합니다.

잡 시스템은 여러 코어에 걸쳐 워커 스레드 그룹을 관리합니다. 컨텍스트가 바뀌지 않도록 하기 위해 일반적으로 CPU 논리 코어당 하나의 워커 스레드가 있지만, 시스템이 운영체제나 기타 전용 애플리케이션에서 사용할 코어 몇 개를 예약해 둘 수 있습니다.

잡 시스템은 잡 대기열에 잡을 배치하여 실행합니다. 잡 시스템의 워커 스레드는 잡 대기열에서 항목을 가져와 실행합니다. 잡 시스템은 종속성을 관리하고 작업이 올바른 순서대로 실행되도록 합니다.

잡이란?

잡(job)은 특정한 단일 작업을수행하는 작은 작업 단위입니다. 잡은 메서드 호출의 동작과 유사한 방식으로 파라마터를 수신하고 데이터 작업을 수행합니다. 잡은 독립적일 수도 있고, 다른 잡이 먼저 완료된 후에 실행되어야 할 수도 있습니다.

잡 종속성이란?

게임 개발에 필요한 시스템처럼 복잡한 시스템에서는 각 잡이 독립적일 가능성이 낮습니다. 이 경우 잡은 일반적으로 다음 잡에 사용할 데이터를 준비하는데, 이를 위해 종속성을 인식하고 지원합니다. jobA jobB에 종속된 경우 잡 시스템은 jobB가 완료될 때까지 jobA가 실행되지 않도록 합니다.


C# 잡 시스템의 안전 시스템

경쟁 상태

멀티스레드 코드를 작성할 때는 항상 경쟁 상태가 발생할 위험이 있습니다. 경쟁 상태는 통제할 수 없는 다른 프로세스의 타이밍에 따라 작업의 결과가 달라지는 경우에 발생합니다.

경쟁 상태가 반드시 버그는 아니지만, 비결정론적인 동작의 원인이 됩니다. 경쟁 상태로 인해 버그가 발생한 경우, 타이밍에 따라 원인이 달라지기 때문에 특수한 경우를 제외하고는 문제를 재현할 수 없어 근본적인 원인을 식별하기가 어려울 수 있습니다. 이러한 문제를 디버깅하면 중단점과 로깅에 따라 개별 스레드의 타이밍이 바뀌므로 문제가 사라질 수 있습니다. 경쟁 상태는 멀티스레드 코드 작성 시 가장 중대한 문제를 유발할 수 있습니다.

안전 시스템

멀티스레드 코드를 더 쉽게 작성할 수 있도록 Unity C# 잡 시스템은 모든 잠재적인 경쟁 상태를 감지하고 그로 인해 발생할 수 있는 버그를 차단합니다.

예를 들어, C# 잡 시스템에서 메인 스레드에 있는 코드의 데이터에 대한 레퍼런스를 잡으로 전송하는 경우, 잡이 데이터를 쓰는 동시에 메인 스레드가 데이터를 읽는지 시스템이 확인할 수 없습니다. 이 경우 경쟁 상태가 발생합니다.

C# 잡 시스템은 각 잡에 메인 스레드의 데이터에 대한 레퍼런스를 보내지 않고 작업이 필요한 데이터를 보내 이 문제를 해결합니다. 이 복사본은 데이터를 격리시키므로 경쟁 상태가 발생하지 않습니다.

C# 잡 시스템이 데이터를 복사하는 방법으로 인해 잡은 blittable 데이터 타입에만 액세스할 수 있습니다. 이 데이터 타입을 관리되는 코드와 네이티브 코드 간에 전달하는 경우 변환할 필요가 없습니다.

C# 잡 시스템은 memcpy를 사용하여 blittable 타입을 복사하고 Unity의 관리되는 파트와 네이티브 파트 간에 데이터를 전송할 수 있습니다. 시스템은 잡을 예약할 때 memcpy를 사용하여 데이터를 네이티브 메모리에 저장하고, 잡을 실행할 때 이 복사본에 액세스할 수 있는 권한을 관리되는 파트에 할당합니다. 자세한 내용은 잡 예약을 참조하십시오.

'Unity Engine > Unity3D Engine' 카테고리의 다른 글

C# Unity - Serializable Dictionary  (1) 2020.01.29
#04.C# Job System_02  (0) 2018.12.23
#03.JobSequenceManager  (0) 2018.12.21
#02.JobRepeatManager - 03  (0) 2018.12.20
#02.JobRepeatManager - 02  (0) 2018.12.20
posted by REDFORCE 2018. 12. 21. 11:20

이번에 적을 글은 전편인 JobRepeatManager 에 이어서 JobSequenceManager 입니다.

(대체 얼마나 할일없으면 나 자신은 이런걸 만드는거니...코딩 덕후 같으니)


다음과 같은 이유나 상황일 때 사용하기 위해 만들었습니다.


 > 순차적인 함수 호출이 필요하다

 > 서로 다른 인스턴스에서의 함수 호출로 인해 순차적 호출 시점 제어가 너무 귀찮다.

 > 각 함수들을 Coroutine 으로 순차적 실행을 하고 싶을 때가 있다.


그래서 만든 것이 JobSequenceManager 입니다.



JobSequenceManager는 다음과 같은 함수와 파라미터를 가지고 있습니다.


 멤버 변수

 설명


 public Queue<Tuple<MethodInfo, object, object[]>> _sequenceJobs


 등록되는 Job을 담고 있는 컨테이너 입니다.



 메소드

 설명 

 public void AddJob<T>(string methodName, params object[] parameter) 


 - 수행시킬 Job을 등록하는 함수입니다. 

 - AddJob<T>에서 <T>에는 본인이 등록 시킬 클래스 타입을 넣어주세요.

 - methodName에는 Type T에 구현되어있는 함수 이름을 넣어주세요.

 - 해당 함수에 파라미터를 전달 하고 싶은게 있을 시엔 parameter에 전달하면 됩니다.


 public void OnExecuteSequenceJob()


 - 등록 된 Job을 수행시킵니다.
 - 모든 Job을 일괄 순차적으로 수행시킵니다.


 public void OnExecuteSequenceCoroutine()


 - 등록 된 Job을 Corotuine 형태로 수행시킵니다.

 - 모든 Job을 순차적으로 수행시킵니다.

 - JobSequenceManager의 CoExecuteJobSequence( )
에서 한 Job마다 수행이 끝날 때마다 yield return null 이 불려집니다.


 protected IEnumerator CoExecuteJobSequence()


 - 등록 된 Job을 IEnumerator(Corotuine) 형태로 수행시키는 함수입니다.

 



사용 방법은 간단하게 아래 샘플로 적어두겠습니다.



'Unity Engine > Unity3D Engine' 카테고리의 다른 글

#04.C# Job System_02  (0) 2018.12.23
#04.C# Job System_01  (0) 2018.12.22
#02.JobRepeatManager - 03  (0) 2018.12.20
#02.JobRepeatManager - 02  (0) 2018.12.20
#02.JobRepeatManager - 01  (0) 2018.12.19
posted by REDFORCE 2018. 12. 21. 00:53

Unity 2018.2.1f1 - NGUI 3.12.0 을 기반으로 작성 되었습니다.

-----------------------

이번에 작성할 내용은 UIRoot에 이어서 UIPanel입니다.




UIPanel 은 NGUI의 UIWidget들이 담겨져서 보여지게 되는 일련의 가장 뒷편에 깔리는 도화지 같은 개념이라 보시면 됩니다.


 

 설명

 Alpha 


 해당 패널의 Hierarcy 구조상 하위에 붙은 모든 Widget들의 Alpha에 영향을 미치는 값 입니다. 하위에 붙어있는 Panel에는 영향을 주지 않습니다.

 

 Depth


 만약 UIPanel이 2개 이상 UIRoot에 자식으로 활성화되어 있을 시

먼저 보여지게 될 순서를 의미합니다.


 Clipping


 특정 영역을 설정하고 그 영역 밖에 있는 부분을 렌더링하지 않는 것을 의미합니다.


 > None : 클리핑을 하지 않습니다.

 > Texture Mask : 등록 된 Texture 영역을 제외하고 클리핑 합니다.

 > Soft Clipping : 패널 영역을 설정하고 클리핑 합니다. Softness 값을 주어 외곽부분을 부드럽게 클리핑 되도록 합니다.

 > Constrained But Dont Clip : 패널 영역을 지정하지만 클리핑은 하지 않습니다.


 Advanced Options

  

 Render Q :
  - Rendering 되어질 때의 순서를 정할 수 있습니다.

  - UI에 Particle System 을 사용하는 상황 같은 Render Queue 경쟁이 벌어질 수 있는 환경에서 설정하는 값 입니다. 

 Sort Order :
  - 같은 DEpth에서 렌더링 순서를 결정합니다.
  - Unity Sprite의 OrderInLayer와 유사합니다.
  - 높을 수록 위에 출력됩니다.

 Normal : 체크하면 패널이 Light에 영향을 받습니다.

 Cull : ScrollView 패널에서 성능 향상을 위해 사용되어지는 옵션입니다. 패널이 드래그(Drag) 되어 Widget이 패널 영역을 벗어날 시 자식위젯들을 Rendering 하지 않습니다.

 Visible : 패널 내부의 Widget들이 스크린 안에 있는지 계산하여 Rendering 여부를 결정하는 데, 이 계산을 건너띄게 만듭니다.
UIWidget 들이 패널을 벗어날 일이 없을 경우 체크하게 되면 성능이 향상 됩니다.

 Padding : 패널의 외각 부분을 부드럽게 만듭니다.
 (클리핑 옵션이 Softness 인 상태에서는 의미는 없는 듯)

 Static : 패널 내의 위젯들이 이동이 없는 경우 Static으로 설정하면 유니티가 Position, Rotation, Scale 값을 계산하지 않아 성능이 향상 됩니다.


 Anchors


  UIPanel 또는 UIWidget 에서 특정 위치를 기준으로 좌표가 잡히도록 설정하는 값 입니다.


 Show Draw Calls

 Draw Call Tool 창을 불러옵니다.


'Unity Engine > NGUI' 카테고리의 다른 글

[NGUI] Infinite ScrollView (AT)  (1) 2019.06.20
NGUI #01.UIRoot  (0) 2018.12.18
posted by REDFORCE 2018. 12. 20. 02:56

#02.JobRepeatManager - 01

#02.JobRepeatManager - 02


이번 글은 마지막으로 JobRepeatManager 에 대한 간단한 구조 설명과

사용 예제로 마무리 하겠습니다.


다소 글이 길어질 수 있습니다. 만약 액기스만 뽑아먹을래! 하는 분은 샘플예제만 보셔도 됩니다.

해서...샘플 예제를 먼저 적어두겠습니다.



----------------------------------------


2. JobRepeatManager


JobRepeatManager 는 Singleton Pattern으로 인스턴스가 생성 됩니다.


싱글톤 패턴으로 생성 되어있는 인스턴스 이므로 만약 JobRepeatManager를 사용하실 분들은 간단히 static으로 인스턴스를 넣어주세요.


JobRepeatManager에는 다음과 같은 Public 함수와 멤버변수가 있습니다.


 멤버변수 및 애트리뷰트

 설명

 public List<JobRepeatBase> JobList


 get; _jobList


 public float MinDelayTime


 get;set; => m_MinDelayTime 



 메소드 이름

 설명 


 public bool AddDelegateJob(string key, 

 JobTodo toDo, 

 float delay = 1.0f,

 int repeatCount = 0,

 object[] parameter = null,             JobEndAction endActionWhenDrop = null,

 JobToDoCondition toDoCondition = null, 

 JobAutoDropCondition autoDropCondition = null, 

 bool isImmediately = true)


 - JobRepeatBase를 생성 및 등록하는 함수

 - 일반적인 Delegate 형태의 Job을 등록할 수 있습니다.


 public AddCoroutineJob (string key, 

 IEnumerator coroutineJobTodo, 

 float delay = 1.0f, 

 int repeatCount = 0,

 object[] param = null,

 JobToDoCondition toDoCondition = null, 

 JobAutoDropCondition autoDropCondition = null,

 bool isImmediately = true)


 - JobRepeatBase를 생성 및 등록하는 함수

 - Coroutine 형태의 Job을 생성합니다.

 - Todo를 추가로 Job에 등록하고 싶으실 땐 AddFunctionChain을 호출하여 사용합니다. 

 public bool JobStart (string key)


 - 특정 등록되어진 Job을 key 값으로 찾아서 Job을 Execute 시킵니다.

 - 정상적인 실행이 성공되면 true를 리턴합니다. 실패 시 return false


 public bool RemoveJob(string key)


 - 특정 등록되어진 Job을 Key 값으로 찾아서 드랍(Drop)시킵니다. 정상적으로 드랍에 성공할 시 true를 리턴합니다.


 public int JobDropAll ( )


 - 등록되어진 모든 Job을 Drop 시킵니다.

 - 드랍시킨 Job 갯수를 리턴합니다.


 public bool ChangeJobDelay (string key, float newDelay)


 - 특정 등록되어진 Job을 Key 값으로 찾은 뒤 해당 Job의 DelayTime을 변경합니다.

 - 만약 수행중(Job Started)인 Job 이었다면 다음 수행부터 Delay가 변경됩니다.

 - 변경에 선공하면 true 를 리턴합니다.


 public bool ChangeJobRepeatCount (string key, int repeatCount)


 - 특정 등록되어진 Job을 Key 값으로 찾은 뒤 해당 Job의 RepeatCount를 변경합니다.

 - 만약 수행중(Job Started)인 Job 이었다면 다음 수행부터 RepeatCount가 변경됩니다.

 - 변경에 성공하면 true를 리턴합니다.



 public bool AddFunctionChain(string key,

 JobTodo todo = null, 

 JobTodoCondition TodoCheck = null,

 JobAutoDropCondition autodropCondition = null, bool isExecuteImmediately = true)


 - key값으로 찾은 Job에 등록되어진 Delegate를 추가로 등록하는 함수입니다.


 public bool RemoveFunctionChain(string key, JobTodo todo = null,   JobTodoCondition todoCheck = null,

 JobAutoDropCondition autodropCondition = null, bool isExecuteImmediately = true)


 -Key 값으로 찾은 Job에 등록되어진 Delegate를 삭제하는 함수입니다.

 public JobRepeatBase GetJobBase(string key)

 - Key 값으로 JobRepeatBase 정보를 찾는 함수입니다.

 private IEnumerator CoAutoDropWorkers()


 - Drop 상태가 된 Job을 삭제시키는 Coroutine 입니다.

 - JobRepeatManager 의 instance가 Start 될 때 실행 됩니다.

 - Drop 상태 체크는 

private WaitForSeconds dropManagingDelay 마다 수행됩니다.

 

 private IEnumerator CoJobHandle(string key)


 - JobRepeatManager에 등록되어진 Job들을 동작시키는 Corotuine 입니다.

 - JobRepeatBase에 담겨져있는 Job.state 값에 따라 Job을 동작시킵니다.



-------------------------------



'Unity Engine > Unity3D Engine' 카테고리의 다른 글

#04.C# Job System_01  (0) 2018.12.22
#03.JobSequenceManager  (0) 2018.12.21
#02.JobRepeatManager - 02  (0) 2018.12.20
#02.JobRepeatManager - 01  (0) 2018.12.19
#01.A에서 B로 일정 시간동안 움직이기  (0) 2018.12.18
posted by REDFORCE 2018. 12. 20. 02:25

#02.JobRepeatManager - 01


-----------------------------
01번 글에 이어서 적어갑니다.

여기서는 먼저 JobRepeatManager에서 Base 오브젝트 역할을 담당하는 JobRepeatBase에 대해서 설명하겠습니다.


1. class JobRepeatBase

JobRepeatBase는 Monobehaviour를 상속한 GameObject 로써 JobRepeatManager에서 생성 및 관리 되어지는 클래스 입니다.


JobRepeatBase 는 다음과 같은 멤버변수를 갖고 있습니다.

 형태 및 이름

 설명

 public string key


 - Job이 생성 될 때 등록되어질 이름(Key) 값 입니다.

 - GameObject로 생성 될 때의 name과 동일합니다.


 public float repeatDelay


 - 반복 형태의  Job일 경우 Delay Time(Second)입니다. 


 public int repeatCount


 - 반복 형태의 Job 일 경우 반복할 횟수 입니다.

 - 이 값이 0 이면 무한 반복합니다.


 public int executeCount


 - 현재 까지 수행한 반복 횟수 값 입니다.

 - executeCount 가 repeatCount 보다 커지면 자동으로 Job이 드랍됩니다. (repeatCount 가 0 이면 무한 반복합니다)


 public IEnumerator jobCoroutine


 - Job을 수행함에 있어 Delegate 형태뿐만 아니라 Coroutine으로 돌리고 싶은 경우 이용할 수 있는 IEneumerator 입니다.

 - JobTodo 보다 우선시되어 수행됩니다.

 

 - 아직 연구중인 Coroutine 구조 입니다.
  (사용하지 않기를 추천)

 

 

 public JobTodo


 - 원형)
 public delegate void JobTodo ( params object[] param)


 - 수행할 내용이 들어갈 수 있는 Todo delegate입니다.

 - Job을 반복적으로 수행할 때의 수행시킬 내용을 여기에 넣으면 됩니다.


 public JobEndAction


 - 원형)

 public delegate void JobEndAction( params object[] param)


 - 모든 반복횟수를 마무리 한 후 Job이 Drop되기 직전 호출되는 JobEndAction Delegate 입니다.

 - Drop 되기전 한 번 호출됩니다.

 - null 일 경우 아무것도 하지 않습니다.


 public JobTodoCondition


 - 원형)

 public delegate bool JobTodoCondition( params object[] param)


 - 반복 수행함에 있어 JobTodo를 실행하기 전 수행(Execute)할 것인지 말 것인지 조건을 넣기 위한 Delegate 입니다.

 - JobTodoCondition에서 return true 일 경우 JobTodo를 수행합니다. return false 이면 JobTodo를 호출하지 않습니다.

 - null 일 경우 무시됩니다.


 public JobAutoDropCondition

 - 원형)
 public delegate bool JobAutoDropCondition( params object[] param)


 -  Job이 반복 수행되어지다가 자동으로 중단되기 위한 조건을 넣을 수 있는 Delegate 입니다.

 - JobAutoDropCondition에서 return true 일 경우 Job이 드랍(Drop) 됩니다. return false 일 경우 무시합니다.

 - null 일 경우 무시됩니다.


 public JOB_STATE


 - 현재 Job의 상태를 표현하는 값 입니다.

 -  public enum JOB_STATE 

  > NONE : 초기화 용

  > JOB_EMPTY : Job이 없음

  > JOB_STANDBY : Job이 수행 대기중

  > JOB_WORKING : Job이 Todo를 수행중

  > JOB_WAITING : Job이 TodoCondition 으로 인해 대기중

  > JOB_DROP : Job이 Drop되어질 예정


 public IEnumerator worker


 -  worker는 실제 Job으로 등록된 일을 수행하는 Corotuine 개체 입니다.

 - 자동으로 JobRepeatManager를 통해 관리되어 지므로 건들지 않는게 좋습니다.

 public object[] parameter


 - Todo, EndAction, TodoCondition, AutoDropCondition Delegate의 param에 전달되어지는 Parameter 입니다.



위와 같이 조금 많은 멤버변수들과 Delegate들이 있는데 부담갖지마시고 사용 방법은 간단합니다~

JobRepeatBase가 어떻게 이용되어 지는지는 03번 글에서 이어서 적도록 하겠습니다.


'Unity Engine > Unity3D Engine' 카테고리의 다른 글

#04.C# Job System_01  (0) 2018.12.22
#03.JobSequenceManager  (0) 2018.12.21
#02.JobRepeatManager - 03  (0) 2018.12.20
#02.JobRepeatManager - 01  (0) 2018.12.19
#01.A에서 B로 일정 시간동안 움직이기  (0) 2018.12.18
posted by REDFORCE 2018. 12. 19. 01:45

#02.JobRepeatManager - 01


이번 글에 작성할 내용은 개인적으로 유니티를 사용하면서 이런 스크립트가 있으면 편할 것 같은데? 라는 생각에 만들어 본 스크립트이다.


그 이름은 Job Repeat Manager !!!!!!!!!!!


개인적으로 만들어놓고 그래서 요놈이 효율적일까? 괜찮은가? 안전한가? 

라는 질문을 수 차례했으나 답은...나도 모르겠당...ㅎㅎ


그래도 올려두면 누군가는 쓰지 않을까? 라는 생각에 피드백도 받아볼 겸 적는다.

-------------------------------


JobRepeatManager는 글쓴이가 심심해서 만들어 본 유틸리티 성향의(?) 스크립트 입니다.

처음에 만들게 된 이유는 다음의 예로 들어보겠습니다.


목적 : 어떤 함수의 내용을 반복적으로 수행하게 하고 싶다
 예) public void MyFunction() { ... } 을 50 번만 2.0초 간격으로 수행하고 싶다.


  + 그러나 public bool isExecute;  라는 변수가 true 일때만 하고 싶다.

  + 만약 public bool isDrop; 이라는 변수가 true 면은 중간에 멈추고 싶다.

  + Invoke나 Coroutine을 쓸 수는 없는 상황이다.

  + 수행되고 있는 펑션의 상태를 Visual로 보고싶다.


위와 같은 상황에서...이걸 어떻게 해결 해야할까...라는 고민중에

결국 다음과 같은 조건을 충족하도록 만들어본 유틸리티 코드입니다.


 조 건 

  1. Update() 를 쓰고 싶지는 않다.
  2. 어떤 내용(To do)을 n번 실행하게 하고 싶다.
  3. 수행되는 내용을 GameObject 로 관리하고 싶다.
  4. 람다(Lambda) 또는 Delegate를 이용한 Event 형태의 Job을 만들어서 관리하고 싶다.


결과적으로 만든 JobRepeatManager 는 아래의 2가지 클래스 파일로 구성 되어 있습니다.


본문에서는 Gist 코드만 남기고 설명은 다음글로 넘기겠습니다.


1) JobRepeatBase.cs



2) JobRepeatManager.cs




'Unity Engine > Unity3D Engine' 카테고리의 다른 글

#04.C# Job System_01  (0) 2018.12.22
#03.JobSequenceManager  (0) 2018.12.21
#02.JobRepeatManager - 03  (0) 2018.12.20
#02.JobRepeatManager - 02  (0) 2018.12.20
#01.A에서 B로 일정 시간동안 움직이기  (0) 2018.12.18
posted by REDFORCE 2018. 12. 18. 01:49

Unity 2018.2.1f1 - NGUI 3.12.0 을 기반으로 작성 되었습니다.


---------------------------


NGUI는 Unity에서 UI를 제작하는데 많이 사용되고 있는 UI Plugin이다.


Unity(Unity GUI)가 과거(대략 유니티3.0 시절) 너무나 구닥다리 거지깽깽이 같은 기능성을 제공하는 바람에 Next-Gen UI Kit 이라고해서 Tasharen Entertainment에서 만들었다.


이 글을 작성하는 시점인 현재는 NGUI 개발자가 유니티에 스카웃되어 UGUI를 개발하고 있다고 알고 있다. 덕분에 UGUI가 옛날에 비하여 상당히 편해지고 좋아졌으나 아직까진 한국에서는 NGUI의 비중이 40% 이상인 것으로 알고 있다.


과거 NGUI가 흥하던 시절에는 NGUI 사용량이 UGUI에 비해 8~90%에 육박하였다.

역사적인 서론은 여기까지하고...


이 글을 적는 목적은 구글에서 NGUI에 대해서 검색할 시 흔히 볼 수 있는 글들이 너무나 오래 된 글들이 많아서 최신 버전을 사용하는 사람들에게는 생소하거나 동작되지 않거나 삭제되거나 변경 된 사항들이 자주 등장하다보니 삽질을 하는 일이 많아서 작성하게 되었다.


(사실 본인이 제일 삽질하는 바람에 답답해서 적게되었다)


---------------------------


#1. UIRoot


NGUI가 Project에 포함되어 있다면 위와 같이 상단 Toolbar에 "NGUI" 가 보입니다.



상단 툴바에서는 

 - Selection, Create, Attach, Tween 등 다양한 기능들이 들어있습니다.

각 항목을 모두 설명하는 것은 내용이 너무 많으므로 차근차근 사용해가면서 설명하겠습니다.



먼저 NGUI가 작동하려면 UIRootUICamera가 필요합니다.


간단하게 먼저 비어있는 Scene에서 NGUI > Create > Texture를 눌러보겠습니다.



위 사진처럼 Texture를 누르면 2번 항목과 같이 UIRoot와 Camera 그리고 Create에서 Texture를 했으므로 UITexture 컴포넌트가 붙은 "Texture" 이름을 가진 GameObject가 생성됩니다.



생성 된 UIRoot 를 선택해서 Inspector 창에 보여지는 정보를 살펴보면 다음과 같이 나옵니다.



UIRoot - 

 UIRoot 컴포넌트는 UIWidget을 상속받은 컴포넌트 및 오브젝트들의 최상단 패널로써,

해상도 또는 크기를 조절할 수 있는 스케일링 역할을 담당합니다.


UIRoot에는 다음과 같은 파라미터가 있습니다.


 파라미터

 설명

 Scaling Style

 1) Flexible : 화면 해상도에 관계 없이 UI가 픽셀 단위에서 언제나 같은 크기를 유지함. 실제 해상도에 따라 보여지는 크기가 작아지거나 커질 수 있음


 2) Constrained : UI가 화면에서 항상 같은 비율로 보이도록 스케일링 합니다. UI의 오리지날 픽셀 단위의 크기가 비율에 맞춰져 변동될 수 있음


 3) ConstrainedOnMobiles : 모바일 플랫폼에서는 Constrained 방식을 사용, 기타 플랫폼에서는 Flexible 방식을 사용합니다.


 Minimum Height

 

Flexible 방식에서 화면의 최소 높이 값을 지정합니다. 화면 높이가 설정한 값보다 작아지면 UI 크기를 조정합니다.


 Maximum Height

 

Flexible 방식에서 화면의 최대 높이를 지정합니다. 화면 높이가 설정한 값보다 커지면 UI 크기를 조정합니다.



UIRoot를 설정함에 있어 가장 중요한 점은 본인이 만드는 프로젝트의 기본 해상도를 어떻게 잡는지가 중요합니다.


16:9 비율을 쓸 것인가 4:3 비율을 쓸 것인가

1920x1080해상도를 기준으로 잡을 것인가 1280x720 해상도를 기준으로 잡을 것인가

등등, 모바일 플랫폼이라면 안드로이드 기기 별 해상도 차이가 심하기 때문에 고민하게 됩니다.


모바일 플랫폼에서는 이에 대응하기 위해 보통 ConstrainedOnMobiles 로 설정합니다.


ConstrainedOnMobiles로 설정하면 다음과 같이 Content Width, Content Height로 기준 해상도를 설정할 수 있습니다.



1) Content Width/Height 둘중 하나만 Fit 활성화 : 체크 된 항목의 비율을 유지하여 스케일링 됩니다.


2) Width/Height Fit 모두 비활성화 : 기기 해상도에 맞추어 UI가 늘어나지만 Camera에 모든 UI가 들어오지 않을 수 있습니다.


3) Width/Height Fit 모두 활성화 : 강제로 UI 항목들이 스케일링 되어 항상 화면에 보여지게 됩니다.


Fit를 둘다 체크할 시 UI 전체 화면이 스케일링 되어 UICamera에 보여질 수 있으나

기기 해상도 차이로 인해 발생하는 공백 부분은 메인카메라에 설정된 Background 값으로 채워집니다.


현재 회사에서 개발중인 게임(모바일)의 경우 


ConstrainedOnMobile 

 > Content Width(1280) Fit(Disable)

 > Content Height (720) Fit(Enable)


인 상태에서 NGUI의 앵커를 이용하여 해상도를 대응하고 있습니다.


모바일 플랫폼에서 그래서 UIRoot를 어떻게 설정하고해라 라는 정답은 없습니다만 최근 AppStore나 GoogleStore에서 요구하는 정책 사항을 고려해볼 때 위와같이 설정하여 앵커로 해상도를 대응하는 방식으로 가야하지 않을까 생각합니다.


(AppStore의 경우 Letter Camera를 사용하면 안됨. 2018년 기준)

좀 더 편한 방법이 있다면 저도 알려주세요.


UIPanel 에 대해서는 다음글에서 다루고 있습니다


RigidBody - 

 마지막으로 UIRoot에는 RigidBody Component가 붙습니다. 만약 RigidBody가 안 붙어 있다면 NGUI의 Widget들의 Event를 동작시킬 수 없습니다.


버튼, 스크롤, 스위치, 패널 등 Widget에서의 Click, Touch, Press, Drag 등의 Event를 검출하기 위해 붙어 있습니다.

'Unity Engine > NGUI' 카테고리의 다른 글

[NGUI] Infinite ScrollView (AT)  (1) 2019.06.20
NGUI #02.UIPanel  (0) 2018.12.21