Files
aibis-dream/Assets/Tests/FrameAnimation/PlayMode/FrameAnimationTimelinePlayModeTests.cs
T

145 lines
5.6 KiB
C#

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<UnityEngine.Object> createdObjects = new List<UnityEngine.Object>();
[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_TakesControlStopsAtTerminalAndPlayerCanPlayAgain()
{
var first = CreateSprite(Color.red);
var second = CreateSprite(Color.blue);
var clip = CreateClip("Timeline", FrameClipEndBehavior.HoldLastFrame, first, second);
var playerObject = Track(new GameObject("Timeline Runtime Player"));
var renderer = playerObject.AddComponent<SpriteRenderer>();
var player = playerObject.AddComponent<FrameClipPlayer>();
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.IsCompleted, Is.True);
Assert.That(ordinaryHandle.Result.Reason, Is.EqualTo(FrameAnimationCompletionReason.Replaced));
Assert.That(renderer.sprite, Is.SameAs(second));
setup.Director.Stop();
Assert.That(renderer.sprite, Is.SameAs(second));
var nextHandle = player.Play();
Assert.That(nextHandle.IsCompleted, Is.False);
Assert.That(renderer.sprite, Is.SameAs(first));
}
[UnityTest]
public IEnumerator Director_CanPauseSeekBackwardAndReplayLoop()
{
var first = CreateSprite(Color.green);
var second = CreateSprite(Color.yellow);
var clip = CreateClip("Loop", FrameClipEndBehavior.Loop, first, second);
var playerObject = Track(new GameObject("Timeline Runtime Loop"));
var renderer = playerObject.AddComponent<SpriteRenderer>();
var player = playerObject.AddComponent<FrameClipPlayer>();
var setup = CreateTimeline(player, clip);
setup.Clip.duration = 0.6d;
setup.Director.Play();
setup.Director.time = 0.15d;
setup.Director.Evaluate();
setup.Director.Pause();
Assert.That(renderer.sprite, Is.SameAs(second));
setup.Director.time = 0.01d;
setup.Director.Evaluate();
Assert.That(renderer.sprite, Is.SameAs(first));
setup.Director.Play();
setup.Director.time = 0.25d;
setup.Director.Evaluate();
yield return null;
Assert.That(renderer.sprite, Is.SameAs(first));
setup.Director.Stop();
Assert.That(renderer.sprite, Is.Not.Null);
}
private TimelineSetup CreateTimeline(FrameClipPlayer player, FrameClip clip)
{
var timeline = Track(ScriptableObject.CreateInstance<TimelineAsset>());
var track = Track(timeline.CreateTrack<FrameAnimationTrack>());
var timelineClip = track.CreateClip<FrameAnimationTimelineClip>();
var asset = Track((FrameAnimationTimelineClip)timelineClip.asset);
asset.SetFrameClipForTests(clip);
timelineClip.start = 0d;
timelineClip.duration = asset.duration;
var directorObject = Track(new GameObject("Frame Animation Runtime Director"));
var director = directorObject.AddComponent<PlayableDirector>();
director.playableAsset = timeline;
director.SetGenericBinding(track, player);
return new TimelineSetup(director, timelineClip);
}
private FrameClip CreateClip(string id, FrameClipEndBehavior endBehavior, params Sprite[] sprites)
{
var clip = Track(ScriptableObject.CreateInstance<FrameClip>());
var frames = new List<FrameAnimationFrame>();
for (var index = 0; index < sprites.Length; index++)
{
frames.Add(new FrameAnimationFrame(sprites[index], 100, $"frame_{index}", index));
}
clip.Configure(id, id, frames, 1f, endBehavior);
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>(T value) where T : UnityEngine.Object
{
createdObjects.Add(value);
return value;
}
private readonly struct TimelineSetup
{
internal PlayableDirector Director { get; }
internal TimelineClip Clip { get; }
internal TimelineSetup(PlayableDirector director, TimelineClip clip)
{
Director = director;
Clip = clip;
}
}
}
}