using UnityEngine; using UnityEngine.Playables; namespace E7.NotchSolution { /// /// /// Adapt anything according to how much a screen space was taken by a single side of safe area. /// /// /// It uses Playables API and animation playables to blend between the first frame /// of 2 , which represent normal state and fully-adapted state. /// As long as something is keyable by the animation system, it could be adapted to the safe area. /// /// /// /// /// Blend amount is 0 ~ 1, calculated from 0 ~ 1 relative screen space taken of a single side that is then /// evaluated through configurable . /// /// /// By using animation system, the modification won't count as dirtying the scene which is great /// when you want to switching the simulator on and off just to observe its effect. /// /// /// Animator is needed for its field binding power but no need for the controller asset, /// because we don't need the costly state machine, just like how works with /// animation playables. /// /// /// However since Unity can't design on /// the Animation pane without with controllers, you may need to temporarily /// add a controller when you are making the clip + add clips as some states in the animation graph, /// then remove the controller once you finished making the clip... /// /// /// At runtime it only take effect on Start, since safe area is not expected to change dynamically, /// and unlike uGUI layout system + , a frequent recalculation is not expected. /// Call if you wish to apply the adaptation manually again. /// /// /// In edit mode, it also apply on notch simulator update. So it is almost like the adaptation always lock your fields. /// In real play it is possible to adjust these adapted fields later freely since it's only on Start. /// /// [HelpURL("https://exceed7.com/notch-solution/components/adaptation/safe-adaptation.html")] public class SafeAdaptation : AdaptationBase { //Currently I think iPhone X has the largest notch, so this should be a good default upper bound of blend value. private const float iPhoneXNotchHeightRelative = 0.05418718f; #if UNITY_EDITOR public float latestSimulatedSpaceTakenRelative; #endif private void Reset() { ResetAdaptationToCurve(AnimationCurve.Linear(0, 0, iPhoneXNotchHeightRelative, 1)); } /// /// At runtime only take effect on `Start`, since safe area is not expected to change dynamically, /// and unlike uGUI and a frequent recalculation is not expected. /// This method applies that adaptation manually again. /// public override void Adapt() { AdaptWithRelativeSafeArea(SafeAreaRelative); } private void AdaptWithRelativeSafeArea(Rect relativeSafeArea) { float spaceTakenRelative = 0; if (evaluationMode != EdgeEvaluationMode.Off) { switch (adaptToEdge) { case RectTransform.Edge.Left: spaceTakenRelative = relativeSafeArea.xMin; break; case RectTransform.Edge.Right: spaceTakenRelative = 1 - relativeSafeArea.xMax; break; case RectTransform.Edge.Top: spaceTakenRelative = 1 - relativeSafeArea.yMax; break; case RectTransform.Edge.Bottom: spaceTakenRelative = relativeSafeArea.yMin; break; } if (evaluationMode == EdgeEvaluationMode.Balanced) { switch (adaptToEdge) { case RectTransform.Edge.Left: spaceTakenRelative = Mathf.Max(spaceTakenRelative, 1 - relativeSafeArea.xMax); break; case RectTransform.Edge.Right: spaceTakenRelative = Mathf.Max(spaceTakenRelative, relativeSafeArea.xMin); break; case RectTransform.Edge.Top: spaceTakenRelative = Mathf.Max(spaceTakenRelative, relativeSafeArea.yMin); break; case RectTransform.Edge.Bottom: spaceTakenRelative = Mathf.Max(spaceTakenRelative, 1 - relativeSafeArea.yMax); break; } } } #if UNITY_EDITOR latestSimulatedSpaceTakenRelative = spaceTakenRelative; #endif base.Adapt(spaceTakenRelative); //Debug.Log($"Evaluated! Got blend {blend} from {spaceTakenRelative} space taken (Relative safe area {relativeSafeArea.xMin} {relativeSafeArea.xMax} {relativeSafeArea.yMin} {relativeSafeArea.yMax})"); } #pragma warning disable 0649 [SerializeField] private RectTransform.Edge adaptToEdge; [SerializeField] private EdgeEvaluationMode evaluationMode; #pragma warning restore 0649 } }