using System.Collections; using System.Collections.Generic; using AibisDream.FrameAnimation.Timeline; using NUnit.Framework; using UnityEngine; using UnityEngine.Playables; using UnityEngine.TestTools; using UnityEngine.Timeline; namespace AibisDream.FrameAnimation.Tests.PlayMode { public sealed class FrameAnimationTimelinePlayModeTests { private readonly List createdObjects = new List(); [TearDown] public void TearDown() { for (var index = createdObjects.Count - 1; index >= 0; index--) { if (createdObjects[index] != null) UnityEngine.Object.DestroyImmediate(createdObjects[index]); } createdObjects.Clear(); } [UnityTest] public IEnumerator Director_TakesControlSupportsSeekAndReleasesPlayer() { var first = CreateSprite(Color.red); var second = CreateSprite(Color.blue); var clip = CreateClip(first, second); var playerObject = Track(new GameObject("Timeline Player")); var renderer = playerObject.AddComponent(); var player = playerObject.AddComponent(); player.ConfigureForAuthoring(clip, false, 1f); var ordinaryHandle = player.Play(); var setup = CreateTimeline(player, clip); setup.Director.Play(); setup.Director.time = 0.15d; setup.Director.Evaluate(); yield return null; Assert.That(ordinaryHandle.Result.Reason, Is.EqualTo(FrameAnimationCompletionReason.Replaced)); Assert.That(renderer.sprite, Is.SameAs(second)); setup.Director.time = 0.01d; setup.Director.Evaluate(); Assert.That(renderer.sprite, Is.SameAs(first)); setup.Director.Stop(); var nextHandle = player.Play(); Assert.That(nextHandle.IsCompleted, Is.False); Assert.That(renderer.sprite, Is.SameAs(first)); } private TimelineSetup CreateTimeline(FrameClipPlayer player, FrameClip clip) { var timeline = Track(ScriptableObject.CreateInstance()); var track = Track(timeline.CreateTrack()); var timelineClip = track.CreateClip(); var asset = Track((FrameAnimationTimelineClip)timelineClip.asset); asset.SetFrameClipForTests(clip); timelineClip.duration = asset.duration; var directorObject = Track(new GameObject("Timeline Director")); var director = directorObject.AddComponent(); director.playableAsset = timeline; director.SetGenericBinding(track, player); return new TimelineSetup(director); } private FrameClip CreateClip(params Sprite[] sprites) { var clip = Track(ScriptableObject.CreateInstance()); var frames = new List(); for (var index = 0; index < sprites.Length; index++) { frames.Add(new FrameAnimationFrame( sprites[index], 100, $"frame_{index}", index)); } clip.Configure( "Timeline", "Timeline", frames, 1f, FrameClipEndBehavior.HoldLastFrame); return clip; } private Sprite CreateSprite(Color color) { var texture = Track(new Texture2D(2, 2)); texture.SetPixels(new[] { color, color, color, color }); texture.Apply(); return Track(Sprite.Create( texture, new Rect(0, 0, 2, 2), Vector2.one * 0.5f)); } private T Track(T value) where T : UnityEngine.Object { createdObjects.Add(value); return value; } private readonly struct TimelineSetup { internal TimelineSetup(PlayableDirector director) { Director = director; } internal PlayableDirector Director { get; } } } }