228 lines
8.2 KiB
C#
228 lines
8.2 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_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<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.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));
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator Director_RespectsClipInSpeedMultiplierAndBackwardSeek()
|
|
{
|
|
var first = CreateSprite(Color.red);
|
|
var second = CreateSprite(Color.green);
|
|
var third = CreateSprite(Color.blue);
|
|
var clip = CreateClip(first, second, third);
|
|
var playerObject = Track(new GameObject("Timeline Time Mapping"));
|
|
var renderer = playerObject.AddComponent<SpriteRenderer>();
|
|
var player = playerObject.AddComponent<FrameClipPlayer>();
|
|
var setup = CreateTimeline(player, clip);
|
|
setup.Clip.clipIn = 0.1d;
|
|
setup.Clip.timeScale = 2d;
|
|
|
|
setup.Director.Play();
|
|
setup.Director.time = 0.025d;
|
|
setup.Director.Evaluate();
|
|
yield return null;
|
|
|
|
Assert.That(renderer.sprite, Is.SameAs(second));
|
|
|
|
setup.Director.time = 0.075d;
|
|
setup.Director.Evaluate();
|
|
Assert.That(renderer.sprite, Is.SameAs(third));
|
|
|
|
setup.Director.time = 0d;
|
|
setup.Director.Evaluate();
|
|
Assert.That(renderer.sprite, Is.SameAs(second));
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator Director_ExtendedLoopClipWrapsAtSourceDuration()
|
|
{
|
|
var first = CreateSprite(Color.yellow);
|
|
var second = CreateSprite(Color.cyan);
|
|
var clip = CreateClip(FrameClipEndBehavior.Loop, first, second);
|
|
var playerObject = Track(new GameObject("Timeline 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.25d;
|
|
setup.Director.Evaluate();
|
|
yield return null;
|
|
|
|
Assert.That(renderer.sprite, Is.SameAs(first));
|
|
|
|
setup.Director.time = 0.35d;
|
|
setup.Director.Evaluate();
|
|
Assert.That(renderer.sprite, Is.SameAs(second));
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator Director_AppliesClearAndHideTerminalBehaviors()
|
|
{
|
|
var clearObject = Track(new GameObject("Timeline Clear"));
|
|
var clearRenderer = clearObject.AddComponent<SpriteRenderer>();
|
|
var clearPlayer = clearObject.AddComponent<FrameClipPlayer>();
|
|
var clearSetup = CreateTimeline(
|
|
clearPlayer,
|
|
CreateClip(
|
|
FrameClipEndBehavior.Clear,
|
|
CreateSprite(Color.magenta)));
|
|
|
|
clearSetup.Director.Play();
|
|
clearSetup.Director.time = clearSetup.Clip.duration;
|
|
clearSetup.Director.Evaluate();
|
|
yield return null;
|
|
|
|
Assert.That(clearRenderer.enabled, Is.True);
|
|
Assert.That(clearRenderer.sprite, Is.Null);
|
|
|
|
var hideObject = Track(new GameObject("Timeline Hide"));
|
|
var hideRenderer = hideObject.AddComponent<SpriteRenderer>();
|
|
var hidePlayer = hideObject.AddComponent<FrameClipPlayer>();
|
|
var hideSetup = CreateTimeline(
|
|
hidePlayer,
|
|
CreateClip(
|
|
FrameClipEndBehavior.HideTarget,
|
|
CreateSprite(Color.white)));
|
|
|
|
hideSetup.Director.Play();
|
|
hideSetup.Director.time = hideSetup.Clip.duration;
|
|
hideSetup.Director.Evaluate();
|
|
yield return null;
|
|
|
|
Assert.That(hideRenderer.enabled, Is.False);
|
|
}
|
|
|
|
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.duration = asset.duration;
|
|
|
|
var directorObject = Track(new GameObject("Timeline Director"));
|
|
var director = directorObject.AddComponent<PlayableDirector>();
|
|
director.playableAsset = timeline;
|
|
director.SetGenericBinding(track, player);
|
|
return new TimelineSetup(director, timelineClip);
|
|
}
|
|
|
|
private FrameClip CreateClip(params Sprite[] sprites)
|
|
{
|
|
return CreateClip(FrameClipEndBehavior.HoldLastFrame, sprites);
|
|
}
|
|
|
|
private FrameClip CreateClip(
|
|
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(
|
|
"Timeline",
|
|
"Timeline",
|
|
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 TimelineSetup(PlayableDirector director, TimelineClip clip)
|
|
{
|
|
Director = director;
|
|
Clip = clip;
|
|
}
|
|
|
|
internal PlayableDirector Director { get; }
|
|
internal TimelineClip Clip { get; }
|
|
}
|
|
}
|
|
}
|