So I had some spare time to study things I've always wanted to.
Left: Default shader // Right: Blur shader
Note: All shader files (including the files with number suffix) must be downloaded together. The numbers represent the clipping panel count when using Soft Clip on UIPanel components. Refer to:http://www.tasharen.com/forum/index.php?topic=13985.0
You can customize the amount of blurring by editing the two fields below. iterations variable represents the radius. blurSize variable represents the scale (in UV coordinate) which the other pixel should be sampled from. It should be possible to expose these fields so you can mess around with them through Materials or C# scripts.
half blurSize =0.005; half iterations =4;
Limitations: Originally I wanted to implement a Gaussian Blur effect but it's quite complicated and expensive. So it ended up in a sort of "hack" by blurring the pixels in horizontal and vertical axis only. While it may look fine on low iteration count, it doesn't take the diagonal pixels in to calculation, making high radius blurs look unnatural. I am planning to make another workaround for this issue some time.
Unity 편집기에서 화면 크기를 iPhoneX와 같은 크기 (1125 × 2436)로 설정하면 Unity Player에서 디버그 할 수도 있습니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
public class SafeAreaScreen {
#if UNITY_IOS
[DllImport("__Internal")]
private extern static void GetSafeAreaImpl(out float x, out float y, out float w, out float h);
#endif
static public Rect GetSafeArea()
{
float x, y, w, h;
//初期値設定
x = 0;
y = 0;
w = Screen.width;
h = Screen.height;
#if UNITY_IOS && !UNITY_EDITOR
//iOSSafeAreasPluginを呼び出す
GetSafeAreaImpl(out x, out y, out w, out h);
#elif UNITY_ANDROID && !UNITY_EDITOR
//Androidの縦長端末対応が必要になったときのために
#else
//UnityエディタでiPhoneXのテストできるように値を設定する
if(Screen.width == 1125 && Screen.height == 2436 ){
y = 102;
h = 2202;
}
#endif
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;
//セーフエリアのyの位置取得
Rect screenSize = GetSafeArea();
if (Screen.height != screenSize.height) {
offset = (int)screenSize.y;
}
return offset;
}
}
NGUI의 SafeArea
NguiSafeAreaPatch.cs
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){
//offsetの値を取得する
SetUIAnchorOffset(anchor);
return;
}
// UIRectをAnchorを使っている場合
UIRect rect = gameObject.GetComponent();
if (rect != null) {
//現在,NGUIのソースコードを解析中
//完成しだい公開予定
return;
}
}
private void SetUIAnchorOffset(UIAnchor anchor){
//現在のoffsetを取得する
Vector2 nowOffset = anchor.pixelOffset;
//TOP側の補正値取得
int topCorrectionOffset = SafeAreaScreen.GetTopOffsetY ();
//Bottom側の補正値取得
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);
break;
case UIAnchor.Side.Bottom:
case UIAnchor.Side.BottomLeft:
case UIAnchor.Side.BottomRight:
anchor.pixelOffset.Set(nowOffset.x, nowOffset.y + bottomCorrectionOffset);
break;
}
}
}
사용법은이 소스 코드를 UIAnchor가 부착되어있는 게임 객체에 첨부 할뿐.
소스에서 무슨 일을하는지는 동작 환경이 iPhoneX 판정되면 스크린과 안전 영역의 높이의 차이를 계산하여 차등 분 게임 오브젝트를 낮 춥니 다.
델타 값은 UIAnchor의 "Pixel Offset"에 할당됩니다.
소스 코드를 반영한 결과
NguiSafeAreaPatch.cs을 UIAnchor에 연결시킨 결과를 기재합니다.
■ 반영 전
■ 반영 후
그 결과 안전 영역을 기준으로 할 수있었습니다.
이것으로 UIAnchor 대해서는 SafeArea의 대처가되었습니다.
그러나, 그 밖에도 「UIRect의 Anchor '에 대해서도 SafeAreas 대응이 있습니다.대응이 끝나는대로 수시 문서에 추가하는 것입니다.