using UnityEngine; namespace E7.NotchSolution { /// /// A base class which use the first frame of 2 , and a blend value, /// to control an with Playables API once on `Start()`. /// Those information are all in serialized together with this class. /// /// /// You can create other kinds of adaptation component by subclassing this. /// [ExecuteAlways] [RequireComponent(typeof(Animator))] public abstract class AdaptationBase : MonoBehaviour, INotchSimulatorTarget { private Rect[] storedSimulatedCutoutsRelative = NotchSolutionUtility.defaultCutouts; private Rect storedSimulatedSafeAreaRelative = NotchSolutionUtility.defaultSafeArea; private BlendedClipsAdaptor SelectedAdaptation => supportedOrientations == SupportedOrientations.Dual ? NotchSolutionUtility.GetCurrentOrientation() == ScreenOrientation.Landscape ? landscapeAdaptation : portraitOrDefaultAdaptation : portraitOrDefaultAdaptation; private Animator AnimatorComponent => GetComponent(); /// /// Provide safe area in 0~1 value related to the screen size, /// already taken account of simulated or runtime value. /// protected Rect SafeAreaRelative => NotchSolutionUtility.ShouldUseNotchSimulatorValue ? storedSimulatedSafeAreaRelative : NotchSolutionUtility.ScreenSafeAreaRelative; private void Start() { Adapt(); } private void Update() { if (Application.isPlaying == false) { Adapt(); } } void INotchSimulatorTarget.SimulatorUpdate(Rect simulatedSafeAreaRelative, Rect[] simulatedCutoutsRelative) { storedSimulatedSafeAreaRelative = simulatedSafeAreaRelative; storedSimulatedCutoutsRelative = simulatedCutoutsRelative; Adapt(); } /// /// Make the adaptation curve reset to the specified . /// private protected void ResetAdaptationToCurve(AnimationCurve curve) { portraitOrDefaultAdaptation = new BlendedClipsAdaptor(curve); landscapeAdaptation = new BlendedClipsAdaptor(curve); } /// /// Drive with playable graph, based on a blend /// between the first frame of 2 . /// /// /// Adaptation curve evaluates this value into a 0-1 blend between 2 clips. /// protected void Adapt(float valueForAdaptationCurve) { SelectedAdaptation.Adapt(valueForAdaptationCurve, AnimatorComponent); } /// /// Any adaptation component will be "adapted" only once on Start(), but /// this call could make that happen again on-demand. /// /// /// This should ended up calling somehow in the implementation. /// public abstract void Adapt(); #pragma warning disable 0649 [SerializeField] private SupportedOrientations supportedOrientations; /// /// Holds 2 that will be used when the game has one possible orientation, /// or portrait orientation when the game could handle both portrait and landscape orientation. /// [Space] [SerializeField] private BlendedClipsAdaptor portraitOrDefaultAdaptation; /// /// Holds 2 that will be used when in landscape orientation /// when the game could handle both portrait and landscape orientation. /// [SerializeField] private BlendedClipsAdaptor landscapeAdaptation; #pragma warning restore 0649 #if UNITY_EDITOR internal void AssignAdaptationClips(AnimationClip normalState, AnimationClip adaptedState, bool forPortrait) { var bca = forPortrait ? portraitOrDefaultAdaptation : landscapeAdaptation; bca.AssignAdaptationClips(normalState, adaptedState); } /// /// Check if both clips are nested on the same controller asset or not. /// internal bool TryGetLinkedControllerAsset(bool forPortrait, out RuntimeAnimatorController controllerAsset) { var bca = forPortrait ? portraitOrDefaultAdaptation : landscapeAdaptation; return bca.TryGetLinkedControllerAsset(out controllerAsset); } internal bool IsAdaptable(bool forPortrait) { var bca = forPortrait ? portraitOrDefaultAdaptation : landscapeAdaptation; return bca.Adaptable; } #endif } }