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


분류 전체보기 (2375)N
Unity3D (592)N
Programming (473)
Unreal (4)
Gamebryo (56)
Tip & Tech (193)
협업 (37)
3DS Max (3)
Game (12)
Utility (118)
Etc (92)
Link (31)
Portfolio (19)
Subject (90)
iOS,OSX (38)
Android (13)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (1)
Memories (20)
Interest (37)
Thinking (37)
한글 (26)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Statistics Graph


« » 2019.12
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        




[링크] https://github.com/Over17/UnityAndroidNotchSupport



Support for Android Notch (Cutout) in Unity 2017.4 and earlier - Over17/UnityAndroidNotchSupport



Android devices with a notch (display cutout) have recently become quite common. However, if you make a Unity application and deploy it to such device, by default Android OS will letter-box your app so that it the notch doesn't interfere with your UI.

If you want to make use of the whole display surface area and render in the area "behind" the notch, you need to add code to your application. Fortunately, since Unity 2018.3 there is a special option in the Player settings called "Render outside safe area" which does exactly this. If you want to have the same option in earlier versions of Unity - this plugin was made for you!

One advantage of this plugin over the built-in Unity solution is that it allows changing the setting in runtime if needed, by calling public void SetRenderBehindNotch(bool enabled) in RenderBehindNotchSupport.

If you are planning to make use of "rendering behind the notch" feature, you'll also need another feature which returns you the area of the screen which is outside of the notch area (and is safe to render to). The API is equivalent to what Screen.safeArea API does in newer Unity versions, and returns a Rect.

This plugin is targeted towards Unity 2017.4, however I see no reasons why it shouldn't work with earlier versions too.

System Requirements

  • Tested on Unity 2017.4.28f1. Should work on any Unity version out there, but make sure your target API is set to 28 or higher. There is no point in using this plugin in Unity 2018.3 or later because these versions have notch support out of the box.
  • An Android device with Android 9 Pie or later. Some devices with earlier Android versions have notch/cutout, but Google has added a corresponding API only in Android 9. Feel free to add other vendor-specific bits of code to add support on earlier Androids at your own risk.


  1. Copy the contents of Assets directory to your project
  2. Attach the Assets/Scripts/RenderBehindNotchSupport.cs script to a game object of your choice in your first scene to make sure the plugin is loaded as early as possible
  3. The script has a public boolean property so that you can tick/untick the checkbox to enable or disable rendering behind the notch with a single click
  4. If you want to change the setting in runtime, call public void SetRenderBehindNotch(bool enabled) in RenderBehindNotchSupport class.
  5. Attach the Assets/Scripts/AndroidSafeArea.cs script to a game object of your choice if you need the safe area API. The property AndroidSafeArea.safeArea is returning a Rect, use it to layout your UI.
  6. Enjoy

Alternative solution

Instead of using the script (or if you want to apply the "render behind the notch" flag as early as possible), you could modify the theme used by Unity. To do so, please create a file at the path Assets/Plugins/Android/res/values-v28/styles.xml with the following contents:

Unity 2017.4 or newer

<?xml version="1.0" encoding="utf-8"?> <resources> <style name="BaseUnityTheme" parent="android:Theme.Material.Light.NoActionBar.Fullscreen"> <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> </style> </resources>

Before 2017.4 (ie. 5.6)

<?xml version="1.0" encoding="utf-8"?> <resources> <style name="UnityThemeSelector" parent="android:Theme.Material.Light.NoActionBar.Fullscreen"> <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> </style> </resources>

There is no need to add the script to your project in this case. You may also need to tweak the snippet above if you are using a custom theme.

I recommend using the default approach with the script unless you have good reasons to do otherwise.

Useful Links


Licensed under MIT license.

Posted by blueasa

댓글을 달아 주세요

[스크립트 파일]



아래 위치와 같이 Anchor의 하위에 GameObject를 하나 만들고,

인스펙터와 같이 Top/Bottom에 따라 만들어진 GameObeject를 Drag&Drop 해서 Link 한다.



위와 같이 셋팅해 주면 Fan이 Top쪽 Safe Area가 있으면 그에 맞게 좀 더 내려온다

(Bottom은 같은 형태로 List Offset List_Bottom에 Link 해주면 된다.)


대충 만들어서 넣어놔서 정리좀 하고 싶지만 다음 기회로..

필요하신 분은 받아서 써보시고 개량해서 공유 좀 해주세요~



[참조] https://blueasa.tistory.com/2272

Posted by blueasa

댓글을 달아 주세요

우선, NGUI의 UIAnchor 대해 SafeAreas 대응 할 수 있기 때문에 참고.

이외에도 SafeAreas으로 다음의 대응이 필요하지만,이 기사에서는 UIAnchor의 대처 방법을 설명합니다.

필요할 수 :

· UIRect의 Anchor

· UIScrollView의 표시 범위 조정 (Anchor의 기준이 변화하기 때문에 UI 조정해야 할)

Contents [ hide ]

전제 조건 :

이 문서는 다음을 전제로 이야기를 진행합니다.

· Unity5.6.6를 사용하여 개발하고 있습니다.

· iOSSafeAreasPlugin을 다운로드하여 가져올 수 있음

Plugin 다운로드 사이트


· OS는 iOS만을 고려하고 있습니다.

소스 코드

우선 소스 코드에서 공개합니다.

안전 영역의 취득


이 소스 코드는 주로 안전 영역의 취득을 담당하고 있습니다.

Unity 편집기에서 화면 크기를 iPhoneX와 같은 크기 (1125 × 2436)로 설정하면 Unity Player에서 디버그 할 수도 있습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;

public class SafeAreaScreen  {

    private extern static void GetSafeAreaImpl(out float x, out float y, out float w, out float h);

    static public Rect GetSafeArea()
        float x, y, w, h;

        x = 0;
        y = 0;
        w = Screen.width;
        h = Screen.height;

        GetSafeAreaImpl(out x, out y, out w, out h);



        if(Screen.width == 1125 && Screen.height == 2436 ){
            y = 102;
            h = 2202;

        return new Rect(x, y, w, h);

    static public int GetTopOffsetY(){
        int offset = 0;

        Rect screenSize = GetSafeArea();

        if (Screen.height != screenSize.height) {
            offset = Screen.height - (int)screenSize.height - (int)screenSize.y;

        return offset;

    static public int GetBottomOffsetY(){
        int offset = 0;

        Rect screenSize = GetSafeArea();

        if (Screen.height != screenSize.height) {
            offset = (int)screenSize.y;

        return offset;


NGUI의 SafeArea


SafeAreaScreen.cs에서 얻은 안전 영역을 바탕으로 Anchor의 위치를 ​​조정합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NguiSafeAreaPatch : MonoBehaviour {

    void Awake()
        // UIAnchorを使ってAnchorを設定している場合
        UIAnchor anchor = gameObject.GetComponent();
        if(anchor != null){



        // UIRectをAnchorを使っている場合
        UIRect rect = gameObject.GetComponent();
        if (rect != null) {

    private void SetUIAnchorOffset(UIAnchor anchor){

        Vector2 nowOffset = anchor.pixelOffset;

        int topCorrectionOffset = SafeAreaScreen.GetTopOffsetY ();

        int bottomCorrectionOffset = SafeAreaScreen.GetBottomOffsetY ();

        switch (anchor.side) {

            case UIAnchor.Side.Top:
            case UIAnchor.Side.TopLeft:
            case UIAnchor.Side.TopRight:
                anchor.pixelOffset.Set(nowOffset.x, nowOffset.y - topCorrectionOffset);


            case UIAnchor.Side.Bottom:
            case UIAnchor.Side.BottomLeft:
            case UIAnchor.Side.BottomRight:
                anchor.pixelOffset.Set(nowOffset.x, nowOffset.y + bottomCorrectionOffset);			




사용법은이 소스 코드를 UIAnchor가 부착되어있는 게임 객체에 첨부 할뿐.

소스에서 무슨 일을하는지는 동작 환경이 iPhoneX 판정되면 스크린과 안전 영역의 높이의 차이를 계산하여 차등 분 게임 오브젝트를 낮 춥니 다.

델타 값은 UIAnchor의 "Pixel Offset"에 할당됩니다.

소스 코드를 반영한 ​​결과

NguiSafeAreaPatch.cs을 UIAnchor에 연결시킨 결과를 기재합니다.

■ 반영 전

■ 반영 후

그 결과 안전 영역을 기준으로 할 수있었습니다.

이것으로 UIAnchor 대해서는 SafeArea의 대처가되었습니다.

그러나, 그 밖에도 「UIRect의 Anchor '에 대해서도 SafeAreas 대응이 있습니다. 대응이 끝나는대로 수시 문서에 추가하는 것입니다.



[출처] https://dream-target.jp/2018/10/01/post-470/



とりあえず、NGUIのUIAnchorについてSafeAreas対応ができたのでメモ。 実行環境がiPhoneXと判定したら、スクリーンとセーフエリアの高さの差分を計算して、差分だけゲームオブジェクト(UIAnchorがアタッチされていること)を下げます。



Posted by blueasa

댓글을 달아 주세요

Unity Script에서 UIApplicationExitsOnSuspend Key 제거(with PostProcessBuild)



using UnityEditor;
using UnityEditor.Callbacks;
using System.IO;
using UnityEditor.iOS.Xcode;
public class BuildProcessor
   public static void OnPostprocessBuild(BuildTarget buildTarget, string pathToBuiltProject)
      // Get plist
      string plistPath = pathToBuiltProject + "/Info.plist";
      PlistDocument plist = new PlistDocument();
      // Get root
      PlistElementDict rootDict = plist.root;
      // Set encryption usage boolean
      string encryptKey = "ITSAppUsesNonExemptEncryption";
        rootDict.SetBoolean(encryptKey, false);
      // remove exit on suspend if it exists.
      string exitsOnSuspendKey = "UIApplicationExitsOnSuspend";
      // Write to file
      File.WriteAllText(plistPath, plist.WriteToString());


[출처] https://forum.unity.com/threads/the-info-plist-contains-a-key-uiapplicationexitsonsuspend.689200/


The Info.plist contains a key 'UIApplicationExitsOnSuspend

I have this error after updated my inapp module. Using unity 2018.3.13f1 ITMS-90339: Deprecated Info.plist Key - The Info.plist contains a key...




[참조] https://blog.naver.com/yoohee2018/221566174487


[Unity] Deprecated Info.plist Key - The Info.plist contains a key 'UIApplicationExitsOnSuspend'

Unity 2019.1.4.1f​[19.06.19 기준 에러발생]유니티 iOS 빌드하여 Xcode에서 Archive 제출 시 다음과...



Posted by blueasa

댓글을 달아 주세요

[링크] — The free app that makes your Internet faster.

Install the free app that makes your phone’s Internet more fast, private, and reliable.의 가장 큰 문제점은, 그게 대체 무엇인지 제대로 설명하는 곳이 없다는 것입니다.

심지어 해당 제품의 설명 페이지 조차도 추상적인 언급만 존재합니다.


어쨌든, 저는 아이폰을 사용하는 지인에게는 그냥 을 쓰라고 말합니다.

주의할 점이 하나 있는데, WARP는 켜지 마십시오. 유료 구독도 할 필요가 없습니다.은 VPN인가?

아닙니다.을 켜면 VPN 로고가 나타나기 때문에 VPN이라 생각하기 쉽지만, VPN이 아니라, 다음의 두가지 일을 수행합니다.


1. DNS 서버를 바꿈.

2. DNS 와의 통신을 암호화 함.


DNS가 뭔데요

인터넷의 특정한 페이지나 자원에 접근하려면 우리는 http://aaa.com/bbb 같은 주소를 씁니다. 이때 aaa.com 이라는 것은 사람이 읽거나 외우기 쉽도록 만들어진 주소 이며, 컴퓨터들 끼리는  4자리의 256진수를 사용합니다.

예를들어 google.com의 경우 실제 컴퓨터가 사용하는 주소는 입니다.


여러분이 브라우저나 기타 모든 인터넷에 접근하는 프로그램을 사용할 때, 운영체제는 google.com 과 같은 주소를로 바꾸기 위해 주소를 DNS 서버에 물어 보게 됩니다. 이를 DNS 쿼리라고 합니다. 안타깝게도 현대의 운영체제는 암호화된 DNS 서버를 자체적으로 지원하지 않기 때문에, 이 내용은 고스란히 광고 추적자나 통신사가 감청할 수 있게 됩니다.


클라우드플레어라는 회사는 이 문제를 해결하기 위해 로컬 VPN서버를 이용해 DNS 쿼리만 암호화 하는 일을 수행하는이라는 앱을 만들었습니다. DNS 쿼리 암호화 이외에 통신 내용 암호화 및 터널링 등 VPN의 본래 목적의 기능은 전혀 수행 하지 않습니다. DNS 쿼리에만 암호화를 추가하는 것 뿐이기 때문에 사실 더 빨라지거나 하지는 않습니다. 단순 기술적으로만 놓고 보자면 아주 아주 아주 약간 더 느려져야 합니다.


근데 왜 쓰라는 겁니까

DNS 쿼리가 감청되는 것을 막기 위해서 입니다. 인터넷 서비스 제공자(통신사, ISP)들은 여러분이 어떤 사이트에 접속하는지 알 수 있기 때문에, 이와 여러분의 가입 정보를 조합하여 양질의 광고 식별자를 만들어 재판매 할 가능성이 있습니다. 이를 원천 봉쇄하기 위함입니다. 또한 ISP들은 여러분이 특정 해외 도메인에 접속 하려 할 때, 특별한 트리거를 작동시킬 수도 있습니다. 예를 들면 다음과 같은 식입니다.


1. 여러분이 넷플릭스에 접속합니다.

2. 여러분의 PC/디바이스는 DNS 에 netflix.com을 쿼리하고 DNS 서버는를 반환합니다.

3. ISP는 2의 과정을 모두 감청 했기 때문에, 여러분의 장비가와 연결을 맺는 다면 넷플릭스를 사용한다는 사실을 알 수 있습니다.

4. ISP는 해외 망 사용료를 줄이기 위해에 접속에 대해 QOS등을 걸어 속도 저하를 일으킬 수 있습니다.


즉, 더 빨라지기 위해서가 아니라, 더 느려지지 않기 위해서 쓰는 것이라고 보시면 됩니다. 


대게의 ISP는 해외망 사용료를 줄이기 위해 국내 망사용료를 지불하지 않는 해외 서비스들에 대해 기본적으로 3%의 정도의 속도로만 작동하게 하며, 비용 지출을 통제 범위 내에 두기 위해, 전체 사용자에 대해 QOS를  각 해외 사이트 마다 두거나 혹은 특별한 블랙 리스트를 운용하는 것으로 여겨 집니다. (망사용료 협상이 잘 안된 사이트들)


예를 들어 새벽 시간대에 iCloud는 그런대로 잘 작동할 수 있습니다. 하지만 모든 유저들이 동시에 iOS를 업데이트 받거나, 활발히 사용하는 시간대에서는 단순 3% 감속 뿐 아니라 전체 사용 트래픽 QOS에 따라 추가적인 속도 저하가 일어날 수 있습니다. 따라서 여러분이 iCloud에 접속하는 것을 모르도록 만드는 일이 중요한 일이 될 수 있습니다. 


iCloud와 같은 광범위한 클라우드 서비스는 매우 넓은 영역의 IP를 사용하고 자주 바뀌기 때문에 통신사는 IP만으로 여러분이 iCloud에 접속한다는 사실을 알 수 없습니다. 따라서, DNS 쿼리를 암호화 하면 IP가 해외 주소란 것만 알지 아이클라우드라는 것은 모르기 때문에 3%로만 느려질 뿐, 추가적인 QOS가 더 걸리지는 않는다는 겁니다.


하지만은 DNS 쿼리만 암호화 할 뿐, 통신 내용의 비밀을 보장해 주지 않는 다는 점을 기억하십시오. https가 아닌 http에 접속한다면, 제 3자가 모든 내용을 볼 수 있습니다.


WARP는 뭔데요

안타깝게도 세상과 자본주의는 더 흉악해서 암호화된 DNS 서버 사용만으로는 여러분을 완전히 보호할 수 없습니다. 요즘은 클라우드 시대이다 보니, 같은 IP 주소에 여러개의 서비스가 제공되고 있을 수 있습니다.


예를 들어 구글과 페이스북이 라는 곳에서 함께 운영되고 있다고 가정합시다. 라는 주소 만으로는 페이스 북인지 구글인지 구분할 수 없습니다. 그래서 우리가 같은 주소에 살고 있는 수신자를 구분하기 위해 사서함 번호를 사용하듯, 요청에는 받는 주소(IP)외에도 "구글" 혹은 "페이스 북"이라고 함께 기재해 보내야 합니다.


이것이 그 유명한 SNI(서버 이름 식별자)입니다. 안타깝게도 이 또한 암호화되어 있지 않습니다. 일반적인 https의 SSL로 이를 암호화 하려면 누가 알아볼 수 있는 키로 암호화 해야 하나라는 문제가 생깁니다. 구글의 키로 암호화 하건, 페이스북의 키로 암호화 하건,라는 서버는 이를 복호화 할 수 없으므로 누구에게 요청을 전달해야 하는지 알 수 없게 됩니다. 따라서 이 보다 상위 수준의 암호화 프로토콜이 필요해 지는 것입니다.


통신사는 SNI 정보를 이용하여, DNS를 암호화 하여 인터넷 연결을 보호하려는 전략을 파괴할 수 있으며, 더 나가서는 감청 및 차단, 위조등을 수행할 수 있게 됩니다. 심지어 대한민국의 경우 SNI 감청 기술을 국가가 개발하여 통신사에 넘겼습니다. 이를 막기 위해 애플 및 구글 클라우드 플레어라는 회사들이 암호화된 SNI(ESNI) 프로토콜을 만들고 있지만, 암호화된 DNS와 마찬가지로 현재로서는 이를 지원하는 운영체제 나 웹 서비스가 존재하지 않습니다.


(일부 브라우저가 플러그인 형태로 제공하지만, 이는 브라우저의 통신만 보호할 뿐, 운영체제 전체의 인터넷 접근 기능을 보호하지 못합니다.)


이 문제를 해결하기 위해 WARP 라는 서비스가 추가로 탄생합니다. WARP는 다음과 같은 일을 합니다.

1. 일단이 하는 일은 다 합니다.

2. 기기내 모든 암호화 되지 않은 모든 요청을 암호화 하여 서버로 보냅니다.

3. 서버는 실제 요청을 받아들일 서버로 요청을 대신 보냅니다. 이때 해당 서버가 WARP와 호환이 되는 경우라면, 여러분의 IP및 식별 정보를 함께 보냅니다. (VPN과 달리 WARP는 여러분을 숨겨주지 않습니다!!! 단지 제 3자가 못 보게 막는 것 뿐입니다.) 그래야 IP 기반의 국가별 서비스가 제대로 동작하기 때문입니다. (국가별 콘텐트나 지도등)

4. 응답도 대신 받아 암호화 하여 다시 돌려 보내 줍니다.


거의 VPN과 유사합니다. 다만, IP를 숨기지 않습니다. (지원되는 경우만 한하여 - 현재로서는 클라우드 플레어에서 호스트 되는 서비스들만 지원 됨) 유료로 구독하는 경우, 3~4과정의 라우팅을 여러분의 위치에 더 적합하게 바꾸고 일정 수준의 트래픽을 보장하게 됩니다. WARP는 일단 라우팅 경로가 다르기 때문에, 최적의 속도를 낼 수 없고(하지만 실제로는 어른들의 사정에 의해 더 빨라질 수 있음), 동작 원리의 대부분이 VPN이기 때문에 트래픽에 민감하며(유료 구독이 아니라면), WARP를 지원하는 사이트의 수가 매우 적기 때문에 사용이 권장되지 않습니다. 


예를 들어 WARP를 켜면 넷플릭스는 여러분이 미국에 거주하는 고객이라고 착각하게 되어 한글 자막을 사용할 수 없게 될 것입니다. 페이스 북이나 구글 같은 큰 서비스들도 지원되지 않아 여러분이 미국에서 접속한 것으로 취급할 것입니다.



- 을 쓰면 DNS 쿼리가 암호화되어 여러분이 어떤 인터넷 서비스를 쓰는 지 통신사가 모름

- 따라서 개인 정보 노출 및 서비스에 대한 특수한 제약을 막을 수 있음. 하지만 이는 SNI 감청으로 털릴 수 있는 상황이나 현재는 사이트 차단 용도로만 활용되고 있음.

- WARP를 쓰면 클라우드 플레어에서 호스팅 되는 서비스들과 SNI를 포함하여 안전하게 암호화 통신을 하면서도, 해당 서비스들에게 VPN 처럼 여러분의 IP를 숨기지 않아도 됨. 하지만, 대부분의 비 WARP 호환 서비스들은 VPN을 통해 접속하는 것 처럼 작동하게 되므로 권장되지 않음.




아직까지는 SNI 감청에 의한 고의 속도 저하는 관측된 바가 없습니다만, 이것도 시간 문제일거라고 봅니다.



[출처] https://www.clien.net/service/board/cm_iphonien/14353306 WARP 가 도대체 무엇인가 : 클리앙의 가장 큰 문제점은, 그게 대체 무엇인지 제대로 설명하는 곳이 없다는 것입니다. 심지어 해당 제품의 설명 페이지 조차도 추상적인 언급만 존재합니다. 어쨌든, 저는 아이폰을 사용하는 지인에게는 그냥 을 쓰라고 말합니다. 주의할 점이 하나 있는데, WARP는 켜지 마십시오. 유료 구독도 할 필요가 없습니다.은 VPN인가? 아닙니다.을 켜면 VPN 로고가 나타나기 때문에 VPN이라 생각하기



Posted by blueasa

댓글을 달아 주세요

        // AndroidManifext.xml
        // <meta-data android:name="aa.bb.channelid" android:value="D4LW023" />
        // <meta-data android:name="aa.bb.subchannelid" android:value="1" />
        AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity");
        string packageName = activity.Call<string>("getPackageName");
        AndroidJavaObject manager = activity.Call<AndroidJavaObject>("getPackageManager");
        AndroidJavaObject packageInfo = manager.Call<AndroidJavaObject>("getApplicationInfo", packageName, manager.GetStatic<int>("GET_META_DATA"));
        AndroidJavaObject aBundle = packageInfo.Get<AndroidJavaObject>("metaData");
        string strChannelId = aBundle.Call<string>("getString", "aa.bb.channelid");	// string
        int iSubChannelId = aBundle.Call<int>("getInt", "aa.bb.subchannelid");	// int


[정보제공] 게임코디-선후님

Posted by blueasa

댓글을 달아 주세요

[링크] http://naver.me/GvreNiF5


손가락 빠는 버릇, 이렇게 고쳐주기

[BY 허그맘] 4살 딸아이가 손가락을 심하게 빨아서 걱정이 많습니다. 처음에는 심심하거나 졸릴 때 주로...


Posted by blueasa

댓글을 달아 주세요