using System;
using UnityEngine.Playables;
using UnityEngine.UI;
namespace UnityEngine.Sequences.Timeline
{
// Note: The documentation XML are added only to remove warning when validating the package until this class
// can be made private. In the meantime, it is explicitly excluded from the documentation, see
// Documentation > filter.yml
///
/// Contains the logic for displaying and scaling the image to the screen size.
///
class StoryboardPlayableBehaviour : PlayableBehaviour
{
Texture m_Board = null;
///
///
///
public Texture board
{
set => m_Board = value;
}
bool m_ShowBoard = true;
///
///
///
public bool showBoard
{
set => m_ShowBoard = value;
}
Vector2 m_Position = Vector2.zero;
///
///
///
public Vector2 position
{
set => m_Position = value;
}
float m_Alpha = 1;
///
///
///
public float alpha
{
set => m_Alpha = value;
}
Vector3 m_Rotation = Vector3.zero;
///
///
///
public Vector3 rotation
{
set => m_Rotation = value;
}
Vector2 m_Scale = Vector2.one;
///
///
///
public Vector2 scale
{
set => m_Scale = value;
}
Canvas m_Canvas;
///
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
ScriptPlayable outputPlayable =
(ScriptPlayable)playable.GetOutput(0);
var outputPlayableBehaviour = outputPlayable.GetBehaviour();
m_Canvas = outputPlayableBehaviour.canvas;
if (m_Canvas == null || m_Board == null || !m_ShowBoard) return;
if (m_Canvas.transform.childCount == 0)
{
// if the board isn't loaded, load it
var boardGo = new GameObject(m_Board.name);
boardGo.hideFlags = HideFlags.HideAndDontSave;
boardGo.transform.parent = m_Canvas.transform;
boardGo.transform.localPosition = m_Position;
boardGo.transform.localScale = GetBestFitScale();
var currentBoard = boardGo.AddComponent();
currentBoard.texture = m_Board;
// Using SetNativeSize because otherwise textures are resized to 100x100 by default
currentBoard.SetNativeSize();
var color = Color.white;
color.a = m_Alpha;
currentBoard.color = color;
currentBoard.transform.rotation = Quaternion.Euler(m_Rotation);
}
else
{
// there is a board, rescale it & adjust rotation
var child = m_Canvas.transform.GetChild(0);
child.localScale = GetBestFitScale();
child.rotation = Quaternion.Euler(m_Rotation);
}
}
///
/// Calculates how much a board needs to be scaled in order to fit to the size of the current GameView
/// Uses BestFit (does not affect original aspect ratio of the image)
///
/// Vector2 that indicates how much to scale the orginial image to fit the GameView
Vector2 GetBestFitScale()
{
// TODO: investigate how to get it to scale with Gameview size and aspect ratio changes
Rect screen = new Rect((float)Screen.width / 2, (float)Screen.height / 2, Screen.width, Screen.height);
Vector2 reScale = Vector2.one;
if (m_Board != null
&& m_Board.width > 0 && m_Board.height > 0
&& screen.width > 0 && screen.height > 0)
{
// Fits the image to the size of the GameView without altering the aspect ratio
float bestFitScale = Math.Min(screen.height / m_Board.height, screen.width / m_Board.width);
reScale *= bestFitScale;
}
reScale.x *= m_Scale.x;
reScale.y *= m_Scale.y;
return reScale;
}
///
/// When the playhead leaves the clip, remove the board from the canvas
public override void OnBehaviourPause(Playable playable, FrameData info)
{
if (m_Canvas == null) return;
if (m_Canvas.transform.childCount <= 0) return;
var child = m_Canvas.transform.GetChild(0);
child.SetParent(null);
#if UNITY_EDITOR
Object.DestroyImmediate(child.gameObject);
#else
Object.Destroy(child.gameObject);
#endif
}
}
}