├── .editorconfig ├── .github └── FUNDING.yml ├── .gitignore ├── Editor.meta ├── Editor ├── Gilzoide.SafeAreaLayout.Editor.asmdef ├── Gilzoide.SafeAreaLayout.Editor.asmdef.meta ├── SafeAreaLayoutGroupEditor.cs └── SafeAreaLayoutGroupEditor.cs.meta ├── Extras~ ├── demo.gif └── demo.mp4 ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── Anchors.cs ├── Anchors.cs.meta ├── Gilzoide.SafeAreaLayout.asmdef ├── Gilzoide.SafeAreaLayout.asmdef.meta ├── IgnoreSafeArea.cs ├── IgnoreSafeArea.cs.meta ├── KeyValuePairExtensions.cs ├── KeyValuePairExtensions.cs.meta ├── SafeAreaLayoutGroup.cs ├── SafeAreaLayoutGroup.cs.meta ├── SafeAreaUtility.cs └── SafeAreaUtility.cs.meta ├── Samples~ ├── SimpleSample.meta └── SimpleSample │ ├── SampleScene.unity │ └── SampleScene.unity.meta ├── UNLICENSE ├── UNLICENSE.meta ├── package.json └── package.json.meta /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | 9 | [*.cs] 10 | indent_size = 4 -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [gilzoide] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: gilzoide # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: gilzoide # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Samples 2 | Samples.meta -------------------------------------------------------------------------------- /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0122a24dbe560414fa955eed3e9aa4fc 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/Gilzoide.SafeAreaLayout.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Gilzoide.SafeAreaLayout.Editor", 3 | "rootNamespace": "Gilzoide.SafeAreaLayout.Editor", 4 | "references": [ 5 | "GUID:fd2e74c383d99ee42b26f035675e91df" 6 | ], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": false, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /Editor/Gilzoide.SafeAreaLayout.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1758ad77bd2804766853c38e6bdb092e 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Editor/SafeAreaLayoutGroupEditor.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | 5 | namespace Gilzoide.SafeAreaLayout.Editor 6 | { 7 | [CustomEditor(typeof(SafeAreaLayoutGroup)), CanEditMultipleObjects] 8 | public class SafeAreaLayoutGroupEditor : UnityEditor.Editor 9 | { 10 | private static readonly GUIContent _previewModeContent = new GUIContent 11 | { 12 | text = "Preview Mode", 13 | tooltip = "This will be used to simulate cutouts in editor while playing or hovering the preview button below", 14 | }; 15 | 16 | public override void OnInspectorGUI() 17 | { 18 | serializedObject.Update(); 19 | DrawDefaultInspector(); 20 | serializedObject.ApplyModifiedProperties(); 21 | 22 | EditorGUILayout.Space(); 23 | EditorGUILayout.LabelField("Editor cutout simulation", EditorStyles.boldLabel); 24 | 25 | int currentPreviewMode = SafeAreaUtility.CurrentEditorPreviewMode; 26 | int newPreviewMode = EditorGUILayout.Popup(_previewModeContent, currentPreviewMode, SafeAreaUtility.EditorPreviewModeNames); 27 | if (currentPreviewMode != newPreviewMode) 28 | { 29 | SafeAreaUtility.CurrentEditorPreviewMode = newPreviewMode; 30 | if (Application.isPlaying) 31 | { 32 | RefreshAll(); 33 | } 34 | } 35 | 36 | bool preview = HoverButton("Hover to Preview Layout"); 37 | if (preview != SafeAreaLayoutGroup.PreviewInEditor) 38 | { 39 | SafeAreaLayoutGroup.PreviewInEditor = preview; 40 | RefreshAll(); 41 | } 42 | } 43 | 44 | private static void RefreshAll() 45 | { 46 | foreach (SafeAreaLayoutGroup safeArea in FindObjectsOfType()) 47 | { 48 | safeArea.RefreshChildrenAnchors(); 49 | LayoutRebuilder.ForceRebuildLayoutImmediate(safeArea.SelfRectTransform); 50 | } 51 | SceneView.RepaintAll(); 52 | } 53 | 54 | private static bool HoverButton(string content) 55 | { 56 | GUILayout.Box(content, EditorStyles.miniButton); 57 | return GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /Editor/SafeAreaLayoutGroupEditor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 59123a62bd8fc4a86ae13c2ca399a7f1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Extras~/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-safe-area-layout/647b3ea0706fb3ff7684dc524c2fba9a62ec7452/Extras~/demo.gif -------------------------------------------------------------------------------- /Extras~/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gilzoide/unity-safe-area-layout/647b3ea0706fb3ff7684dc524c2fba9a62ec7452/Extras~/demo.mp4 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Safe Area Layout 2 | [![openupm](https://img.shields.io/npm/v/com.gilzoide.safe-area-layout?label=openupm®istry_uri=https://package.openupm.com)](https://openupm.com/packages/com.gilzoide.safe-area-layout/) 3 | 4 | Unity GUI [layout group](https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/UIAutoLayout.html#layout-groups) 5 | that makes children respect the [Safe Area](https://docs.unity3d.com/ScriptReference/Screen-safeArea.html). 6 | It drives direct children's anchors while in Play Mode and supports [`LayoutElement.ignoreLayout`](https://docs.unity3d.com/Packages/com.unity.ugui@1.0/api/UnityEngine.UI.ILayoutIgnorer.html). 7 | 8 | ![Demonstration video](Extras~/demo.gif) 9 | 10 | ## Features 11 | - Fully integrated with Unity GUI's layout system: only rebuilds the layout when needed, no `Update` method or coroutines attached 12 | - Does not resize it's own `RectTransform`, so it can be used in objects with a `Canvas` component directly 13 | - Does not demand a full screen `RectTransform`: the script detects where your rect overlaps with the Safe Area and updates accordingly 14 | - Ignore children using a `IgnoreSafeArea` component or `LayoutElement` with `Ignore Layout` marked as true. 15 | Useful for background images, for example. 16 | - Preview Safe Area adjustments in Editor using any of the Preview Modes in `SafeAreaLayoutGroup`'s inspector while hovering the `Hover to Preview Layout` button or while in Play Mode. 17 | All Preview Modes support both portrait and landscape resolutions. 18 | `Screen.safeArea` Preview Mode is only applied when using Unity's [Device Simulator](https://docs.unity3d.com/Manual/device-simulator-introduction.html) (in Unity 2020 and older, available as an [UPM package](https://docs.unity3d.com/Packages/com.unity.device-simulator@latest/index.html)) 19 | - Only affects canvases in either `Screen Space - Overlay` or `Screen Space - Camera` modes, so `World Space` canvases are ignored 20 | 21 | 22 | ## Installing 23 | Either: 24 | 25 | - Install using [openupm](https://openupm.com/): 26 | ``` 27 | openupm add com.gilzoide.safe-area-layout 28 | ``` 29 | 30 | - Install via [Unity Package Manager](https://docs.unity3d.com/Manual/upm-ui-giturl.html) 31 | using the following git URL: 32 | ``` 33 | https://github.com/gilzoide/unity-safe-area-layout.git#1.0.2 34 | ``` 35 | 36 | - Clone this repository directly to your `Packages` folder or anywhere inside your project's `Assets`. 37 | 38 | 39 | ## Sample 40 | A sample scene is available at [Samples~/SimpleSample](Samples~/SimpleSample). 41 | 42 | 43 | ## How to use 44 | 1. Add the [SafeAreaLayoutGroup](Runtime/SafeAreaLayoutGroup.cs) script anywhere in your UI hierarchy, even objects with `Canvas` components are supported. 45 | Direct children will have their anchors driven while the script is enabled. 46 | 2. (optional) Select the Safe Area edges that your layout group will respect. 47 | 3. (optional) Make specific children be ignored by the layout group by adding the `IgnoreSafeArea` component to them. 48 | Alternatively, use `LayoutElement` components with the `Ignore Layout` flag marked as true. 49 | 4. (optional) Use one of the Preview Modes while in editor to preview the adjustments. 50 | Preview is applied on Play Mode and while hovering the `Hover to Preview Layout` button in the `SafeAreaLayoutGroup`'s inspector. 51 | 5. Play the game (play the game, everybody play the gaaaame) 52 | 6. Enjoy 🍾 53 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c2dcb89faeaf64274b08643a4a2e1c30 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 71c6aca1e8708b246bd58b6b82351d22 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/Anchors.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Gilzoide.SafeAreaLayout 4 | { 5 | public struct Anchors 6 | { 7 | public Vector2 AnchorMin; 8 | public Vector2 AnchorMax; 9 | 10 | public Anchors(Vector2 anchorMin, Vector2 anchorMax) 11 | { 12 | AnchorMin = anchorMin; 13 | AnchorMax = anchorMax; 14 | } 15 | 16 | public Anchors(RectTransform rectTransform) 17 | { 18 | AnchorMin = rectTransform.anchorMin; 19 | AnchorMax = rectTransform.anchorMax; 20 | } 21 | 22 | public Anchors WithHorizontalMargins(float leftMargin, float rightMargin) 23 | { 24 | return new Anchors( 25 | anchorMin: new Vector2(Remap01(AnchorMin.x, leftMargin, 1f - rightMargin), AnchorMin.y), 26 | anchorMax: new Vector2(Remap01(AnchorMax.x, leftMargin, 1f - rightMargin), AnchorMax.y) 27 | ); 28 | } 29 | 30 | public Anchors WithVerticalMargins(float bottomMargin, float topMargin) 31 | { 32 | return new Anchors( 33 | anchorMin: new Vector2(AnchorMin.x, Remap01(AnchorMin.y, bottomMargin, 1f - topMargin)), 34 | anchorMax: new Vector2(AnchorMax.x, Remap01(AnchorMax.y, bottomMargin, 1f - topMargin)) 35 | ); 36 | } 37 | 38 | public void ApplyTo(RectTransform rectTransform) 39 | { 40 | rectTransform.anchorMin = AnchorMin; 41 | rectTransform.anchorMax = AnchorMax; 42 | } 43 | 44 | private static float Remap01(float value, float from, float to) 45 | { 46 | return from + (to - from) * value; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Runtime/Anchors.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9498a296e00482e4bb125da644016ceb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/Gilzoide.SafeAreaLayout.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Gilzoide.SafeAreaLayout", 3 | "rootNamespace": "Gilzoide.SafeAreaLayout", 4 | "references": [], 5 | "includePlatforms": [], 6 | "excludePlatforms": [], 7 | "allowUnsafeCode": false, 8 | "overrideReferences": false, 9 | "precompiledReferences": [], 10 | "autoReferenced": true, 11 | "defineConstraints": [], 12 | "versionDefines": [], 13 | "noEngineReferences": false 14 | } -------------------------------------------------------------------------------- /Runtime/Gilzoide.SafeAreaLayout.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fd2e74c383d99ee42b26f035675e91df 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime/IgnoreSafeArea.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.UI; 3 | 4 | namespace Gilzoide.SafeAreaLayout 5 | { 6 | public class IgnoreSafeArea : MonoBehaviour, ILayoutIgnorer 7 | { 8 | public bool ignoreLayout => true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Runtime/IgnoreSafeArea.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df8b0765def604e77b929b38a87f10a1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/KeyValuePairExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Gilzoide.SafeAreaLayout 4 | { 5 | public static class KeyValuePairExtensions 6 | { 7 | public static void Deconstruct(this KeyValuePair entry, out TKey key, out TValue value) 8 | { 9 | key = entry.Key; 10 | value = entry.Value; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Runtime/KeyValuePairExtensions.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 27e5ed3e2be9287429fb9e4594b71484 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SafeAreaLayoutGroup.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | using UnityEngine.UI; 4 | 5 | namespace Gilzoide.SafeAreaLayout 6 | { 7 | [RequireComponent(typeof(RectTransform)), ExecuteAlways] 8 | public class SafeAreaLayoutGroup : MonoBehaviour, ILayoutGroup 9 | { 10 | public bool IsDrivingLayout => (Application.isPlaying || PreviewInEditor) 11 | && _canvas != null && _canvas.renderMode != RenderMode.WorldSpace; 12 | 13 | #if UNITY_EDITOR 14 | public static bool PreviewInEditor = false; 15 | #else 16 | public const bool PreviewInEditor = false; 17 | #endif 18 | 19 | [Tooltip("Whether safe area's top edge will be respected")] 20 | public bool TopEdge = true; 21 | [Tooltip("Whether safe area's left edge will be respected")] 22 | public bool LeftEdge = true; 23 | [Tooltip("Whether safe area's right edge will be respected")] 24 | public bool RightEdge = true; 25 | [Tooltip("Whether safe area's bottom edge will be respected")] 26 | public bool BottomEdge = true; 27 | 28 | public RectTransform SelfRectTransform => (RectTransform) transform; 29 | 30 | protected readonly Dictionary _childrenAnchors = new Dictionary(); 31 | protected DrivenRectTransformTracker _drivenRectTransformTracker = new DrivenRectTransformTracker(); 32 | protected readonly Vector3[] _worldCorners = new Vector3[4]; 33 | protected Canvas _canvas; 34 | protected Rect _screenRect; 35 | 36 | protected virtual void OnEnable() 37 | { 38 | _canvas = FindRootCanvas(); 39 | RefreshChildrenAnchors(); 40 | } 41 | 42 | protected virtual void OnDisable() 43 | { 44 | _canvas = null; 45 | ClearChildrenAnchors(); 46 | } 47 | 48 | protected virtual void OnTransformChildrenChanged() 49 | { 50 | if (isActiveAndEnabled) 51 | { 52 | RefreshChildrenAnchors(); 53 | } 54 | } 55 | 56 | protected virtual void OnTransformParentChanged() 57 | { 58 | if (isActiveAndEnabled) 59 | { 60 | _canvas = FindRootCanvas(); 61 | RefreshChildrenAnchors(); 62 | } 63 | } 64 | 65 | public virtual void SetLayoutHorizontal() 66 | { 67 | if (!IsDrivingLayout) 68 | { 69 | return; 70 | } 71 | 72 | RefreshScreenRect(); 73 | float horizontalSize = _screenRect.size.x; 74 | if (horizontalSize <= 0) 75 | { 76 | return; 77 | } 78 | 79 | Rect safeArea = SafeAreaUtility.GetSafeArea(); 80 | float leftMargin = LeftEdge ? Mathf.Max(0, safeArea.xMin - _screenRect.xMin) / horizontalSize : 0; 81 | float rightMargin = RightEdge ? Mathf.Max(0, _screenRect.xMax - safeArea.xMax) / horizontalSize : 0; 82 | 83 | foreach ((RectTransform child, Anchors anchors) in _childrenAnchors) 84 | { 85 | anchors.WithHorizontalMargins(leftMargin, rightMargin).ApplyTo(child); 86 | } 87 | } 88 | 89 | public virtual void SetLayoutVertical() 90 | { 91 | if (!IsDrivingLayout) 92 | { 93 | return; 94 | } 95 | 96 | float verticalSize = _screenRect.size.y; 97 | if (verticalSize <= 0) 98 | { 99 | return; 100 | } 101 | 102 | Rect safeArea = SafeAreaUtility.GetSafeArea(); 103 | float bottomMargin = BottomEdge ? Mathf.Max(0, safeArea.yMin - _screenRect.yMin) / verticalSize : 0; 104 | float topMargin = TopEdge ? Mathf.Max(0, _screenRect.yMax - safeArea.yMax) / verticalSize : 0; 105 | 106 | foreach ((RectTransform child, _) in _childrenAnchors) 107 | { 108 | new Anchors(child).WithVerticalMargins(bottomMargin, topMargin).ApplyTo(child); 109 | } 110 | } 111 | 112 | public void ClearChildrenAnchors() 113 | { 114 | _drivenRectTransformTracker.Clear(); 115 | foreach ((RectTransform child, Anchors anchors) in _childrenAnchors) 116 | { 117 | anchors.ApplyTo(child); 118 | } 119 | _childrenAnchors.Clear(); 120 | } 121 | 122 | public void RefreshChildrenAnchors() 123 | { 124 | if (!IsDrivingLayout) 125 | { 126 | ClearChildrenAnchors(); 127 | return; 128 | } 129 | 130 | _drivenRectTransformTracker.Clear(); 131 | var childrenToUntrack = new HashSet(_childrenAnchors.Keys); 132 | foreach (Transform child in transform) 133 | { 134 | if (!(child is RectTransform rectTransform) 135 | || child.TryGetComponent(out ILayoutIgnorer ignorer) && ignorer.ignoreLayout) 136 | { 137 | continue; 138 | } 139 | 140 | _drivenRectTransformTracker.Add(this, rectTransform, DrivenTransformProperties.Anchors); 141 | if (!_childrenAnchors.ContainsKey(rectTransform)) 142 | { 143 | _childrenAnchors[rectTransform] = new Anchors(rectTransform); 144 | } 145 | childrenToUntrack.Remove(rectTransform); 146 | } 147 | 148 | foreach (RectTransform previousChild in childrenToUntrack) 149 | { 150 | _childrenAnchors.Remove(previousChild); 151 | } 152 | 153 | LayoutRebuilder.MarkLayoutForRebuild(SelfRectTransform); 154 | } 155 | 156 | protected void RefreshScreenRect() 157 | { 158 | SelfRectTransform.GetWorldCorners(_worldCorners); 159 | 160 | Vector3 bottomLeft = _worldCorners[0]; 161 | Vector3 topRight = _worldCorners[2]; 162 | if (_canvas.renderMode == RenderMode.ScreenSpaceCamera && _canvas.worldCamera != null) 163 | { 164 | Camera camera = _canvas.worldCamera; 165 | bottomLeft = camera.WorldToScreenPoint(bottomLeft); 166 | topRight = camera.WorldToScreenPoint(topRight); 167 | } 168 | _screenRect = Rect.MinMaxRect(bottomLeft.x, bottomLeft.y, topRight.x, topRight.y); 169 | } 170 | 171 | protected Canvas FindRootCanvas() 172 | { 173 | Canvas canvas = GetComponentInParent(); 174 | return canvas != null ? canvas.rootCanvas : null; 175 | } 176 | 177 | #if UNITY_EDITOR 178 | protected virtual void OnValidate() 179 | { 180 | LayoutRebuilder.MarkLayoutForRebuild(SelfRectTransform); 181 | } 182 | #endif 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /Runtime/SafeAreaLayoutGroup.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 970e6a3612105e14bbb42ae9c891cda5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SafeAreaUtility.cs: -------------------------------------------------------------------------------- 1 | using UnityEditor; 2 | using UnityEngine; 3 | 4 | namespace Gilzoide.SafeAreaLayout 5 | { 6 | public static class SafeAreaUtility 7 | { 8 | #if UNITY_EDITOR 9 | public const float NotchScreenProportion = 44f / 812f; 10 | public const float HomeButtonNotchScreenProportion = 21f / 375f; 11 | 12 | public static readonly string EditorPreviewModePrefsKey = $"{typeof(SafeAreaLayoutGroup).FullName}.{nameof(EditorPreviewMode)}"; 13 | 14 | public enum EditorPreviewMode 15 | { 16 | /// Uses . Preview can only be seen on scenes 17 | ScreenSafeArea, 18 | /// Simulates an iPhone X cutout (top + bottom in portrait, left + right + bottom in landscape) 19 | IPhoneX, 20 | /// Simulates a single cutout (top in portrait, left in landscape) 21 | SingleCutoutTop, 22 | /// Simulates a single cutout (bottom in portrait, right in landscape) 23 | SingleCutoutBottom, 24 | /// Simulates a double cutout (top + bottom in portrait, left + right in landscape) 25 | DoubleCutout, 26 | } 27 | 28 | public static readonly string[] EditorPreviewModeNames = { 29 | "Screen.safeArea", 30 | "iPhone X", 31 | "Single Cutout (top)", 32 | "Single Cutout (bottom)", 33 | "Double Cutout", 34 | }; 35 | 36 | public static int CurrentEditorPreviewMode 37 | { 38 | get => EditorPrefs.GetInt(EditorPreviewModePrefsKey, (int) EditorPreviewMode.ScreenSafeArea); 39 | set => EditorPrefs.SetInt(EditorPreviewModePrefsKey, value); 40 | } 41 | 42 | public static Rect GetSafeArea() 43 | { 44 | Rect screenRect = new Rect(0, 0, Screen.width, Screen.height); 45 | switch ((EditorPreviewMode) CurrentEditorPreviewMode) 46 | { 47 | case EditorPreviewMode.ScreenSafeArea: 48 | default: 49 | return Screen.safeArea; 50 | 51 | case EditorPreviewMode.IPhoneX: 52 | return ApplyCutoutIPhoneX(screenRect); 53 | 54 | case EditorPreviewMode.SingleCutoutTop: 55 | return ApplyCutoutTop(screenRect); 56 | 57 | case EditorPreviewMode.SingleCutoutBottom: 58 | return ApplyCutoutBottom(screenRect); 59 | 60 | case EditorPreviewMode.DoubleCutout: 61 | return ApplyCutoutDouble(screenRect); 62 | } 63 | } 64 | 65 | public static Rect ApplyCutoutIPhoneX(Rect rect) 66 | { 67 | bool isPortrait = rect.height >= rect.width; 68 | if (isPortrait) 69 | { 70 | float inset = rect.height * NotchScreenProportion; 71 | rect.yMin += inset; 72 | rect.yMax -= inset; 73 | } 74 | else 75 | { 76 | float horizontalInset = rect.width * NotchScreenProportion; 77 | rect.xMin += horizontalInset; 78 | rect.xMax -= horizontalInset; 79 | float homeButtonInset = rect.height * HomeButtonNotchScreenProportion; 80 | rect.yMin += homeButtonInset; 81 | } 82 | return rect; 83 | } 84 | 85 | public static Rect ApplyCutoutTop(Rect rect) 86 | { 87 | bool isPortrait = rect.height >= rect.width; 88 | if (isPortrait) 89 | { 90 | float inset = rect.height * NotchScreenProportion; 91 | rect.yMax -= inset; 92 | } 93 | else 94 | { 95 | float horizontalInset = rect.width * NotchScreenProportion; 96 | rect.xMin += horizontalInset; 97 | } 98 | return rect; 99 | } 100 | 101 | public static Rect ApplyCutoutBottom(Rect rect) 102 | { 103 | bool isPortrait = rect.height >= rect.width; 104 | if (isPortrait) 105 | { 106 | float inset = rect.height * NotchScreenProportion; 107 | rect.yMin += inset; 108 | } 109 | else 110 | { 111 | float horizontalInset = rect.width * NotchScreenProportion; 112 | rect.xMax -= horizontalInset; 113 | } 114 | return rect; 115 | } 116 | 117 | public static Rect ApplyCutoutDouble(Rect rect) 118 | { 119 | bool isPortrait = rect.height >= rect.width; 120 | if (isPortrait) 121 | { 122 | float inset = rect.height * NotchScreenProportion; 123 | rect.yMin += inset; 124 | rect.yMax -= inset; 125 | } 126 | else 127 | { 128 | float horizontalInset = rect.width * NotchScreenProportion; 129 | rect.xMin += horizontalInset; 130 | rect.xMax -= horizontalInset; 131 | } 132 | return rect; 133 | } 134 | #else 135 | public static Rect GetSafeArea() 136 | { 137 | return Screen.safeArea; 138 | } 139 | #endif 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /Runtime/SafeAreaUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 11318d092c5834f7cab0225a6eb7a7de 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Samples~/SimpleSample.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e5347a542d3e047869097588bc4bda26 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Samples~/SimpleSample/SampleScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 0 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 500 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 2 83 | m_PVRDenoiserTypeDirect: 0 84 | m_PVRDenoiserTypeIndirect: 0 85 | m_PVRDenoiserTypeAO: 0 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 0 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!1 &519420028 127 | GameObject: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | serializedVersion: 6 133 | m_Component: 134 | - component: {fileID: 519420032} 135 | - component: {fileID: 519420031} 136 | - component: {fileID: 519420029} 137 | m_Layer: 0 138 | m_Name: Main Camera 139 | m_TagString: MainCamera 140 | m_Icon: {fileID: 0} 141 | m_NavMeshLayer: 0 142 | m_StaticEditorFlags: 0 143 | m_IsActive: 1 144 | --- !u!81 &519420029 145 | AudioListener: 146 | m_ObjectHideFlags: 0 147 | m_CorrespondingSourceObject: {fileID: 0} 148 | m_PrefabInstance: {fileID: 0} 149 | m_PrefabAsset: {fileID: 0} 150 | m_GameObject: {fileID: 519420028} 151 | m_Enabled: 1 152 | --- !u!20 &519420031 153 | Camera: 154 | m_ObjectHideFlags: 0 155 | m_CorrespondingSourceObject: {fileID: 0} 156 | m_PrefabInstance: {fileID: 0} 157 | m_PrefabAsset: {fileID: 0} 158 | m_GameObject: {fileID: 519420028} 159 | m_Enabled: 1 160 | serializedVersion: 2 161 | m_ClearFlags: 2 162 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 163 | m_projectionMatrixMode: 1 164 | m_GateFitMode: 2 165 | m_FOVAxisMode: 0 166 | m_SensorSize: {x: 36, y: 24} 167 | m_LensShift: {x: 0, y: 0} 168 | m_FocalLength: 50 169 | m_NormalizedViewPortRect: 170 | serializedVersion: 2 171 | x: 0 172 | y: 0 173 | width: 1 174 | height: 1 175 | near clip plane: 0.3 176 | far clip plane: 1000 177 | field of view: 60 178 | orthographic: 1 179 | orthographic size: 5 180 | m_Depth: -1 181 | m_CullingMask: 182 | serializedVersion: 2 183 | m_Bits: 4294967295 184 | m_RenderingPath: -1 185 | m_TargetTexture: {fileID: 0} 186 | m_TargetDisplay: 0 187 | m_TargetEye: 0 188 | m_HDR: 1 189 | m_AllowMSAA: 0 190 | m_AllowDynamicResolution: 0 191 | m_ForceIntoRT: 0 192 | m_OcclusionCulling: 0 193 | m_StereoConvergence: 10 194 | m_StereoSeparation: 0.022 195 | --- !u!4 &519420032 196 | Transform: 197 | m_ObjectHideFlags: 0 198 | m_CorrespondingSourceObject: {fileID: 0} 199 | m_PrefabInstance: {fileID: 0} 200 | m_PrefabAsset: {fileID: 0} 201 | m_GameObject: {fileID: 519420028} 202 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 203 | m_LocalPosition: {x: 0, y: 0, z: -10} 204 | m_LocalScale: {x: 1, y: 1, z: 1} 205 | m_ConstrainProportionsScale: 0 206 | m_Children: [] 207 | m_Father: {fileID: 0} 208 | m_RootOrder: 0 209 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 210 | --- !u!1 &594843959 211 | GameObject: 212 | m_ObjectHideFlags: 0 213 | m_CorrespondingSourceObject: {fileID: 0} 214 | m_PrefabInstance: {fileID: 0} 215 | m_PrefabAsset: {fileID: 0} 216 | serializedVersion: 6 217 | m_Component: 218 | - component: {fileID: 594843962} 219 | - component: {fileID: 594843961} 220 | - component: {fileID: 594843960} 221 | m_Layer: 0 222 | m_Name: EventSystem 223 | m_TagString: Untagged 224 | m_Icon: {fileID: 0} 225 | m_NavMeshLayer: 0 226 | m_StaticEditorFlags: 0 227 | m_IsActive: 1 228 | --- !u!114 &594843960 229 | MonoBehaviour: 230 | m_ObjectHideFlags: 0 231 | m_CorrespondingSourceObject: {fileID: 0} 232 | m_PrefabInstance: {fileID: 0} 233 | m_PrefabAsset: {fileID: 0} 234 | m_GameObject: {fileID: 594843959} 235 | m_Enabled: 1 236 | m_EditorHideFlags: 0 237 | m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} 238 | m_Name: 239 | m_EditorClassIdentifier: 240 | m_SendPointerHoverToParent: 1 241 | m_HorizontalAxis: Horizontal 242 | m_VerticalAxis: Vertical 243 | m_SubmitButton: Submit 244 | m_CancelButton: Cancel 245 | m_InputActionsPerSecond: 10 246 | m_RepeatDelay: 0.5 247 | m_ForceModuleActive: 0 248 | --- !u!114 &594843961 249 | MonoBehaviour: 250 | m_ObjectHideFlags: 0 251 | m_CorrespondingSourceObject: {fileID: 0} 252 | m_PrefabInstance: {fileID: 0} 253 | m_PrefabAsset: {fileID: 0} 254 | m_GameObject: {fileID: 594843959} 255 | m_Enabled: 1 256 | m_EditorHideFlags: 0 257 | m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} 258 | m_Name: 259 | m_EditorClassIdentifier: 260 | m_FirstSelected: {fileID: 0} 261 | m_sendNavigationEvents: 1 262 | m_DragThreshold: 10 263 | --- !u!4 &594843962 264 | Transform: 265 | m_ObjectHideFlags: 0 266 | m_CorrespondingSourceObject: {fileID: 0} 267 | m_PrefabInstance: {fileID: 0} 268 | m_PrefabAsset: {fileID: 0} 269 | m_GameObject: {fileID: 594843959} 270 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 271 | m_LocalPosition: {x: 0, y: 0, z: 0} 272 | m_LocalScale: {x: 1, y: 1, z: 1} 273 | m_ConstrainProportionsScale: 0 274 | m_Children: [] 275 | m_Father: {fileID: 0} 276 | m_RootOrder: 2 277 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 278 | --- !u!1 &865852568 279 | GameObject: 280 | m_ObjectHideFlags: 0 281 | m_CorrespondingSourceObject: {fileID: 0} 282 | m_PrefabInstance: {fileID: 0} 283 | m_PrefabAsset: {fileID: 0} 284 | serializedVersion: 6 285 | m_Component: 286 | - component: {fileID: 865852572} 287 | - component: {fileID: 865852571} 288 | - component: {fileID: 865852570} 289 | - component: {fileID: 865852569} 290 | - component: {fileID: 865852573} 291 | m_Layer: 5 292 | m_Name: Canvas 293 | m_TagString: Untagged 294 | m_Icon: {fileID: 0} 295 | m_NavMeshLayer: 0 296 | m_StaticEditorFlags: 0 297 | m_IsActive: 1 298 | --- !u!114 &865852569 299 | MonoBehaviour: 300 | m_ObjectHideFlags: 0 301 | m_CorrespondingSourceObject: {fileID: 0} 302 | m_PrefabInstance: {fileID: 0} 303 | m_PrefabAsset: {fileID: 0} 304 | m_GameObject: {fileID: 865852568} 305 | m_Enabled: 1 306 | m_EditorHideFlags: 0 307 | m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} 308 | m_Name: 309 | m_EditorClassIdentifier: 310 | m_IgnoreReversedGraphics: 1 311 | m_BlockingObjects: 0 312 | m_BlockingMask: 313 | serializedVersion: 2 314 | m_Bits: 4294967295 315 | --- !u!114 &865852570 316 | MonoBehaviour: 317 | m_ObjectHideFlags: 0 318 | m_CorrespondingSourceObject: {fileID: 0} 319 | m_PrefabInstance: {fileID: 0} 320 | m_PrefabAsset: {fileID: 0} 321 | m_GameObject: {fileID: 865852568} 322 | m_Enabled: 1 323 | m_EditorHideFlags: 0 324 | m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} 325 | m_Name: 326 | m_EditorClassIdentifier: 327 | m_UiScaleMode: 1 328 | m_ReferencePixelsPerUnit: 100 329 | m_ScaleFactor: 1 330 | m_ReferenceResolution: {x: 1024, y: 768} 331 | m_ScreenMatchMode: 0 332 | m_MatchWidthOrHeight: 0.5 333 | m_PhysicalUnit: 3 334 | m_FallbackScreenDPI: 96 335 | m_DefaultSpriteDPI: 96 336 | m_DynamicPixelsPerUnit: 1 337 | m_PresetInfoIsWorld: 0 338 | --- !u!223 &865852571 339 | Canvas: 340 | m_ObjectHideFlags: 0 341 | m_CorrespondingSourceObject: {fileID: 0} 342 | m_PrefabInstance: {fileID: 0} 343 | m_PrefabAsset: {fileID: 0} 344 | m_GameObject: {fileID: 865852568} 345 | m_Enabled: 1 346 | serializedVersion: 3 347 | m_RenderMode: 0 348 | m_Camera: {fileID: 0} 349 | m_PlaneDistance: 100 350 | m_PixelPerfect: 0 351 | m_ReceivesEvents: 1 352 | m_OverrideSorting: 0 353 | m_OverridePixelPerfect: 0 354 | m_SortingBucketNormalizedSize: 0 355 | m_AdditionalShaderChannelsFlag: 25 356 | m_SortingLayerID: 0 357 | m_SortingOrder: 0 358 | m_TargetDisplay: 0 359 | --- !u!224 &865852572 360 | RectTransform: 361 | m_ObjectHideFlags: 0 362 | m_CorrespondingSourceObject: {fileID: 0} 363 | m_PrefabInstance: {fileID: 0} 364 | m_PrefabAsset: {fileID: 0} 365 | m_GameObject: {fileID: 865852568} 366 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 367 | m_LocalPosition: {x: 0, y: 0, z: 0} 368 | m_LocalScale: {x: 0, y: 0, z: 0} 369 | m_ConstrainProportionsScale: 0 370 | m_Children: 371 | - {fileID: 1222392002} 372 | - {fileID: 1850018549} 373 | - {fileID: 989674673} 374 | - {fileID: 1717808511} 375 | - {fileID: 2019263039} 376 | m_Father: {fileID: 0} 377 | m_RootOrder: 1 378 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 379 | m_AnchorMin: {x: 0, y: 0} 380 | m_AnchorMax: {x: 0, y: 0} 381 | m_AnchoredPosition: {x: 0, y: 0} 382 | m_SizeDelta: {x: 0, y: 0} 383 | m_Pivot: {x: 0, y: 0} 384 | --- !u!114 &865852573 385 | MonoBehaviour: 386 | m_ObjectHideFlags: 0 387 | m_CorrespondingSourceObject: {fileID: 0} 388 | m_PrefabInstance: {fileID: 0} 389 | m_PrefabAsset: {fileID: 0} 390 | m_GameObject: {fileID: 865852568} 391 | m_Enabled: 1 392 | m_EditorHideFlags: 0 393 | m_Script: {fileID: 11500000, guid: 970e6a3612105e14bbb42ae9c891cda5, type: 3} 394 | m_Name: 395 | m_EditorClassIdentifier: 396 | TopEdge: 1 397 | LeftEdge: 1 398 | RightEdge: 1 399 | BottomEdge: 1 400 | --- !u!1 &989674672 401 | GameObject: 402 | m_ObjectHideFlags: 0 403 | m_CorrespondingSourceObject: {fileID: 0} 404 | m_PrefabInstance: {fileID: 0} 405 | m_PrefabAsset: {fileID: 0} 406 | serializedVersion: 6 407 | m_Component: 408 | - component: {fileID: 989674673} 409 | - component: {fileID: 989674675} 410 | - component: {fileID: 989674674} 411 | m_Layer: 5 412 | m_Name: '[Text] Left' 413 | m_TagString: Untagged 414 | m_Icon: {fileID: 0} 415 | m_NavMeshLayer: 0 416 | m_StaticEditorFlags: 0 417 | m_IsActive: 1 418 | --- !u!224 &989674673 419 | RectTransform: 420 | m_ObjectHideFlags: 0 421 | m_CorrespondingSourceObject: {fileID: 0} 422 | m_PrefabInstance: {fileID: 0} 423 | m_PrefabAsset: {fileID: 0} 424 | m_GameObject: {fileID: 989674672} 425 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 426 | m_LocalPosition: {x: 0, y: 0, z: 0} 427 | m_LocalScale: {x: 1, y: 1, z: 1} 428 | m_ConstrainProportionsScale: 0 429 | m_Children: [] 430 | m_Father: {fileID: 865852572} 431 | m_RootOrder: 2 432 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 433 | m_AnchorMin: {x: 0, y: 0} 434 | m_AnchorMax: {x: 0, y: 1} 435 | m_AnchoredPosition: {x: 0, y: 0} 436 | m_SizeDelta: {x: 0, y: 0} 437 | m_Pivot: {x: 0.5, y: 0.5} 438 | --- !u!114 &989674674 439 | MonoBehaviour: 440 | m_ObjectHideFlags: 0 441 | m_CorrespondingSourceObject: {fileID: 0} 442 | m_PrefabInstance: {fileID: 0} 443 | m_PrefabAsset: {fileID: 0} 444 | m_GameObject: {fileID: 989674672} 445 | m_Enabled: 1 446 | m_EditorHideFlags: 0 447 | m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} 448 | m_Name: 449 | m_EditorClassIdentifier: 450 | m_Material: {fileID: 0} 451 | m_Color: {r: 1, g: 1, b: 1, a: 1} 452 | m_RaycastTarget: 1 453 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 454 | m_Maskable: 1 455 | m_OnCullStateChanged: 456 | m_PersistentCalls: 457 | m_Calls: [] 458 | m_text: LEFT 459 | m_isRightToLeft: 0 460 | m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} 461 | m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} 462 | m_fontSharedMaterials: [] 463 | m_fontMaterial: {fileID: 0} 464 | m_fontMaterials: [] 465 | m_fontColor32: 466 | serializedVersion: 2 467 | rgba: 4294967295 468 | m_fontColor: {r: 1, g: 1, b: 1, a: 1} 469 | m_enableVertexGradient: 0 470 | m_colorMode: 3 471 | m_fontColorGradient: 472 | topLeft: {r: 1, g: 1, b: 1, a: 1} 473 | topRight: {r: 1, g: 1, b: 1, a: 1} 474 | bottomLeft: {r: 1, g: 1, b: 1, a: 1} 475 | bottomRight: {r: 1, g: 1, b: 1, a: 1} 476 | m_fontColorGradientPreset: {fileID: 0} 477 | m_spriteAsset: {fileID: 0} 478 | m_tintAllSprites: 0 479 | m_StyleSheet: {fileID: 0} 480 | m_TextStyleHashCode: -1183493901 481 | m_overrideHtmlColors: 0 482 | m_faceColor: 483 | serializedVersion: 2 484 | rgba: 4294967295 485 | m_fontSize: 70 486 | m_fontSizeBase: 70 487 | m_fontWeight: 400 488 | m_enableAutoSizing: 0 489 | m_fontSizeMin: 18 490 | m_fontSizeMax: 72 491 | m_fontStyle: 0 492 | m_HorizontalAlignment: 1 493 | m_VerticalAlignment: 512 494 | m_textAlignment: 65535 495 | m_characterSpacing: 0 496 | m_wordSpacing: 0 497 | m_lineSpacing: 0 498 | m_lineSpacingMax: 0 499 | m_paragraphSpacing: 0 500 | m_charWidthMaxAdj: 0 501 | m_enableWordWrapping: 1 502 | m_wordWrappingRatios: 0.4 503 | m_overflowMode: 0 504 | m_linkedTextComponent: {fileID: 0} 505 | parentLinkedComponent: {fileID: 0} 506 | m_enableKerning: 1 507 | m_enableExtraPadding: 0 508 | checkPaddingRequired: 0 509 | m_isRichText: 1 510 | m_parseCtrlCharacters: 1 511 | m_isOrthographic: 1 512 | m_isCullingEnabled: 0 513 | m_horizontalMapping: 0 514 | m_verticalMapping: 0 515 | m_uvLineOffset: 0 516 | m_geometrySortingOrder: 0 517 | m_IsTextObjectScaleStatic: 0 518 | m_VertexBufferAutoSizeReduction: 0 519 | m_useMaxVisibleDescender: 1 520 | m_pageToDisplay: 1 521 | m_margin: {x: 0, y: 0, z: 0, w: 0} 522 | m_isUsingLegacyAnimationComponent: 0 523 | m_isVolumetricText: 0 524 | m_hasFontAssetChanged: 0 525 | m_baseMaterial: {fileID: 0} 526 | m_maskOffset: {x: 0, y: 0, z: 0, w: 0} 527 | --- !u!222 &989674675 528 | CanvasRenderer: 529 | m_ObjectHideFlags: 0 530 | m_CorrespondingSourceObject: {fileID: 0} 531 | m_PrefabInstance: {fileID: 0} 532 | m_PrefabAsset: {fileID: 0} 533 | m_GameObject: {fileID: 989674672} 534 | m_CullTransparentMesh: 1 535 | --- !u!1 &1222392001 536 | GameObject: 537 | m_ObjectHideFlags: 0 538 | m_CorrespondingSourceObject: {fileID: 0} 539 | m_PrefabInstance: {fileID: 0} 540 | m_PrefabAsset: {fileID: 0} 541 | serializedVersion: 6 542 | m_Component: 543 | - component: {fileID: 1222392002} 544 | - component: {fileID: 1222392004} 545 | - component: {fileID: 1222392003} 546 | - component: {fileID: 1222392005} 547 | m_Layer: 5 548 | m_Name: '[Image] Background' 549 | m_TagString: Untagged 550 | m_Icon: {fileID: 0} 551 | m_NavMeshLayer: 0 552 | m_StaticEditorFlags: 0 553 | m_IsActive: 1 554 | --- !u!224 &1222392002 555 | RectTransform: 556 | m_ObjectHideFlags: 0 557 | m_CorrespondingSourceObject: {fileID: 0} 558 | m_PrefabInstance: {fileID: 0} 559 | m_PrefabAsset: {fileID: 0} 560 | m_GameObject: {fileID: 1222392001} 561 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 562 | m_LocalPosition: {x: 0, y: 0, z: 0} 563 | m_LocalScale: {x: 1, y: 1, z: 1} 564 | m_ConstrainProportionsScale: 0 565 | m_Children: [] 566 | m_Father: {fileID: 865852572} 567 | m_RootOrder: 0 568 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 569 | m_AnchorMin: {x: 0, y: 0} 570 | m_AnchorMax: {x: 1, y: 1} 571 | m_AnchoredPosition: {x: 0, y: 0} 572 | m_SizeDelta: {x: 0, y: 0} 573 | m_Pivot: {x: 0.5, y: 0.5} 574 | --- !u!114 &1222392003 575 | MonoBehaviour: 576 | m_ObjectHideFlags: 0 577 | m_CorrespondingSourceObject: {fileID: 0} 578 | m_PrefabInstance: {fileID: 0} 579 | m_PrefabAsset: {fileID: 0} 580 | m_GameObject: {fileID: 1222392001} 581 | m_Enabled: 1 582 | m_EditorHideFlags: 0 583 | m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} 584 | m_Name: 585 | m_EditorClassIdentifier: 586 | m_Material: {fileID: 0} 587 | m_Color: {r: 1, g: 1, b: 1, a: 0.392} 588 | m_RaycastTarget: 1 589 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 590 | m_Maskable: 1 591 | m_OnCullStateChanged: 592 | m_PersistentCalls: 593 | m_Calls: [] 594 | m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} 595 | m_Type: 1 596 | m_PreserveAspect: 0 597 | m_FillCenter: 1 598 | m_FillMethod: 4 599 | m_FillAmount: 1 600 | m_FillClockwise: 1 601 | m_FillOrigin: 0 602 | m_UseSpriteMesh: 0 603 | m_PixelsPerUnitMultiplier: 1 604 | --- !u!222 &1222392004 605 | CanvasRenderer: 606 | m_ObjectHideFlags: 0 607 | m_CorrespondingSourceObject: {fileID: 0} 608 | m_PrefabInstance: {fileID: 0} 609 | m_PrefabAsset: {fileID: 0} 610 | m_GameObject: {fileID: 1222392001} 611 | m_CullTransparentMesh: 1 612 | --- !u!114 &1222392005 613 | MonoBehaviour: 614 | m_ObjectHideFlags: 0 615 | m_CorrespondingSourceObject: {fileID: 0} 616 | m_PrefabInstance: {fileID: 0} 617 | m_PrefabAsset: {fileID: 0} 618 | m_GameObject: {fileID: 1222392001} 619 | m_Enabled: 1 620 | m_EditorHideFlags: 0 621 | m_Script: {fileID: 11500000, guid: df8b0765def604e77b929b38a87f10a1, type: 3} 622 | m_Name: 623 | m_EditorClassIdentifier: 624 | --- !u!1 &1717808510 625 | GameObject: 626 | m_ObjectHideFlags: 0 627 | m_CorrespondingSourceObject: {fileID: 0} 628 | m_PrefabInstance: {fileID: 0} 629 | m_PrefabAsset: {fileID: 0} 630 | serializedVersion: 6 631 | m_Component: 632 | - component: {fileID: 1717808511} 633 | - component: {fileID: 1717808513} 634 | - component: {fileID: 1717808512} 635 | m_Layer: 5 636 | m_Name: '[Text] Right' 637 | m_TagString: Untagged 638 | m_Icon: {fileID: 0} 639 | m_NavMeshLayer: 0 640 | m_StaticEditorFlags: 0 641 | m_IsActive: 1 642 | --- !u!224 &1717808511 643 | RectTransform: 644 | m_ObjectHideFlags: 0 645 | m_CorrespondingSourceObject: {fileID: 0} 646 | m_PrefabInstance: {fileID: 0} 647 | m_PrefabAsset: {fileID: 0} 648 | m_GameObject: {fileID: 1717808510} 649 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 650 | m_LocalPosition: {x: 0, y: 0, z: 0} 651 | m_LocalScale: {x: 1, y: 1, z: 1} 652 | m_ConstrainProportionsScale: 0 653 | m_Children: [] 654 | m_Father: {fileID: 865852572} 655 | m_RootOrder: 3 656 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 657 | m_AnchorMin: {x: 1, y: 0} 658 | m_AnchorMax: {x: 1, y: 1} 659 | m_AnchoredPosition: {x: 0, y: 0} 660 | m_SizeDelta: {x: 0, y: 0} 661 | m_Pivot: {x: 0.5, y: 0.5} 662 | --- !u!114 &1717808512 663 | MonoBehaviour: 664 | m_ObjectHideFlags: 0 665 | m_CorrespondingSourceObject: {fileID: 0} 666 | m_PrefabInstance: {fileID: 0} 667 | m_PrefabAsset: {fileID: 0} 668 | m_GameObject: {fileID: 1717808510} 669 | m_Enabled: 1 670 | m_EditorHideFlags: 0 671 | m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} 672 | m_Name: 673 | m_EditorClassIdentifier: 674 | m_Material: {fileID: 0} 675 | m_Color: {r: 1, g: 1, b: 1, a: 1} 676 | m_RaycastTarget: 1 677 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 678 | m_Maskable: 1 679 | m_OnCullStateChanged: 680 | m_PersistentCalls: 681 | m_Calls: [] 682 | m_text: RIGHT 683 | m_isRightToLeft: 0 684 | m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} 685 | m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} 686 | m_fontSharedMaterials: [] 687 | m_fontMaterial: {fileID: 0} 688 | m_fontMaterials: [] 689 | m_fontColor32: 690 | serializedVersion: 2 691 | rgba: 4294967295 692 | m_fontColor: {r: 1, g: 1, b: 1, a: 1} 693 | m_enableVertexGradient: 0 694 | m_colorMode: 3 695 | m_fontColorGradient: 696 | topLeft: {r: 1, g: 1, b: 1, a: 1} 697 | topRight: {r: 1, g: 1, b: 1, a: 1} 698 | bottomLeft: {r: 1, g: 1, b: 1, a: 1} 699 | bottomRight: {r: 1, g: 1, b: 1, a: 1} 700 | m_fontColorGradientPreset: {fileID: 0} 701 | m_spriteAsset: {fileID: 0} 702 | m_tintAllSprites: 0 703 | m_StyleSheet: {fileID: 0} 704 | m_TextStyleHashCode: -1183493901 705 | m_overrideHtmlColors: 0 706 | m_faceColor: 707 | serializedVersion: 2 708 | rgba: 4294967295 709 | m_fontSize: 70 710 | m_fontSizeBase: 70 711 | m_fontWeight: 400 712 | m_enableAutoSizing: 0 713 | m_fontSizeMin: 18 714 | m_fontSizeMax: 72 715 | m_fontStyle: 0 716 | m_HorizontalAlignment: 4 717 | m_VerticalAlignment: 512 718 | m_textAlignment: 65535 719 | m_characterSpacing: 0 720 | m_wordSpacing: 0 721 | m_lineSpacing: 0 722 | m_lineSpacingMax: 0 723 | m_paragraphSpacing: 0 724 | m_charWidthMaxAdj: 0 725 | m_enableWordWrapping: 1 726 | m_wordWrappingRatios: 0.4 727 | m_overflowMode: 0 728 | m_linkedTextComponent: {fileID: 0} 729 | parentLinkedComponent: {fileID: 0} 730 | m_enableKerning: 1 731 | m_enableExtraPadding: 0 732 | checkPaddingRequired: 0 733 | m_isRichText: 1 734 | m_parseCtrlCharacters: 1 735 | m_isOrthographic: 1 736 | m_isCullingEnabled: 0 737 | m_horizontalMapping: 0 738 | m_verticalMapping: 0 739 | m_uvLineOffset: 0 740 | m_geometrySortingOrder: 0 741 | m_IsTextObjectScaleStatic: 0 742 | m_VertexBufferAutoSizeReduction: 0 743 | m_useMaxVisibleDescender: 1 744 | m_pageToDisplay: 1 745 | m_margin: {x: 0, y: 0, z: 0, w: 0} 746 | m_isUsingLegacyAnimationComponent: 0 747 | m_isVolumetricText: 0 748 | m_hasFontAssetChanged: 0 749 | m_baseMaterial: {fileID: 0} 750 | m_maskOffset: {x: 0, y: 0, z: 0, w: 0} 751 | --- !u!222 &1717808513 752 | CanvasRenderer: 753 | m_ObjectHideFlags: 0 754 | m_CorrespondingSourceObject: {fileID: 0} 755 | m_PrefabInstance: {fileID: 0} 756 | m_PrefabAsset: {fileID: 0} 757 | m_GameObject: {fileID: 1717808510} 758 | m_CullTransparentMesh: 1 759 | --- !u!1 &1850018548 760 | GameObject: 761 | m_ObjectHideFlags: 0 762 | m_CorrespondingSourceObject: {fileID: 0} 763 | m_PrefabInstance: {fileID: 0} 764 | m_PrefabAsset: {fileID: 0} 765 | serializedVersion: 6 766 | m_Component: 767 | - component: {fileID: 1850018549} 768 | - component: {fileID: 1850018551} 769 | - component: {fileID: 1850018550} 770 | m_Layer: 5 771 | m_Name: '[Text] Top' 772 | m_TagString: Untagged 773 | m_Icon: {fileID: 0} 774 | m_NavMeshLayer: 0 775 | m_StaticEditorFlags: 0 776 | m_IsActive: 1 777 | --- !u!224 &1850018549 778 | RectTransform: 779 | m_ObjectHideFlags: 0 780 | m_CorrespondingSourceObject: {fileID: 0} 781 | m_PrefabInstance: {fileID: 0} 782 | m_PrefabAsset: {fileID: 0} 783 | m_GameObject: {fileID: 1850018548} 784 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 785 | m_LocalPosition: {x: 0, y: 0, z: 0} 786 | m_LocalScale: {x: 1, y: 1, z: 1} 787 | m_ConstrainProportionsScale: 0 788 | m_Children: [] 789 | m_Father: {fileID: 865852572} 790 | m_RootOrder: 1 791 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 792 | m_AnchorMin: {x: 0, y: 1} 793 | m_AnchorMax: {x: 1, y: 1} 794 | m_AnchoredPosition: {x: 0, y: 0} 795 | m_SizeDelta: {x: 0, y: 0} 796 | m_Pivot: {x: 0.5, y: 0.5} 797 | --- !u!114 &1850018550 798 | MonoBehaviour: 799 | m_ObjectHideFlags: 0 800 | m_CorrespondingSourceObject: {fileID: 0} 801 | m_PrefabInstance: {fileID: 0} 802 | m_PrefabAsset: {fileID: 0} 803 | m_GameObject: {fileID: 1850018548} 804 | m_Enabled: 1 805 | m_EditorHideFlags: 0 806 | m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} 807 | m_Name: 808 | m_EditorClassIdentifier: 809 | m_Material: {fileID: 0} 810 | m_Color: {r: 1, g: 1, b: 1, a: 1} 811 | m_RaycastTarget: 1 812 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 813 | m_Maskable: 1 814 | m_OnCullStateChanged: 815 | m_PersistentCalls: 816 | m_Calls: [] 817 | m_text: TOP 818 | m_isRightToLeft: 0 819 | m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} 820 | m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} 821 | m_fontSharedMaterials: [] 822 | m_fontMaterial: {fileID: 0} 823 | m_fontMaterials: [] 824 | m_fontColor32: 825 | serializedVersion: 2 826 | rgba: 4294967295 827 | m_fontColor: {r: 1, g: 1, b: 1, a: 1} 828 | m_enableVertexGradient: 0 829 | m_colorMode: 3 830 | m_fontColorGradient: 831 | topLeft: {r: 1, g: 1, b: 1, a: 1} 832 | topRight: {r: 1, g: 1, b: 1, a: 1} 833 | bottomLeft: {r: 1, g: 1, b: 1, a: 1} 834 | bottomRight: {r: 1, g: 1, b: 1, a: 1} 835 | m_fontColorGradientPreset: {fileID: 0} 836 | m_spriteAsset: {fileID: 0} 837 | m_tintAllSprites: 0 838 | m_StyleSheet: {fileID: 0} 839 | m_TextStyleHashCode: -1183493901 840 | m_overrideHtmlColors: 0 841 | m_faceColor: 842 | serializedVersion: 2 843 | rgba: 4294967295 844 | m_fontSize: 70 845 | m_fontSizeBase: 70 846 | m_fontWeight: 400 847 | m_enableAutoSizing: 0 848 | m_fontSizeMin: 18 849 | m_fontSizeMax: 72 850 | m_fontStyle: 0 851 | m_HorizontalAlignment: 2 852 | m_VerticalAlignment: 256 853 | m_textAlignment: 65535 854 | m_characterSpacing: 0 855 | m_wordSpacing: 0 856 | m_lineSpacing: 0 857 | m_lineSpacingMax: 0 858 | m_paragraphSpacing: 0 859 | m_charWidthMaxAdj: 0 860 | m_enableWordWrapping: 1 861 | m_wordWrappingRatios: 0.4 862 | m_overflowMode: 0 863 | m_linkedTextComponent: {fileID: 0} 864 | parentLinkedComponent: {fileID: 0} 865 | m_enableKerning: 1 866 | m_enableExtraPadding: 0 867 | checkPaddingRequired: 0 868 | m_isRichText: 1 869 | m_parseCtrlCharacters: 1 870 | m_isOrthographic: 1 871 | m_isCullingEnabled: 0 872 | m_horizontalMapping: 0 873 | m_verticalMapping: 0 874 | m_uvLineOffset: 0 875 | m_geometrySortingOrder: 0 876 | m_IsTextObjectScaleStatic: 0 877 | m_VertexBufferAutoSizeReduction: 0 878 | m_useMaxVisibleDescender: 1 879 | m_pageToDisplay: 1 880 | m_margin: {x: 0, y: 0, z: 0, w: 0} 881 | m_isUsingLegacyAnimationComponent: 0 882 | m_isVolumetricText: 0 883 | m_hasFontAssetChanged: 0 884 | m_baseMaterial: {fileID: 0} 885 | m_maskOffset: {x: 0, y: 0, z: 0, w: 0} 886 | --- !u!222 &1850018551 887 | CanvasRenderer: 888 | m_ObjectHideFlags: 0 889 | m_CorrespondingSourceObject: {fileID: 0} 890 | m_PrefabInstance: {fileID: 0} 891 | m_PrefabAsset: {fileID: 0} 892 | m_GameObject: {fileID: 1850018548} 893 | m_CullTransparentMesh: 1 894 | --- !u!1 &2019263038 895 | GameObject: 896 | m_ObjectHideFlags: 0 897 | m_CorrespondingSourceObject: {fileID: 0} 898 | m_PrefabInstance: {fileID: 0} 899 | m_PrefabAsset: {fileID: 0} 900 | serializedVersion: 6 901 | m_Component: 902 | - component: {fileID: 2019263039} 903 | - component: {fileID: 2019263041} 904 | - component: {fileID: 2019263040} 905 | m_Layer: 5 906 | m_Name: '[Text] Bottom' 907 | m_TagString: Untagged 908 | m_Icon: {fileID: 0} 909 | m_NavMeshLayer: 0 910 | m_StaticEditorFlags: 0 911 | m_IsActive: 1 912 | --- !u!224 &2019263039 913 | RectTransform: 914 | m_ObjectHideFlags: 0 915 | m_CorrespondingSourceObject: {fileID: 0} 916 | m_PrefabInstance: {fileID: 0} 917 | m_PrefabAsset: {fileID: 0} 918 | m_GameObject: {fileID: 2019263038} 919 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 920 | m_LocalPosition: {x: 0, y: 0, z: 0} 921 | m_LocalScale: {x: 1, y: 1, z: 1} 922 | m_ConstrainProportionsScale: 0 923 | m_Children: [] 924 | m_Father: {fileID: 865852572} 925 | m_RootOrder: 4 926 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 927 | m_AnchorMin: {x: 0, y: 0} 928 | m_AnchorMax: {x: 1, y: 0} 929 | m_AnchoredPosition: {x: 0, y: 0} 930 | m_SizeDelta: {x: 0, y: 0} 931 | m_Pivot: {x: 0.5, y: 0.5} 932 | --- !u!114 &2019263040 933 | MonoBehaviour: 934 | m_ObjectHideFlags: 0 935 | m_CorrespondingSourceObject: {fileID: 0} 936 | m_PrefabInstance: {fileID: 0} 937 | m_PrefabAsset: {fileID: 0} 938 | m_GameObject: {fileID: 2019263038} 939 | m_Enabled: 1 940 | m_EditorHideFlags: 0 941 | m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} 942 | m_Name: 943 | m_EditorClassIdentifier: 944 | m_Material: {fileID: 0} 945 | m_Color: {r: 1, g: 1, b: 1, a: 1} 946 | m_RaycastTarget: 1 947 | m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} 948 | m_Maskable: 1 949 | m_OnCullStateChanged: 950 | m_PersistentCalls: 951 | m_Calls: [] 952 | m_text: BOTTOM 953 | m_isRightToLeft: 0 954 | m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} 955 | m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} 956 | m_fontSharedMaterials: [] 957 | m_fontMaterial: {fileID: 0} 958 | m_fontMaterials: [] 959 | m_fontColor32: 960 | serializedVersion: 2 961 | rgba: 4294967295 962 | m_fontColor: {r: 1, g: 1, b: 1, a: 1} 963 | m_enableVertexGradient: 0 964 | m_colorMode: 3 965 | m_fontColorGradient: 966 | topLeft: {r: 1, g: 1, b: 1, a: 1} 967 | topRight: {r: 1, g: 1, b: 1, a: 1} 968 | bottomLeft: {r: 1, g: 1, b: 1, a: 1} 969 | bottomRight: {r: 1, g: 1, b: 1, a: 1} 970 | m_fontColorGradientPreset: {fileID: 0} 971 | m_spriteAsset: {fileID: 0} 972 | m_tintAllSprites: 0 973 | m_StyleSheet: {fileID: 0} 974 | m_TextStyleHashCode: -1183493901 975 | m_overrideHtmlColors: 0 976 | m_faceColor: 977 | serializedVersion: 2 978 | rgba: 4294967295 979 | m_fontSize: 70 980 | m_fontSizeBase: 70 981 | m_fontWeight: 400 982 | m_enableAutoSizing: 0 983 | m_fontSizeMin: 18 984 | m_fontSizeMax: 72 985 | m_fontStyle: 0 986 | m_HorizontalAlignment: 2 987 | m_VerticalAlignment: 1024 988 | m_textAlignment: 65535 989 | m_characterSpacing: 0 990 | m_wordSpacing: 0 991 | m_lineSpacing: 0 992 | m_lineSpacingMax: 0 993 | m_paragraphSpacing: 0 994 | m_charWidthMaxAdj: 0 995 | m_enableWordWrapping: 1 996 | m_wordWrappingRatios: 0.4 997 | m_overflowMode: 0 998 | m_linkedTextComponent: {fileID: 0} 999 | parentLinkedComponent: {fileID: 0} 1000 | m_enableKerning: 1 1001 | m_enableExtraPadding: 0 1002 | checkPaddingRequired: 0 1003 | m_isRichText: 1 1004 | m_parseCtrlCharacters: 1 1005 | m_isOrthographic: 1 1006 | m_isCullingEnabled: 0 1007 | m_horizontalMapping: 0 1008 | m_verticalMapping: 0 1009 | m_uvLineOffset: 0 1010 | m_geometrySortingOrder: 0 1011 | m_IsTextObjectScaleStatic: 0 1012 | m_VertexBufferAutoSizeReduction: 0 1013 | m_useMaxVisibleDescender: 1 1014 | m_pageToDisplay: 1 1015 | m_margin: {x: 0, y: 0, z: 0, w: 0} 1016 | m_isUsingLegacyAnimationComponent: 0 1017 | m_isVolumetricText: 0 1018 | m_hasFontAssetChanged: 0 1019 | m_baseMaterial: {fileID: 0} 1020 | m_maskOffset: {x: 0, y: 0, z: 0, w: 0} 1021 | --- !u!222 &2019263041 1022 | CanvasRenderer: 1023 | m_ObjectHideFlags: 0 1024 | m_CorrespondingSourceObject: {fileID: 0} 1025 | m_PrefabInstance: {fileID: 0} 1026 | m_PrefabAsset: {fileID: 0} 1027 | m_GameObject: {fileID: 2019263038} 1028 | m_CullTransparentMesh: 1 1029 | -------------------------------------------------------------------------------- /Samples~/SimpleSample/SampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2cda990e2423bbf4892e6590ba056729 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /UNLICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2cdd84b35c6bc0d47889eb510bd1c686 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.gilzoide.safe-area-layout", 3 | "displayName": "Safe Area Layout", 4 | "version": "1.0.2", 5 | "description": "uGUI layout group for respecting the Safe Area, supports children's LayoutElement.ignoreLayout\n\nJust add the SafeAreaLayoutGroup script anywhere in your UI hierarchy (even to objects with Canvases) and children's anchors will be adjusted to be within the Safe Area. Optionally, add IgnoreSafeArea components to children for them to be ignored from Safe Area adjustments.", 6 | "homepage": "https://github.com/gilzoide/unity-safe-area-layout", 7 | "author": { 8 | "name": "Gil Barbosa Reis" 9 | }, 10 | "unity": "2017.2", 11 | "samples": [ 12 | { 13 | "displayName": "Simple Sample", 14 | "description": "Simple sample with a background image and text labels in each edge of the screen", 15 | "path": "Samples~/SimpleSample" 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 36a1a3a11a879ec4184659a1fc848fb5 3 | PackageManifestImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | --------------------------------------------------------------------------------