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

카테고리

분류 전체보기 (2844)
Unity3D (891)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (188)
협업 (64)
3DS Max (3)
Game (12)
Utility (141)
Etc (99)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (52)
Android (16)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

컬링(Culling)

  • 최종 화면에 영향을 미치지 않는 물체를 파악하고 이를 렌더링 대상에서 제외시켜 필요한 물체만 그리는 기법
  • 프러스텀 컬림(Frustum Culling)
    • 가장 기본적이면서도 효과가 좋은 방법
    • 카메라 영역내의 공간 정보만 살려두고 영역 외부에 설정된 정보는 모두 버림
    • 카메라에 프로젝트에 설정된 레이어별로 차단 거리(Per-Layer Cull Distances)를 지정하면 이 값을 사용해 레이어에 속한 게임 오브젝트들을 컬링함
  • 오클루젼 컬링(Occlusion Culling)
    • 기존의 절두체를 이용한 컬링 기법의 한계를 보완하고 효율적으로 공간 정보를 관리해 빠르게 렌더링을 수행할 수 있게 도와주는 기법
    • Unity의 Windows => Occlusion Culling 메뉴를 통해 설정
    • 오클루젼 컬링 제작방법
      1. 오클루젼 영역 설정
      2. 오클루젼 컬링 데이터 제작
      3. 최종 결과 시뮬레이션
    • 오클루젼 포털(Occlusion Portal)
      • 오클루젼 영역을 스크립트로 조절하는 기능

드로우 콜 배칭(Draw Call Batching)

  • 텍스쳐 아틀라스(Texture Atlas)를 사용하여 콜수를 줄임
  • 성질이 동일한 물체들을 하나의 메시와 재질을 사용하게 통합
    • 여러 게임 오브젝트의 메시를 하나의 메시로 통합해주는 CombineChildren 컴포넌트를 제공
    • 최상위 게임 오브젝트에 이 컴포넌트를 사용하면 자식 오브젝트들이 갖는 메시들을 분석한 후 재질별로 메시를 통합해 재가공함
    • 컴바인 메시(Combined Mesh)를 통한 작업시 주의할 점
      • 게임 오브젝트들을 통합하면 게임 오브젝트별로 움직일 수 없게 됨
      • 관련된 빛의 계산이 통합된 모든 메시를 대상으로 수행됨
    • 메터리얼(Materials)
      • 다른 텍스쳐에 있는 두개의 독립적인 메터리얼을 하나의 큰 텍스쳐로 결합 할 수 있음(텍스처 아틀라스)
      • 일단 텍스처를 동일한 아틀라스로 묶으면 단일 메터리얼로 사용할 수 있게 됨
    • 배칭(Batching)
      • 현재 씬의 상황을 판단해 자동으로 드로우 콜을 줄이게 최적화하는 기능

      • 정적 배칭 Static Batching (Pro required)

        • Static 옵션이 설정된 게임 오브젝트에서 동일한 재질을 사용하는 물체가 있는 경우 유니티는 이들을 자동으로 하나의 메시로 통합 관리함
        • 움직이지 않는 물체에 대해 지정만 하면 자동으로 수행
      • 동적 배칭 Dynamic Batching

        • 움직이는 물체를 대상으로 동일한 재질을 사용하는 경우 이를 판단해 자동으로 메시를 통합해 드로우 콜을 줄여주는 기능
        • 총 정점의 데이터 수가 900개 미만인 메시를 지닌 게임 오브젝트만을 대상으로 수행됨
        • 메시 데이터가 위치 외에도 노멀, UV, 라이트맵 UV 등 총 3개의 속성을 갖고 있는 경우 정점의 수가 225개를 넘으면 동적 배칭이 적용되지 않음

최적의 퍼포먼스를 위한 캐릭터 모델링(Modeling Characters for Optimal Performance)

  • 싱글 스킨 메쉬 렌더러 사용

    • 각 캐릭터에 스킨 메쉬 렌더러(class-SkinnedMeshRenderer)는 하나여야 합니다.
    • Unity는 시야 컬링 및 경계 볼륨의 업데이트를 사용하여 애니메이션을 최적화하고, 이러한 최적화는 하나의 애니메이션 컴포넌트 및 하나의 스킨 메쉬 렌더러를 사용하는 경우에만 활성화됩니다.
    • 모델의 렌더링 시간은 두개의 스킨 메쉬를 사용할때 하나의 스킨 메쉬를 사용 할 때보다 대략 2배 정도 이며, 여러개의 메쉬를 사용하여 실질적인 메리트가 있는 일은 드뭅니다.
  • 가능한 메터리얼을 적게 사용

    • 각 메쉬의 메테리얼의 수를 최대한 적게 해야 합니다.
    • 여러 메테리얼을 캐릭터에서 사용하는 이유는, 다른 부분에서 다른 쉐이더가 필요한 경우 뿐 입니다(예를 들면 눈 부분은 특수 쉐이더).
    • 그러나 캐릭터에서 두 개 또는 세 개의 메테리얼로 거의 모든 케이스에 충분 합니다.
  • 가능한 한 본(Bones)를 적게 사용

    • 전형적인 데스크톱 게임의 본 계층은 15개에서 60개 사이의 본을 사용합니다.
    • 본의 수가 적을수록 퍼포먼스가 좋아집니다.
    • 30개 정도의 본으로 데스크톱 플랫폼에서는 아주 좋은 품질을 얻을 수 있고, 모바일 플랫폼에서도 비교적 좋은 품질을 얻을 수 있습니다.
    • 이상적으로는 모바일 장치에서는 30개보다 적게 하고, 데스크톱 게임에서도 30개를 크게 초과하지 않도록 합니다.
  • 폴리곤 갯수를 적게 사용

    • 폴리곤 수는 필요한 품질 및 대상 플랫폼에 의존합니다.
    • 모바일 장치는 메쉬 당 300에서 1500 폴리곤으로 좋은 결과를 얻을 수 있으며, 데스크톱 플랫폼에서의 이상적인 범위는 1500에서 4000 정도입니다.
    • 반면, 게임에 많은 캐릭터가 있을 때 메쉬 당 폴리곤의 수를 줄일 필요가 있을 것 입니다.
    • 예를 들어, Half Life 2는 캐릭터에 2500 - 5000 삼각형 수였습니다.
    • 현재 PS3와 XBox 360의 최고 랭크 게임은 보통 캐릭터에 5000에서 7000 삼각형 수입니다.
  • 포워드 및 역운동학을 분리

    • 애니메이션이 임포트 될 때, 모델의 역운동학(IK) 노드는 포워드 운동학(FK)에 베이크(baked)된 결과로 Unity는 IK 노드가 전혀 필요 없습니다.
    • 그러나 모델에 남아있으면 애니메이션에 영향을 미치지 않음에도 불구하고 CPU 오버 헤드가 발생합니다.
    • 선호에 따라 Unity 또는 모델링 도구, 어느 것이든 중복 IK 노드를 제거할 수 있습니다.
    • 이상적으로는 IK 및 FK 계층을 모델링 시에 별도로 보관하여 필요할 때 IK 노드를 쉽게 제거할 수 있도록 해야 합니다.

렌더링 통계 창(Rendering Statistics Window) 확인

  • Time per frame and FPS
    • 하나의 게임 프레임을 처리 및 렌더링하는데 걸린 시간(프레임/초)
    • 이 숫자는 프레임 업데이트 및 게임 뷰의 렌더링에 걸린 시간만 포함되는 것에 유의
    • 에디터가 씬 뷰 인스펙터의 그리기 및 에디터 전용 작업을 수행하는데 걸린 시간은 포함되지 않음
  • Batches
    • “Batching” is where the engine attempts to combine the rendering of multiple objects into a chunk of memory in order to reduce CPU overhead due to resources switching.
  • Saved by batching
    • Number of batches that was combined. To ensure good batching, you should share materials between different objects as often as possible.
    • Changing rendering states will break up batches into groups with the same states.
  • Tris and Verts 그려진 삼각형과 정점의 수. 이것은 optimizing for low-end hardware에서 중요합니다.
  • Screen 화면 크기, 안티 앨리어싱 레벨 및 메모리 사용량.
  • SetPass 렌더링 패스의 수. 각 패스에 대해서 유니티 런타임은 CPU 오버헤드를 가져올 수 있는 새로운 쉐이더를 바인딩한다.
  • Visible Skinned Meshes 렌더링된 스킨 메쉬 수
  • Animations 재생 에니메이션 수

프레임 디버거(Frame Debugger)

  • 메뉴: Window > Frame Debugger
  • 매 프레임마다 그리는 오브젝트 정보를 보여줌

쉐이더 로딩타임 최적화(Optimizing Shader Load Time)

항상 포함하는 쉐이더와 미리 로딩해야 하는 쉐이더 집합을 설정하여 쉐이더 로딩시간을 효율적으로 관리해 줌

  • 항상 포함하는 쉐이더(Always Included Shaders)

    • Project Settings > Graphics > Always Included Shaders
  • 미리 로딩하는 여러가지 쉐이더 집합(Preloaded Shader Variant Collection)

    • 쉐이더 집합 생성

    • Assets > Create > Shader Variant Collection

    • 쉐이더 집합 미리 로딩 목록에 추가

    • Project Settings > Graphics > Preloaded Shaders

텍스처 캐시(Texture Cache)

  • 모바일의 경우 GPU 제조사에서 권장하는 텍스처 포멧을 사용하면 캐시 적중률이 높아져 속도의 향상을 얻게 되며, 특히 GPU의 성능이 약한 스마트폰 기기에서는 이러한 부분의차이가 큼
  • 플랫폼별 권장 텍스처 포멧
  • 안드로이드 텍스처 압축 지원
    • http://stackoverflow.com/questions/9148795/android-opengl-texture-compression/9514396#9514396
    • ETC1 (Ericsson texture compression)
      • This format is supported by all? Android phones.
      • But, It doesn't support an alpha channel, so can only be used for opaque textures.
    • PVRTC (PowerVR texture compression)
      • Supported by devices with PowerVR GPUs (Nexus S, Kindle fire ...)
    • ATITC (ATI texture compression)
      • Used in devices with Adreno GPU from Qaulcomm (Nexus One ...)
    • S3TC (S3 texture compression)
      • This texture compression is used in the NVIDIA chipset integrated devices (Motorola Xoom ...)
  • 안드로이드 Developer에 정의된 내용
    • https://developer.android.com/guide/topics/graphics/opengl.html#textures
    • ATITC (ATC) - ATI texture compression
      • GL_AMD_compressed_ATC_texture
      • GL_ATI_texture_compression_atitc
    • PVRTC - PowerVR texture compression
      • GL_IMG_texture_compression_pvrtc
    • S3TC (DXTn/DXTC) - S3 texture compression
      • GL_OES_texture_compression_S3TC
      • GL_EXT_texture_compression_s3tc
      • GL_EXT_texture_compression_dxt1
      • GL_EXT_texture_compression_dxt3
      • GL_EXT_texture_compression_dxt5
    • 3DC - 3DC texture compression
      • GL_AMD_compressed_3DC_texture
// Texture compression supported on Android
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  Strings = gl.glGetString(GL10.GL_EXTENSIONS);
 
  if (s.contains("GL_IMG_texture_compression_pvrtc")) {
    // Use PVRTC compressed textures
  } else if (s.contains("GL_AMD_compressed_ATC_texture") ||
             s.contains("GL_ATI_texture_compression_atitc")) {
    // Use ATITC compressed textures
  } else if (s.contains("GL_OES_texture_compression_S3TC") ||
             s.contains("GL_EXT_texture_compression_s3tc")) {
    // Use DTX Textures
  } else {
    // Handle no texture compression founded
  }
}

텍스처 설정

  • Texture
  • Normal map
  • Editor GUI and Legacy GUI
  • Sprite (2D and UI)
  • Cursor
  • Reflection
  • Cookie
  • Lightmap
  • Advanced

텍스처 포멧지원 확인

텍스처 생성팁

오버드로우(Overdraw)

  • 물체가 겹쳐서 뒤에 있는 물체를 그린후에 앞에 있는 물체를 다시 그리면 겹치는 부분만큼 픽셀을 계산해서 그려야 함
  • 이렇게 특정 영역의 픽셀을 다시 그리는 것을 오버드로우라고 함
  • 불투명한 물체의 오버드로우를 줄이는 좋은 방법은 가장 큰 영역을 차지하는 물체를 먼저 그리게 설정하는 것

유용한 에셋





[출처] https://github.com/zzragida/UnityDocs/wiki/Graphics-Optimization

반응형
Posted by blueasa
, |
using UnityEngine;
 using System.Collections;
 using UnityEngine.UI; // Required when Using UI elements.
 
 public class AlphaButton : MonoBehaviour
 {
     public float AlphaThreshold = 0.1f;
 
     void Start()
     {
         this.GetComponent<Image>().alphaHitTestMinimumThreshold = AlphaThreshold;
     }
 }



[출처] https://answers.unity.com/questions/821613/unity-46-is-it-possible-for-ui-buttons-to-be-non-r.html

[참조] http://www.devkorea.co.kr/bbs/board.php?bo_table=m03_qna&wr_id=68902

반응형
Posted by blueasa
, |


[링크] http://unitytutorial.tistory.com/34

반응형
Posted by blueasa
, |


[링크] http://dongin2009.blog.me/221131218231


반응형
Posted by blueasa
, |

다음과 같이, Application.OpenURL을 이용해서

내 App을 사용하는 유저의 버그 리포트나 기타 문의사항 등을 메일로 받아보도록 할 수 있습니다.


mailto : 받는 메일 주소

subject : 보낼 메일의 제목

body : 보낼 메일의 내용



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
using UnityEngine;
 
public class EmailSender : MonoBehaviour
{
    public void OnClickEvent()
    {
        string mailto = "myapp.support@gmail.com";
        string subject = EscapeURL("버그 리포트 / 기타 문의사항");
        string body = EscapeURL
            (
             "이 곳에 내용을 작성해주세요.\n\n\n\n" +
             "________" +
             "Device Model : " + SystemInfo.deviceModel + "\n\n" +
             "Device OS : " + SystemInfo.operatingSystem + "\n\n" +
             "________"
            );
 
        Application.OpenURL("mailto:" + mailto + "?subject=" + subject + "&body=" + body);
    }
 
    private string EscapeURL(string url)
    {
        return WWW.EscapeURL(url).Replace("+""%20");
    }
 
}
 
cs



위의 OnClickEvent를 버튼에 달아서 사용하였습니다.

아래는 최근에 런칭한 로그(LOG) : 항해의 시작 이라는 게임 내 화면입니다.

이 프로젝트 런칭 준비하느라 통 블로그 활동을 못했네요 ... (핑계)





아래는, 위 사진의 '이메일 문의' 버튼을 눌렀을 때 나오는 화면입니다.

메일을 보내는 유저의 디바이스 모델과 OS도 알 수 있어서 도움이 되겠죠?








출처: http://minhyeokism.tistory.com/46 [programmer-dominic.kim]

반응형
Posted by blueasa
, |

[출처http://theeye.pe.kr/archives/2725#disqus_thread

유니티에서 사용되는 코루틴(Coroutine)은 왜 필요한가?

유니티에서 화면의 변화를 일으키기 위해서는 Update() 함수 내에서 작업을 하게 됩니다. 이 Update() 함수는 매 프레임을 그릴때마다 호출되며 60fps의경우라면 초당 60번의 Update() 함수 호출이 발생하게 됩니다. 하나의 프레임 안에서 어떤 작업을 한다면 이 Update() 함수에 코드를 작성하면 될 것입니다.

하지만 다수의 프레임을 오가며 어떤 작업을 수행해야 한다면 어떻게 해야 할까요? 혹은 특정 시간, 가령 3초 동안 특정 작업을 수행해야 한다면 어떻게 해야 할까요? 3초니깐 3 x 60 = 180 프레임동안 작업을 수행하도록 하면 될까요?

안타깝게도 기기의 성능이나 상황에 따라 프레임 드랍(Frame drop)이라는 상황이 발생하게 됩니다. 60fps의 게임일지라 하더라도 디바이스의 성능에 따라 그 이하로 떨어질 수 있다는 의미가 됩니다. 이렇게 되면 더더욱 3초 동안 작업을 수행한다는게 쉽지 않은 일이 됩니다.

예로 다음의 코드를 준비하였습니다. 특정 오브젝트를 페이드 아웃(Fade out) 시키는 예제 코드입니다. 이 코드를 수행하면 스프라이트의 알파값이 점점 작아져서 결국 화면에서 사라지게 됩니다.






위의 코드를 보면 매 프레임마다 스프라이트 렌더러의 알파값을 0.1씩 감소시키고 있습니다. Update() 함수가 10번 호출되면 사라지게 되겠네요. 이는 1/6 초만에 사라지게 된다는것을 의미합니다. 이것도 1/6초만에 사라질지 보장받기가 어렵습니다.

그럼 혹시, 1초에 걸쳐 (60fps가 정상적으로 보장될 경우 60 프레임에 걸쳐) 사라지게 하려면 어떻게 하면 될까요? 대충 알파값을 0.017씩 감소시키면 될까요? 프레임이 아닌 시간 단위로 특정 작업을 수행할 수 있을까요? 여기서 생각할 수 있는 수단은 Time.deltaTime 이 있습니다.

하지만 우리가 여기서 알아보고자 하는것은 델타 타임이 아닌 코루틴이므로 코루틴에 대해서 알아보도록 하겠습니다. 코루틴은 프레임과 상관없이 별도의 서브 루틴에서 원하는 작업을 원하는 시간만큼 수행하는 것이 가능합니다.

다음은 코루틴을 사용하여 1초동안 페이드 아웃을 진행하는 예제 코드입니다.








이전 코드에서는 Update() 에서 모든 작업을 처리하던것을 Start() 에서 RunFadeOut() 코루틴을 실행하는것으로 변경된 것을 볼 수 있습니다. 여기서 주목해야 하는 부분은 yield return new WaitForSeconds(0.1f); 부분입니다.

이 복잡해 보이는 코드는 0.1초 동안 잠시 멈추라는 의미를 가진 코드입니다. 이제 위의 코드를 통해서 페이드 아웃 효과는 0.1초씩 10번을 수행하며 1초동안 사라지는 모습을 보여주게 됩니다. 이 코루틴은 Update() 함수에 종속적이지 않으며 마치 별도의 쓰레드와 같이 동작을 하게 됩니다. 이와 같은 코드로 프레임율에 영향을 받지 않는 시간 기반의 서브루틴을 구동할 수 있게 되었습니다.

IEnumerator와 yield는 무엇이며 어떤 관계가 있는가?

그렇다면 여기서 궁금증을 유발하는 부분이 몇가지 있는데요 RunFadeOut의 리턴 타입은 IEnumerator(열거자) 입니다. 또한 while 문 내부에 보면 yield(양보)라는 구문이 보이는군요. 그 뒤로 return이 따라나오는 것도 일반적인 언어에서 보기 힘든 문법입니다. 이것들이 어떤 관계를 가지고 있는지 알아보겠습니다.

우선 다음의 일반적인 C# 코드를 한번 살펴보도록 하겠습니다.





위의 Main() 함수를 실행하게 되면 다음과 같은 결과물이 출력됩니다.



조금 헷갈리지만 알고보면 어렵지 않은 코드입니다. 이 코드는 다음과 같은 순서로 동작하게 됩니다.

  1. SomeNumbers() 함수를 실행한 결과를 IEnumerator 열거자로 받습니다. 정확히는 실행된 결과가 아닙니다. enumerator 에 함수의 실행결과가 할당 되었다고 생각될만한 코드지만 여기서는 SomeNumbers() 함수는 한줄도 실행되지 않은 상태입니다. 함수의 포인터를 받았다고 생각하시는게 이해하시기 편할 것 같습니다.
  2. while 문을 만나면서 처음으로 enumerator의 MoveNext()가 호출됩니다. 여기서 SomeNumbers()가 실행이 되며 딱 yield 문을 만날때까지 실행이 됩니다.
  3. 첫번째 yield 문인 yield return 3; 을 만납니다. 여기서는 표현식 그대로 return 3에게 양보한다는 느낌으로 코드를 읽으시면 될 것 같습니다. 우선 여기까지 오면 3을 리턴하는것에 양보가 일어납니다. 이때에 리턴되는 값이 존재하므로 MoveNext()의 결과값으로 true가 반환됩니다.
  4. 이제 enumerator의 Current를 통해서 현재 반환된 값을 꺼내올 수 있습니다. MoveNext()를 통해서 yield return 되는 값이 있는지를 알 수 있고 반환된 값이 있다면 Current에 담겨 있게 됩니다.
  5. Debug.Log를 사용하여 Current를 출력해보면 처음으로 양보 반환된 3이 출력되게 됩니다.
  6. 다시한번 while문이 실행되며 MoveNext()가 호출되면 정말 재미있게도 가장 마지막에 yield return이 일어났던 위치의 다음줄부터 재실행이 되게 됩니다. 다시한번 yield 문을 만날때까지 진행이 됩니다.
  7. 이번에는 두번째 yield문인 yield return 5를 만나게 됩니다. 결과적으로 MoveNext() 의 결과값은 true가 되게 됩니다.
  8. 현재 Current에 할당된 값은 MoveNext()의 양보 반환된 값인 5가 될 것입니다.
  9. Debug.Log를 통해 값을 출력해보면 5가 출력됩니다.
  10. 다시한번 while문의 MoveNext()를 호출하면 yield return 5; 다음줄부터 재시작이 되게 되면 yield return 8;까지 진행이 되게 됩니다.
  11. 8이 양보 반환되었으므로 MoveNext()의 값은 true가 되며 Current에는 8이 들어가있게 됩니다.
  12. Debug.Log로 8이 출력됩니다.
  13. 다시한번 MoveNext() 가 호출되며 yield return 8; 이후의 코드부터 실행이 되지만 함수의 끝을 만나게 되므로 더이상 yield가 일어나지 않습니다.
  14. MoveNext() 의 결과 값으로 false가 반환되며 while 문이 종료됩니다.

조금 특이하지만 함수의 반환값이 IEnumerable, IEnumerable<T>, IEnumerator, IEnumerator<T> 인 경우에는 위와 같은 동작을 하게 됩니다. 함수의 동작이 비동기적으로 동작하게 되므로 파라미터에 ref나 out을 사용할 수 없다는 제약 사항이 있습니다. 위의 코드 동작 예시는 코루틴이 어떻게 동작하는지 알기위한 기본적인 코드라고 생각됩니다. 이제 다시 코루틴으로 돌아가 보겠습니다.







StartCoroutine을 직접 구현해 본다면 위와 같은 형태의 코드가 될 것 같습니다. 먼저 코루틴 함수의 포인터 역할을 하는 열거자를 받은 다음에 MoveNext()를 통해 첫번째 yield를 만날때까지 수행하고 그 결과값을 받습니다. 그리고 그 결과값에 맞는 작업을 수행해줍니다. 그리고 이것을 함수가 완료될 때까지 반복합니다.

위의 코드에서는 4번의 MoveNext()가 호출될 것이며 3번의 yield문을 만날 것입니다. 마지막 MoveNext()에서는 false가 반환될 것이므로 코루틴이 종료됩니다. 만약 함수의 실행이 완료되기 이전에 임의로 코루틴을 종료시키고 싶다면 yield break를 호출하면 됩니다. 즉시 MoveNext()에서 false가 반환되어 종료됩니다.

결론적으로 StartCoroutine은 IEnumerator를 반환하는 함수를 인자로 받으며 이 함수는 특이하게도 실행된 결과를 의미하는것이 아니라 함수 포인터와 같은 개념으로 사용이 됩니다.




이 코드를 한번 봐보겠습니다. 일반적인 함수의 개념으로 보자면 StartCoroutine에는 RunCoroutine() 함수의 결과값이 파라미터로 넘겨지게 되어있습니다. 하지만 여기서 RunCoroutine()은 단 한줄도 실행이 되지 않습니다. 함수의 포인터 역할을 하는 IEnumerator가 넘겨지게 되고 MoveNext()를 호출할 때마다 yield 문을 만날때까지 수행됩니다. 만나게 되면 MoveNext()가 true를 반환하고 함수가 끝나거나 yield break; 를 만나게 되면 false를 반환하게 됩니다. true를 반환할 경우 Current를 통해 반환된 값을 꺼내볼 수 있습니다.

StartCoroutine을 수행할 때 사용할 수 있는 두가지 방법

public Coroutine StartCoroutine(IEnumerator routine);

일반적으로 사용할 수 있는 방법입니다. 수행하고자 하는 코루틴의 IEnumerator 열거자를 넘겨서 실행되도록 합니다. 다음과 같은 방법으로 사용이 가능합니다.




위와 같은 방법은 일반적인 방법으로 waitTime 파라미터 값을 넘길 수 있으며 코루틴이 실행되는데에 추가적인 오버헤드가 전혀 없는 방법입니다. 뿐만 아니라 Start() 함수의 반환값을 IEnumerator로 변경하여 아예 코루틴이 실행 완료될때까지 기다리도록 의존적인 방법으로 실행하는 것도 가능합니다.




위의 코드는 WaitAndPrint(waitTime) 코루틴이 실행 완료된 이후에야 Done이 출력되는 과정을 보여줍니다.

public Coroutine StartCoroutine(string methodName, object value = null);

대부분의 경우는 StartCoroutine을 사용하기 위해 전자의 방법을 사용합니다. 하지만 StartCoroutine을 문자열 형태의 코루틴 함수 이름으로도 호출하는 것이 가능합니다. 이렇게 호출하면 StopCoroutine 역시 함수 이름만으로 호출하는것이 가능해 집니다.





위의 코드는 DoSomething(someParameter) 코루틴 함수를 함수 이름과 넘겨질 파라미터를 통해 호출하는 과정을 보여주고 있습니다. 그리고 1초 기다린 뒤에 실행했었던 DoSomething 코루틴을 종료시킵니다. 이러한 함수 이름을 문자열로 넘겨 실행하는 방법은 StartCoroutine을 수행하는데에 오버헤드가 크고 파라미터를 한개밖에 넘길 수 없다는 제약사항이 있습니다. 물론 배열을 넘기는것 역시 가능합니다.

yield return에서 사용할 수 있는 것들

위에서 본 예시에는 WaitForSeconds 클래스를 양보 반환함으로써 원하는 시간(초)만큼 기다리는 것이 가능하다는것을 알 수 있었습니다. 추가로 더 알아 보도록 하겠습니다.

yield return new WaitForSecondsRealtime (float time);

WaitForSeconds와 하는 역할은 동일하지만 결정적으로 다른것이 있습니다. 유니티상의 시간은 임의로 느리게 하거나 빠르게 하는 것이 가능합니다. 이를 Time.timeScale을 통해서 조정을 할 수 있습니다. 매트릭스에서 보던 총알이 느리게 날아오면서 그것을 피하는 모션을 구현해 본다면 이 값을 1보다 낮추게 되면 현재 시간의 진행보다 느려지게 되며 1보다 빠르게 변경하면 현재의 시간의 진행보다 빨라지게 됩니다. 하지만 WaitForSecondsRealtime는 이러한 Scaled Time의 영향을 받지 않고 현실 시간 기준으로만 동작을 하게 됩니다.

yield return new WaitForFixedUpdate ();

다음 FixedUpdate() 가 실행될때까지 기다리게 됩니다. 이 FixedUpdate()는 Update()와 달리 일정한 시간 단위로 호출되는 Update() 함수라고 생각하시면 됩니다.

yield return new WaitForEndOfFrame ();

하나의 프레임워 완전히 종료될 때 호출이 됩니다. Update(), LateUpdate() 이벤트가 모두 실행되고 화면에 렌더링이 끝난 이후에 호출이 됩니다. 특수한 경우에 사용하면 될 것 같습니다만 잘 모르겠군요.

yield return null;

WaitForEndOfFrame를 이야기 했다면 이것을 꼭 이야기 해야 할 것 같습니다. yield return null; 을 하게 되면 다음 Update() 가 실행될때까지 기다린다는 의미를 갖게 됩니다. 좀 더 정확하게는 Update()가 먼저 실행되고 null을 양보 반환했던 코루틴이 이어서 진행 됩니다. 그 다음에 LateUpdate()가 호출됩니다.

yield return new WaitUntil (System.Func<Bool> predicate);

이번엔 특정 조건식이 성공할때까지 기다리는 방법입니다. WaitUntil에 실행하고자 하는 식을 정의해 두면 매번 Update() 와 LateUpdate() 이벤트 사이에 호출해 보고 결과값이 true면 이후로 재진행을 하게 됩니다. 다음의 예제 코드를 보겠습니다.








이 코드는 Update() 함수를 통해 매 프레임마다 frame 멤버 변수값을 1씩 최대 10까지 증가시키게 됩니다. 실행중인 코루틴은 frame값이 10또는 10보다 커질때까지 기다리다가 이 식이 충족되게 되면 다음으로 진행을 하게 됩니다. 여기서 사용되는 식은 람다 표기법이 사용됩니다. 다음과 같은 느낌이라고 생각하시면 될 것 같습니다.

yield return new WaitWhile(System.Func<Bool> predicate);

WaitWhile은 WaitUntil과 동일한 목적을 가지고 있지만 한가지만 다릅니다. WaitUntil은 람다식 실행 결과값이 true가 될때까지 기다린다면 WaitWhile은 false가 될때까지 기다립니다. 즉 WaitWhile은 결과가 true인 동안 계속 기다리게 됩니다.








위의 코드는 첫프레임부터 람다식의 결과가 true이게 됩니다. 10프레임에 도달하면 false가 되어서 이후 진행이 되겠네요.

yield return StartCoroutine (IEnumerator coroutine);

이번에는 심지어 코루틴 내부에서 또다른 코루틴을 호출할 수 있습니다. 물론 그 코루틴이 완료될 때까지 기다리게 됩니다. 의존성 있는 여러작업을 수행하는데에 유리하게 사용 될 수 있습니다.







위와 같은 코드를 실행해 본다면 결과는 다음과 같이 출력됩니다.

Coroutine 중단하기

public void StopCoroutine(IEnumerator routine);

이 방법은 기존에 StartCoroutine을 실행할 때 넘겨주었던 코루틴 함수의 열거자를 파라미터로 사용하여 그것을 중단시키는 방법입니다. 다음과 같은 사용이 가능합니다.








Start() 함수에서 WaitAndPrint(waitTime) 코루틴 함수의 열거자를 획득하여 클래스의 멤버 변수로 설정해 두고 이 코루틴을 실행합니다. 이 코루틴은 1초에 한번씩 WaitAndPrint 를 출력하게 되며 유저가 스페이스키를 누르게 되면 멤버 변수에 담겨 있는 기존 코루틴의 열거자를 이용하여 실행중인 코루틴을 중단시킵니다.

public void StopCoroutine(string methodName);

이 방법은 이전 방식보다 오버헤드는 크지만 간편하게 사용할 수 있는 방법입니다. 다음과 같이 멤버 변수 없이도 간편하게 사용할 수 있습니다.







이때에 주의할 점으로는 StopCoroutine을 문자열로 종료시키려면 StartCoroutine 역시 문자열로 실행했었어야 한다는 점입니다. StartCoroutine(IEnumerator routine) 으로 실행한 다음에 StopCoroutine(string methodName) 으로 종료시킬 수 없습니다.

public void StopAllCoroutines();

마지막으로 현재 Behaviour (클래스라고 이해하면 될 것 같습니다)에서 실행한 모든 코루틴을 한번에 종료시키는 함수입니다. 이와 같은 방법으로 현재 클래스에서 실행한 모든 코루틴을 한번에 중단시키게 됩니다.





어디선가 Example()을 실행하게 되면 DoSomething 코루틴이 실행되게 되면 곧바로 StopAllCoroutines() 이 호출되어 모든 코루틴이 종료됩니다.

참고 :
http://docs.unity3d.com/kr/current/Manual/Coroutines.html
http://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html


반응형
Posted by blueasa
, |


[링크] http://prosto.tistory.com/255


[참조] http://blueasa.tistory.com/2082

반응형
Posted by blueasa
, |


Unlit - Transparent Colored GrayScale.zip




NGUI의 ScrollView 안에 있는 오브젝트의 UITexture에 GrayScale을 적용하려고 아래 [참고]의 쉐이더를 썼는데


제대로 안되길래 보니 Clipping 개수에 따른 추가 쉐이더가 없어서 겸사겸사 만들어서 올려 놓음.



[참고] http://blueasa.tistory.com/1807

반응형
Posted by blueasa
, |

리모트 프로파일링(Remote profiling)은 다음의 스텝들에 의해서 iOS에 가능화 됩니다:

  1. iOS디바이스를 WiFi 네트워크에 연결하십시오. (로컬/임시(adhoc) WiFi 네트워크는 디바이스로부터의 프로파일링 데이터를 유니티 에디터로 보내기 위해서 프로파일에 의해 사용됩니다.)
  2. 유니티의 빌드 설정(build setting) 대화창의 "Autoconnect Profiler" 체크박스를 표시하십시오.
  3. 디바이스를 맥에 케이블로 부착하여 유니티 에디터의 "Build & Run"를 클릭하세요.
  4. 어플리케이션이 디바이스에서 실행할 때, 유니티 에디터의 프로파일러 창을 여십시오.(Window→Profiler)

_주의:_ 가끔 유니티 에디터는 디바이스로 자동 커넥트(autoconnect) 못할 수도 있습니다. 그런 경우는, 해당 디바이스를 선택하고 프로파일러 창에서 Active Profiler 드롭 다운 메뉴로부터 프로파일러 접속이 시작될 수 있습니다.



[출처] https://openwiki.kr/unity/profiler

반응형
Posted by blueasa
, |

Using this method you can see if you are able to view the page you wanted or not by accessing the html of that page you can read it to see if you got redirected or not. this example uses www.google.com as it's check

  1. using System.Net;
  2. public string GetHtmlFromUri(string resource)
  3. {
  4. string html = string.Empty;
  5. HttpWebRequest req = (HttpWebRequest)WebRequest.Create(resource);
  6. try
  7. {
  8. using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
  9. {
  10. bool isSuccess = (int)resp.StatusCode < 299 && (int)resp.StatusCode >= 200;
  11. if (isSuccess)
  12. {
  13. using (StreamReader reader = new StreamReader(resp.GetResponseStream()))
  14. {
  15. //We are limiting the array to 80 so we don't have
  16. //to parse the entire html document feel free to
  17. //adjust (probably stay under 300)
  18. char[] cs = new char[80];
  19. reader.Read(cs, 0, cs.Length);
  20. foreach(char ch in cs)
  21. {
  22. html +=ch;
  23. }
  24. }
  25. }
  26. }
  27. }
  28. catch
  29. {
  30. return "";
  31. }
  32. return html;
  33. }

This is to call the function

  1. using System.Net;
  2. void Start()
  3. {
  4. string HtmlText = GetHtmlFromUri("http://google.com");
  5. if(HtmlText == "")
  6. {
  7. //No connection
  8. }
  9. else if(!HtmlText.Contains("schema.org/WebPage"))
  10. {
  11. //Redirecting since the beginning of googles html contains that
  12. //phrase and it was not found
  13. }
  14. else
  15. {
  16. //success
  17. }
  18. }



[출처] https://answers.unity.com/questions/567497/how-to-100-check-internet-availability.html

반응형
Posted by blueasa
, |