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
}
}