2800 lines
102 KiB
C#
2800 lines
102 KiB
C#
#if TEST_FRAMEWORK_INSTALLED
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading.Tasks;
|
|
using JetBrains.Annotations;
|
|
using NUnit.Framework;
|
|
using PrimeTween;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
using UnityEngine.TestTools;
|
|
using Assert = NUnit.Framework.Assert;
|
|
using AssertionException = UnityEngine.Assertions.AssertionException;
|
|
using Object = UnityEngine.Object;
|
|
using Random = UnityEngine.Random;
|
|
using SuppressMessage = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute;
|
|
|
|
public partial class Tests {
|
|
[Test]
|
|
public void TweenTimeScaleWhileInSequence() {
|
|
var t = Tween.Delay(0.01f);
|
|
Sequence.Create(t);
|
|
expectCantManipulateTweenInsideSequence();
|
|
t.timeScale = 2f;
|
|
LogAssert.NoUnexpectedReceived();
|
|
Tween.StopAll();
|
|
}
|
|
|
|
[Test]
|
|
public async Task TweenTimeScaleOutlive() {
|
|
{
|
|
var tween = Tween.Delay(getDt() / 2);
|
|
var timeScaleTween = Tween.TweenTimeScale(tween, Random.value + 0.01f, float.MaxValue);
|
|
await tween;
|
|
Assert.IsFalse(timeScaleTween.isAlive);
|
|
}
|
|
{
|
|
var seq = Sequence.Create(Tween.Delay(getDt() / 2));
|
|
var timeScaleTween = Tween.TweenTimeScale(seq, Random.value + 0.01f, float.MaxValue);
|
|
await seq;
|
|
Assert.IsFalse(timeScaleTween.isAlive);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public async Task TweenTimeScale() {
|
|
var t = Tween.PositionZ(transform, 10, 1);
|
|
const float iniTimeScale = 0.9f;
|
|
t.timeScale = iniTimeScale;
|
|
Assert.AreEqual(iniTimeScale, t.timeScale);
|
|
const float targetTimeScale = 0.5f;
|
|
await Tween.TweenTimeScale(t, targetTimeScale, 0.001f);
|
|
Assert.AreEqual(targetTimeScale, t.timeScale);
|
|
t.Complete();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator QuaternionDefaultValue() {
|
|
{
|
|
var q = Quaternion.Euler(0, 0, 45);
|
|
var def = new Quaternion();
|
|
Assert.AreEqual(Quaternion.identity.normalized, def.normalized);
|
|
Assert.AreNotEqual(Quaternion.Angle(Quaternion.identity, q), Quaternion.Angle(def, q));
|
|
Assert.AreEqual(Quaternion.Angle(Quaternion.identity, q), Quaternion.Angle(def.normalized, q));
|
|
}
|
|
{
|
|
Tween t = default;
|
|
var def = new Quaternion();
|
|
int numCallback = 0;
|
|
t = Tween.Custom(def, def, 0.01f, delegate {
|
|
numCallback++;
|
|
var startVal = t.tween.startValue.QuaternionVal;
|
|
var endVal = t.tween.endValue.QuaternionVal;
|
|
// Debug.Log($"{startVal}, {endVal}");
|
|
Assert.AreNotEqual(def, startVal);
|
|
Assert.AreNotEqual(def, endVal);
|
|
t.Stop();
|
|
});
|
|
yield return t.ToYieldInstruction();
|
|
Assert.AreEqual(1, numCallback);
|
|
}
|
|
}
|
|
|
|
/// This test can fail if Game window is set to 'Play Unfocused'
|
|
[UnityTest]
|
|
public IEnumerator StartValueIsAppliedOnFirstFrame() {
|
|
const int iniVal = -1;
|
|
float val = iniVal;
|
|
const int startValue = 0;
|
|
Tween.Custom(startValue, 1, 0.01f, newVal => val = newVal);
|
|
Assert.AreEqual(iniVal, val);
|
|
yield return new WaitForEndOfFrame();
|
|
Assert.AreEqual(startValue, val);
|
|
yield return new WaitForEndOfFrame();
|
|
Assert.AreNotEqual(startValue, val);
|
|
}
|
|
|
|
[Test]
|
|
public void SafetyChecksEnabled() {
|
|
#if !PRIME_TWEEN_SAFETY_CHECKS
|
|
Assert.Inconclusive();
|
|
#endif
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenIsDeadInOnComplete() {
|
|
Tween t = default;
|
|
t = Tween.Delay(0.01f, () => {
|
|
Assert.IsFalse(t.isAlive);
|
|
for (int i = 0; i < 6; i++) {
|
|
expectIsDeadError();
|
|
}
|
|
Assert.AreEqual(0, t.elapsedTime);
|
|
Assert.AreEqual(0, t.elapsedTimeTotal);
|
|
Assert.AreEqual(0, t.progress);
|
|
Assert.AreEqual(0, t.progressTotal);
|
|
Assert.AreEqual(0, t.duration);
|
|
Assert.AreEqual(0, t.durationTotal);
|
|
});
|
|
yield return t.ToYieldInstruction();
|
|
}
|
|
|
|
static void expectIsDeadError(bool isCreated = true) => LogAssert.Expect(LogType.Error, new Regex(isCreated ? Constants.isDeadMessage : "Tween or Sequence is not created properly."));
|
|
|
|
[Test]
|
|
public void ShakeDuplication1() {
|
|
var s1 = Tween.ShakeLocalPosition(transform, Vector3.one, 0.1f, startDelay: 0.1f);
|
|
var s2 = Tween.ShakeLocalPosition(transform, Vector3.one, 0.1f);
|
|
Assert.IsTrue(s1.isAlive);
|
|
Assert.IsTrue(s2.isAlive);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ShakeDuplication2() {
|
|
var s1 = Tween.ShakeLocalPosition(transform, Vector3.one, 0.1f);
|
|
Assert.IsTrue(s1.isAlive);
|
|
var s2 = Tween.ShakeLocalPosition(transform, Vector3.one, 0.1f);
|
|
Assert.IsTrue(s1.isAlive);
|
|
yield return null;
|
|
// because two shakes are started the same frame, the first one completes the second one
|
|
Assert.IsTrue(s1.isAlive);
|
|
Assert.IsTrue(s2.isAlive);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ShakeDuplication3() {
|
|
var s1 = Tween.ShakeLocalPosition(transform, Vector3.one, 0.1f);
|
|
yield return null;
|
|
var s2 = Tween.ShakeLocalPosition(transform, Vector3.one, 0.1f);
|
|
yield return null;
|
|
Assert.IsTrue(s1.isAlive);
|
|
Assert.IsTrue(s2.isAlive);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ShakeDuplication4() {
|
|
const float startDelay = 0.05f;
|
|
var s1 = Tween.ShakeLocalPosition(transform, Vector3.one, 0.1f, startDelay: startDelay);
|
|
var s2 = Tween.ShakeLocalPosition(transform, Vector3.one, 0.1f, startDelay: 0.1f);
|
|
yield return Tween.Delay(startDelay + Time.deltaTime).ToYieldInstruction();
|
|
Assert.IsTrue(s1.isAlive);
|
|
Assert.IsTrue(s2.isAlive);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ShakeDuplication5() {
|
|
var target = new GameObject(nameof(ShakeDuplication5)).transform;
|
|
target.localPosition = new Vector3(Random.value, Random.value, Random.value);
|
|
var iniPos = target.localPosition;
|
|
var s1 = Tween.ShakeLocalPosition(target, Vector3.one, 0.1f);
|
|
var seq = Sequence.Create(s1);
|
|
Assert.IsTrue(s1.isAlive);
|
|
var s2 = Tween.ShakeLocalPosition(target, Vector3.one, 0.1f);
|
|
Assert.IsTrue(s1.isAlive);
|
|
Assert.IsTrue(seq.isAlive);
|
|
Assert.IsTrue(s2.isAlive);
|
|
|
|
Assert.IsTrue(s1.tween.startFromCurrent);
|
|
Assert.IsTrue(s2.tween.startFromCurrent);
|
|
yield return null;
|
|
Assert.IsTrue(s1.isAlive);
|
|
Assert.IsTrue(seq.isAlive);
|
|
Assert.IsTrue(s2.isAlive);
|
|
|
|
Assert.IsFalse(s1.tween.startFromCurrent);
|
|
Assert.IsFalse(s2.tween.startFromCurrent);
|
|
Assert.AreEqual(iniPos, s1.tween.startValue.Vector3Val);
|
|
Assert.AreEqual(iniPos, s2.tween.startValue.Vector3Val);
|
|
}
|
|
|
|
[Test]
|
|
public void ShakeDuplicationDestroyedTarget() {
|
|
var target = new GameObject(nameof(ShakeDuplicationDestroyedTarget)).transform;
|
|
Tween.ShakeLocalPosition(target, Vector3.one, 0.1f);
|
|
Object.DestroyImmediate(target.gameObject);
|
|
Tween.ShakeLocalPosition(target, Vector3.one, 0.1f);
|
|
expectTargetIsNull();
|
|
}
|
|
|
|
static void expectTargetIsNull() => LogAssert.Expect(LogType.Error, new Regex("Tween's target is null"));
|
|
|
|
[UnityTest]
|
|
public IEnumerator FramePacing() {
|
|
Tween.StopAll();
|
|
const int fps = 120;
|
|
Application.targetFrameRate = fps;
|
|
QualitySettings.vSyncCount = 0;
|
|
Assert.AreEqual(fps, Application.targetFrameRate);
|
|
yield return null;
|
|
{
|
|
var go = new GameObject();
|
|
go.AddComponent<FramePacingTest>();
|
|
while (go != null) {
|
|
yield return null;
|
|
}
|
|
}
|
|
Application.targetFrameRate = targetFrameRate;
|
|
yield return null;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
[Test]
|
|
public void GenerateCode() {
|
|
const string path = "Packages/com.kyrylokuzyk.primetween/Editor/CodeGenerator.asset";
|
|
var cg = UnityEditor.AssetDatabase.LoadAssetAtPath<CodeGenerator>(path);
|
|
cg.generateAllMethods();
|
|
}
|
|
#endif
|
|
|
|
[Test]
|
|
public void TweenCompleteInvokeOnCompleteParameter() {
|
|
{
|
|
int numCompleted = 0;
|
|
var t = Tween.Scale(transform, 1.5f, 0.01f).OnComplete(() => numCompleted++);
|
|
t.Complete();
|
|
Assert.AreEqual(1, numCompleted);
|
|
t.Complete();
|
|
Assert.AreEqual(1, numCompleted);
|
|
}
|
|
/*{
|
|
int numCompleted = 0;
|
|
var t = Tween.Scale(transform, 1.5f, 0.01f).OnComplete(() => numCompleted++);
|
|
t.Complete(false);
|
|
Assert.AreEqual(0, numCompleted);
|
|
t.Complete(false);
|
|
Assert.AreEqual(0, numCompleted);
|
|
t.Complete();
|
|
Assert.AreEqual(0, numCompleted);
|
|
}*/
|
|
}
|
|
|
|
[Test]
|
|
public void IgnoreFromInScale() {
|
|
var t = Tween.Scale(transform, 1.5f, 0.01f);
|
|
Assert.IsTrue(t.tween.startFromCurrent);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator FromToValues() {
|
|
{
|
|
var duration = getDt() * Random.Range(0.5f, 1.5f);
|
|
var t = Tween.Custom(0, 0, duration, ease: Ease.Linear, onValueChange: delegate { });
|
|
while (t.isAlive) {
|
|
Assert.AreEqual(t.elapsedTime, t.progress * duration, 0.001f);
|
|
Assert.AreEqual(t.interpolationFactor, t.progress);
|
|
Assert.AreEqual(t.interpolationFactor, t.progressTotal);
|
|
yield return null;
|
|
}
|
|
}
|
|
var from = Random.value;
|
|
var to = Random.value;
|
|
var data = new TweenSettings<float>(from, to, 0.01f);
|
|
{
|
|
var t = Tween.LocalPositionX(transform, data);
|
|
Assert.AreEqual(from, t.tween.startValue.FloatVal);
|
|
Assert.AreEqual(to, t.tween.endValue.FloatVal);
|
|
}
|
|
{
|
|
var t = Tween.Custom(this, data, delegate { });
|
|
Assert.AreEqual(from, t.tween.startValue.FloatVal);
|
|
Assert.AreEqual(to, t.tween.endValue.FloatVal);
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenCompleteWhenInterpolationCompleted() {
|
|
float curVal = 0f;
|
|
var t = Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 2, endDelay: 1f, cycleMode: CycleMode.Yoyo);
|
|
while (t.interpolationFactor < 1f) {
|
|
yield return null;
|
|
}
|
|
Assert.AreEqual(0, t.cyclesDone);
|
|
Assert.AreEqual(1f, curVal);
|
|
t.Complete();
|
|
Assert.AreEqual(0f, curVal);
|
|
}
|
|
|
|
[Test]
|
|
public async Task CycleModeIncremental() {
|
|
{
|
|
float curVal = 0f;
|
|
await Tween.Custom(this, 0f, 1f, 0.01f, (_, val) => curVal = val, cycles: 2, cycleMode: CycleMode.Incremental);
|
|
Assert.AreEqual(2f, curVal);
|
|
}
|
|
{
|
|
float curVal = 0f;
|
|
await Tween.Custom(this, 0f, 1f, 0.01f, (_, val) => curVal = val, cycles: 4, cycleMode: CycleMode.Incremental);
|
|
Assert.AreEqual(4f, curVal);
|
|
}
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.01f, (_, val) => curVal = val, cycles: 2, cycleMode: CycleMode.Incremental)
|
|
.Complete();
|
|
Assert.AreEqual(2f, curVal);
|
|
}
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.01f, (_, val) => curVal = val, cycles: 4, cycleMode: CycleMode.Incremental)
|
|
.Complete();
|
|
Assert.AreEqual(4f, curVal);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TweenCompleteWithEvenCycles() {
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 2, cycleMode: CycleMode.Restart)
|
|
.Complete();
|
|
Assert.AreEqual(1f, curVal);
|
|
}
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 4, cycleMode: CycleMode.Restart)
|
|
.Complete();
|
|
Assert.AreEqual(1f, curVal);
|
|
}
|
|
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 2, cycleMode: CycleMode.Yoyo)
|
|
.Complete();
|
|
Assert.AreEqual(0f, curVal);
|
|
}
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 4, cycleMode: CycleMode.Yoyo)
|
|
.Complete();
|
|
Assert.AreEqual(0f, curVal);
|
|
}
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 2, cycleMode: CycleMode.Rewind)
|
|
.Complete();
|
|
Assert.AreEqual(0f, curVal);
|
|
}
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 4, cycleMode: CycleMode.Rewind)
|
|
.Complete();
|
|
Assert.AreEqual(0f, curVal);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TweenCompleteWithOddCycles() {
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 1, cycleMode: CycleMode.Yoyo)
|
|
.Complete();
|
|
Assert.AreEqual(1f, curVal);
|
|
}
|
|
{
|
|
float curVal = 0f;
|
|
Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 3, cycleMode: CycleMode.Yoyo)
|
|
.Complete();
|
|
Assert.AreEqual(1f, curVal);
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenOnCompleteIsCalledOnceForTweenInSequence() {
|
|
for (int i = 0; i < 1; i++) {
|
|
loopBegin:
|
|
float curVal = 0f;
|
|
int numCompleted = 0;
|
|
float duration = Mathf.Max(minDuration, getDt()) * 10f;
|
|
var t = Tween.Custom(this, 0f, 1f, duration, (_, val) => curVal = val, cycles: 1, cycleMode: CycleMode.Yoyo)
|
|
.OnComplete(() => numCompleted++);
|
|
var s = t.Chain(Tween.Delay(duration));
|
|
while (true) {
|
|
if (!t.isAlive) {
|
|
goto loopBegin;
|
|
}
|
|
if (t.cyclesDone == 1) {
|
|
break;
|
|
}
|
|
yield return null;
|
|
}
|
|
Assert.IsTrue(t.isAlive);
|
|
Assert.AreEqual(1, t.tween.getCyclesDone());
|
|
Assert.IsTrue(t.tween.sequence.IsCreated);
|
|
Assert.AreEqual(1, numCompleted);
|
|
|
|
Assert.IsTrue(s.isAlive);
|
|
Assert.AreEqual(1f, curVal);
|
|
s.Complete();
|
|
Assert.AreEqual(1f, curVal);
|
|
Assert.AreEqual(1, numCompleted);
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TweenCompleteInSequence() {
|
|
float curVal = 0f;
|
|
var t = Tween.Custom(this, 0f, 1f, 0.05f, (_, val) => curVal = val, cycles: 1, cycleMode: CycleMode.Yoyo);
|
|
var s = t.Chain(Tween.Delay(0.05f));
|
|
Assert.IsTrue(t.isAlive);
|
|
Assert.AreEqual(0, t.tween.getCyclesDone());
|
|
Assert.IsTrue(t.tween.sequence.IsCreated);
|
|
Assert.IsTrue(s.isAlive);
|
|
Assert.AreNotEqual(1f, curVal);
|
|
s.Complete();
|
|
Assert.AreEqual(1f, curVal);
|
|
}
|
|
|
|
[Test]
|
|
public async Task AwaitExceptions() {
|
|
expectTweenWasStoppedBecauseException();
|
|
await Tween.Custom(this, 0f, 1f, 1f, delegate {
|
|
throw new Exception();
|
|
});
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator CoroutineEnumeratorNotEnumeratedToTheEnd() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
var t = Tween.Delay(TweenSettings.minDuration * 100);
|
|
var e = t.ToYieldInstruction();
|
|
Assert.IsTrue(e.MoveNext());
|
|
yield return e.Current;
|
|
Assert.IsTrue(t.isAlive);
|
|
while (t.isAlive) {
|
|
yield return null;
|
|
}
|
|
yield return null;
|
|
Assert.AreEqual(0, tweensCount);
|
|
testCompletedCorEnumerator(e);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator CoroutineEnumeratorInfiniteTween() {
|
|
{
|
|
var t = Tween.Position(transform, Vector3.one, getDt(), cycles: -1);
|
|
Tween.Delay(getDt() * 5f).OnComplete(() => t.Stop());
|
|
yield return t.ToYieldInstruction();
|
|
}
|
|
{
|
|
var t = Tween.Position(transform, Vector3.one, getDt(), cycles: -1);
|
|
Tween.Delay(getDt() * 5f).OnComplete(() => t.Complete());
|
|
yield return t.ToYieldInstruction();
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator CoroutineEnumeratorMultipleToYieldInstruction() {
|
|
var t = Tween.Delay(0.01f);
|
|
var e = t.ToYieldInstruction();
|
|
Assert.Throws<AssertionException>(() => t.ToYieldInstruction());
|
|
t.Complete();
|
|
yield return e;
|
|
Assert.IsFalse(t.isAlive);
|
|
testCompletedCorEnumerator(e);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator CoroutineEnumeratorUsingDead() {
|
|
var t = Tween.Delay(0.01f);
|
|
var e = t.ToYieldInstruction();
|
|
yield return e;
|
|
Assert.IsFalse(t.isAlive);
|
|
testCompletedCorEnumerator(e);
|
|
}
|
|
|
|
static void testCompletedCorEnumerator(IEnumerator e) {
|
|
Assert.IsFalse(e.MoveNext());
|
|
Assert.Throws<AssertionException>(() => {
|
|
_ = e.Current;
|
|
});
|
|
Assert.Throws<NotSupportedException>(() => e.Reset());
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator YieldInstructionsClash2() {
|
|
var test = new GameObject().AddComponent<YieldInstructionsClash>();
|
|
// ReSharper disable once LoopVariableIsNeverChangedInsideLoop
|
|
while (test != null) {
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator YieldInstructionsClash() {
|
|
Application.targetFrameRate = 100;
|
|
yield return null;
|
|
Assert.AreEqual(0, tweensCount);
|
|
for (int i = 0; i < 1; i++) {
|
|
{
|
|
var t1 = Tween.Delay(minDuration);
|
|
int frameStart = Time.frameCount;
|
|
yield return t1.ToYieldInstruction();
|
|
Assert.AreEqual(1, Time.frameCount - frameStart);
|
|
Assert.IsFalse(t1.isAlive);
|
|
var t2 = Tween.Delay(minDuration);
|
|
t2.ToYieldInstruction();
|
|
t2.Complete();
|
|
}
|
|
{
|
|
var t1 = Tween.Delay(minDuration);
|
|
t1.ToYieldInstruction();
|
|
yield return null;
|
|
yield return null;
|
|
Assert.IsFalse(t1.isAlive);
|
|
var t2 = Tween.Delay(minDuration);
|
|
t2.ToYieldInstruction();
|
|
t2.Complete();
|
|
}
|
|
}
|
|
Application.targetFrameRate = targetFrameRate;
|
|
}
|
|
|
|
[Test]
|
|
public void TweenDuplicateInSequence() {
|
|
var t1 = Tween.Delay(0.1f);
|
|
var t2 = Tween.Delay(0.1f);
|
|
var s = t1.Chain(t2);
|
|
expectNestTweenTwiceError();
|
|
s.Chain(t1);
|
|
}
|
|
|
|
/*[UnityTest]
|
|
public IEnumerator WaitStopFromValueChange2() {
|
|
Tween t = default;
|
|
t = Tween.WaitWhile(this, _ => {
|
|
Assert.IsTrue(t.isAlive);
|
|
t.Stop();
|
|
return true;
|
|
});
|
|
yield return t.ToYieldInstruction();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator WaitCompleteFromValueChange2() {
|
|
Tween t = default;
|
|
int numValueChanged = 0;
|
|
t = Tween.WaitWhile(this, _ => {
|
|
numValueChanged++;
|
|
switch (numValueChanged) {
|
|
case 1:
|
|
Assert.IsTrue(t.isAlive);
|
|
t.Complete();
|
|
break;
|
|
case 2:
|
|
Assert.IsFalse(t.isAlive);
|
|
break;
|
|
default: throw new Exception();
|
|
}
|
|
return true;
|
|
});
|
|
yield return t.ToYieldInstruction();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator WaitCompleteFromValueChange() {
|
|
var target = new GameObject();
|
|
int numValueChanged = 0;
|
|
yield return Tween.WaitWhile(target, _ => {
|
|
numValueChanged++;
|
|
switch (numValueChanged) {
|
|
case 1:
|
|
Assert.AreEqual(1, Tween.CompleteAll(target, 1, 1));
|
|
break;
|
|
case 2:
|
|
Assert.AreEqual(0, Tween.CompleteAll(target, 0, 0));
|
|
break;
|
|
default: throw new Exception();
|
|
}
|
|
return true;
|
|
}).ToYieldInstruction();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator WaitStopFromValueChange() {
|
|
var target = new GameObject();
|
|
yield return Tween.WaitWhile(target, _ => {
|
|
Assert.AreEqual(1, Tween.StopAll(target, 1, 1));
|
|
return true;
|
|
}).ToYieldInstruction();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenWait() {
|
|
var timeStart = Time.time;
|
|
int numOnCompleteDone = 0;
|
|
const float duration = 0.3f;
|
|
var t = Tween.WaitWhile(this, _ => Time.time - timeStart < duration)
|
|
.OnComplete(() => numOnCompleteDone++);
|
|
yield return null;
|
|
Assert.IsTrue(t.isAlive);
|
|
yield return new WaitForSeconds(duration + 0.01f);
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(1, numOnCompleteDone);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[Test]
|
|
public void TweenWaitInstantComplete() {
|
|
int numOnCompleteDone = 0;
|
|
var t = Tween.WaitWhile(this, _ => true).OnComplete(() => numOnCompleteDone++);
|
|
Assert.IsTrue(t.isAlive);
|
|
t.Complete();
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(1, numOnCompleteDone);
|
|
}
|
|
|
|
[Test]
|
|
public void TweenWaitInstantStop() {
|
|
int numOnCompleteDone = 0;
|
|
var t = Tween.WaitWhile(this, _ => true).OnComplete(() => numOnCompleteDone++);
|
|
Assert.IsTrue(t.isAlive);
|
|
t.Stop();
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(0, numOnCompleteDone);
|
|
}
|
|
|
|
[Test]
|
|
public void TweenWaitException() {
|
|
var t = Tween.WaitWhile(this, _ => throw new Exception()).OnComplete(Assert.Fail);
|
|
Assert.IsTrue(t.isAlive);
|
|
LogAssert.Expect(LogType.Error, new Regex("Tween was stopped because of exception"));
|
|
LogAssert.Expect(LogType.Error, new Regex(Constants.onCompleteCallbackIgnored));
|
|
t.Complete();
|
|
Assert.IsFalse(t.isAlive);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenWaitDuration() {
|
|
// Application.targetFrameRate = 60;
|
|
var t = Tween.WaitWhile(this, _ => true);
|
|
validate();
|
|
Assert.AreEqual(0, t.elapsedTime);
|
|
Assert.AreEqual(0, t.elapsedTimeTotal);
|
|
yield return null;
|
|
Assert.AreNotEqual(0, t.elapsedTime);
|
|
Assert.AreNotEqual(0, t.elapsedTimeTotal);
|
|
// for (int i = 0; i < 60; i++) {
|
|
// yield return null;
|
|
// Debug.Log($"{t.elapsedTime}, {t.elapsedTimeTotal}");
|
|
// }
|
|
validate();
|
|
t.Complete();
|
|
void validate() {
|
|
Assert.AreEqual(-1, t.cyclesTotal);
|
|
Assert.AreEqual(0, t.cyclesDone);
|
|
Assert.IsTrue(float.IsPositiveInfinity(t.duration));
|
|
Assert.IsTrue(float.IsPositiveInfinity(t.durationTotal));
|
|
Assert.AreEqual(0, t.progress);
|
|
Assert.AreEqual(0, t.progressTotal);
|
|
Assert.AreEqual(0, t.interpolationFactor);
|
|
}
|
|
}*/
|
|
|
|
[Test]
|
|
public void ZeroDurationWarning() {
|
|
var oldSetting = PrimeTweenConfig.warnZeroDuration;
|
|
try {
|
|
PrimeTweenConfig.warnZeroDuration = true;
|
|
LogAssert.Expect(LogType.Warning, new Regex(nameof(PrimeTweenManager.warnZeroDuration)));
|
|
Tween.Custom(this, 0, 1, 0, delegate{});
|
|
PrimeTweenConfig.warnZeroDuration = false;
|
|
Tween.Custom(this, 0, 1, 0, delegate{});
|
|
LogAssert.NoUnexpectedReceived();
|
|
} finally {
|
|
PrimeTweenConfig.warnZeroDuration = oldSetting;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void CompleteTweenTwice() {
|
|
int numCompleted = 0;
|
|
var t = createCustomTween(1)
|
|
.OnComplete(() => numCompleted++);
|
|
t.Complete();
|
|
Assert.AreEqual(1, numCompleted);
|
|
t.Complete();
|
|
Assert.AreEqual(1, numCompleted);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator FromValueShouldNotChangeBetweenCycles() {
|
|
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
|
|
var origPos = new Vector3(10, 10, 10);
|
|
cube.transform.position = origPos;
|
|
var tween = Tween.Position(cube.transform, new Vector3(20, 10, 10), 0.01f, cycles: 5);
|
|
Assert.IsTrue(tween.isAlive);
|
|
Assert.IsNotNull(tween.tween.getter);
|
|
while (tween.isAlive) {
|
|
yield return null;
|
|
Assert.AreEqual(origPos, tween.tween.startValue.Vector3Val, "'From' should not change after a cycle. This can happen if tween resets startFromCurrent after a cycle.");
|
|
}
|
|
Object.Destroy(cube);
|
|
}
|
|
|
|
[Test]
|
|
public void SettingIsPausedOnTweenInSequenceDisplayError() {
|
|
var target = new object();
|
|
var t = Tween.Delay(target, 0.01f);
|
|
Sequence.Create(t);
|
|
expectError();
|
|
t.isPaused = true;
|
|
|
|
expectError();
|
|
Tween.SetPausedAll(true, target);
|
|
|
|
expectError();
|
|
Tween.SetPausedAll(false, target);
|
|
|
|
void expectError() {
|
|
expectCantManipulateTweenInsideSequence();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SettingCyclesOnDeadTweenDisplaysError() {
|
|
var t = createTween();
|
|
Assert.IsTrue(t.isAlive);
|
|
t.Complete();
|
|
Assert.IsFalse(t.isAlive);
|
|
expectIsDeadError();
|
|
t.SetRemainingCycles(5);
|
|
}
|
|
|
|
[Test]
|
|
public void TestDeadTween() {
|
|
var t = createDeadTween();
|
|
|
|
expectError();
|
|
t.isPaused = true;
|
|
|
|
t.Stop();
|
|
t.Complete();
|
|
// t.Revert();
|
|
|
|
expectError();
|
|
t.SetRemainingCycles(10);
|
|
|
|
expectError();
|
|
t.OnComplete(delegate{});
|
|
|
|
expectError();
|
|
t.OnComplete(this, delegate { });
|
|
|
|
expectError();
|
|
t.timeScale = 0;
|
|
|
|
void expectError() {
|
|
expectIsDeadError();
|
|
}
|
|
}
|
|
|
|
static Tween createDeadTween() {
|
|
var t = createCustomTween(0.1f);
|
|
t.Complete();
|
|
Assert.IsFalse(t.isAlive);
|
|
return t;
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenIsPaused() {
|
|
var val = 0f;
|
|
var t = Tween.Custom(this, 0, 1, 1, (_, newVal) => {
|
|
val = newVal;
|
|
});
|
|
t.isPaused = true;
|
|
yield return null;
|
|
Assert.AreEqual(0, val);
|
|
yield return null;
|
|
Assert.AreEqual(0, val);
|
|
yield return null;
|
|
Assert.AreEqual(0, val);
|
|
t.isPaused = false;
|
|
yield return null;
|
|
Assert.AreNotEqual(0, val);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator SequenceIsPaused() {
|
|
var val = 0f;
|
|
var t = Tween.Custom(this, 0, 1, 1, (_, newVal) => {
|
|
val = newVal;
|
|
});
|
|
var s = Sequence.Create(t);
|
|
s.isPaused = true;
|
|
yield return null;
|
|
Assert.AreEqual(0, val);
|
|
yield return null;
|
|
Assert.AreEqual(0, val);
|
|
yield return null;
|
|
Assert.AreEqual(0, val);
|
|
s.isPaused = false;
|
|
yield return null;
|
|
Assert.AreNotEqual(0, val);
|
|
}
|
|
|
|
const int capacityForTest = 800;
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweensCapacity() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
PrimeTweenConfig.SetTweensCapacity(capacityForTest);
|
|
Assert.AreEqual(capacityForTest, tweensCapacity);
|
|
PrimeTweenConfig.SetTweensCapacity(0);
|
|
Assert.AreEqual(0, tweensCapacity);
|
|
LogAssert.Expect(LogType.Warning, new Regex("Please increase the capacity"));
|
|
Tween.Delay(0.0001f);
|
|
Tween.Delay(0.0001f); // created before set capacity
|
|
PrimeTweenConfig.SetTweensCapacity(capacityForTest);
|
|
Assert.AreEqual(capacityForTest, tweensCapacity);
|
|
var delay = Tween.Delay(0.0001f);
|
|
yield return delay.ToYieldInstruction(); // should not display warning
|
|
Assert.IsFalse(delay.isAlive);
|
|
yield return null; // the yielded tween is not yet released when the coroutine completes. The release will happen only in a frame
|
|
Assert.AreEqual(0, tweensCount);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
static int tweensCapacity => PrimeTweenManager.Instance.currentPoolCapacity;
|
|
|
|
[Test]
|
|
public void ListResize() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
var list = new List<ReusableTween>();
|
|
test(2, 2);
|
|
Assert.AreNotEqual(list[0], list[1]);
|
|
test(0, 2);
|
|
test(10, 10);
|
|
test(2, 5);
|
|
test(10, 20);
|
|
test(5, 30);
|
|
test(6, 29);
|
|
test(4, 31);
|
|
test(5, 32);
|
|
test(5, 31);
|
|
test(4, 31);
|
|
test(3, 31);
|
|
test(0, 31);
|
|
test(31, 31);
|
|
Assert.Throws<AssertionException>(() => test(32, 31));
|
|
test(0, 0);
|
|
test(10, 10);
|
|
void test(int newCount, int newCapacity) {
|
|
PrimeTweenManager.resizeAndSetCapacity(list, newCount, newCapacity);
|
|
Assert.AreEqual(newCount, list.Count);
|
|
Assert.AreEqual(newCapacity, list.Capacity);
|
|
|
|
PrimeTweenConfig.SetTweensCapacity(newCapacity);
|
|
Assert.AreEqual(newCapacity, tweensCapacity);
|
|
}
|
|
PrimeTweenConfig.SetTweensCapacity(capacityForTest);
|
|
}
|
|
|
|
static ShakeSettings shakeSettings {
|
|
get {
|
|
if (Random.value < 0.5f) {
|
|
return new ShakeSettings(Vector3.one, 1f, 10f, false);
|
|
}
|
|
return new ShakeSettings(Vector3.one, 1f, 10f, false, Ease.Linear);
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ShakeCompleteWhenStartDelayIsNotElapsed() {
|
|
var target = new GameObject(nameof(ShakeCompleteWhenStartDelayIsNotElapsed)).transform;
|
|
var iniPos = Random.value * Vector3.one;
|
|
target.localPosition = iniPos;
|
|
var t = Tween.ShakeLocalPosition(target, Vector3.one, 0.1f, startDelay: 0.1f);
|
|
yield return null;
|
|
Assert.AreEqual(0f, t.interpolationFactor);
|
|
Assert.AreEqual(iniPos, target.localPosition);
|
|
t.Complete();
|
|
Assert.AreEqual(iniPos, target.localPosition);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ShakeScale() {
|
|
var shakeTransform = new GameObject("shake target").transform;
|
|
shakeTransform.position = Vector3.one;
|
|
Assert.AreEqual(shakeTransform.localScale, Vector3.one);
|
|
var t = Tween.ShakeScale(shakeTransform, shakeSettings);
|
|
yield return null;
|
|
Assert.AreNotEqual(shakeTransform.localScale, Vector3.one);
|
|
t.Complete();
|
|
Assert.IsTrue(shakeTransform.localScale == Vector3.one);
|
|
Object.DestroyImmediate(shakeTransform.gameObject);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ShakeLocalRotation() {
|
|
var shakeTransform = new GameObject("shake target").transform;
|
|
shakeTransform.position = Vector3.one;
|
|
Assert.AreEqual(shakeTransform.localRotation, Quaternion.identity);
|
|
var t = Tween.ShakeLocalRotation(shakeTransform, shakeSettings);
|
|
yield return null;
|
|
Assert.AreNotEqual(shakeTransform.localRotation, Quaternion.identity);
|
|
t.Complete();
|
|
Assert.IsTrue(shakeTransform.localRotation == Quaternion.identity);
|
|
Object.DestroyImmediate(shakeTransform.gameObject);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ShakeLocalPosition() {
|
|
var shakeTransform = new GameObject("shake target").transform;
|
|
shakeTransform.position = Vector3.one;
|
|
Assert.AreEqual(shakeTransform.position, Vector3.one);
|
|
var t = Tween.ShakeLocalPosition(shakeTransform, shakeSettings);
|
|
yield return null;
|
|
Assert.AreNotEqual(shakeTransform.position, Vector3.one);
|
|
t.Complete();
|
|
Assert.IsTrue(shakeTransform.position == Vector3.one, shakeTransform.position.ToString());
|
|
Object.DestroyImmediate(shakeTransform.gameObject);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ShakeCustom() {
|
|
var shakeTransform = new GameObject("shake target").transform;
|
|
var iniPos = Vector3.one;
|
|
shakeTransform.position = iniPos;
|
|
Assert.AreEqual(iniPos, shakeTransform.position);
|
|
var t = Tween.ShakeCustom(shakeTransform, iniPos, shakeSettings, (target, val) => target.localPosition = val);
|
|
yield return null;
|
|
Assert.AreNotEqual(iniPos, shakeTransform.position);
|
|
t.Complete();
|
|
Assert.IsTrue(iniPos == shakeTransform.position, iniPos.ToString());
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator CreateShakeWhenTweenListHasNull() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
Tween.Delay(0.0001f);
|
|
LogAssert.Expect(LogType.Error, "Shake's strength is (0, 0, 0).");
|
|
LogAssert.Expect(LogType.Error, new Regex("Shake's frequency should be > 0f"));
|
|
Tween.Delay(0.0001f)
|
|
.OnComplete(() => {
|
|
Assert.AreEqual(1, getNullTweensCount());
|
|
Tween.ShakeLocalPosition(transform, default).Complete();
|
|
});
|
|
yield return null;
|
|
yield return null;
|
|
yield return null;
|
|
Assert.AreEqual(0, tweensCount);
|
|
}
|
|
|
|
static int getNullTweensCount() => PrimeTweenManager.Instance.tweensCount - Tween.GetTweensCount();
|
|
|
|
[UnityTest]
|
|
public IEnumerator DelayNoTarget() {
|
|
int numCallbackCalled = 0;
|
|
var t = Tween.Delay(getDt() * 2f, () => numCallbackCalled++);
|
|
Assert.AreEqual(0, numCallbackCalled);
|
|
while (t.isAlive) {
|
|
yield return null;
|
|
}
|
|
Assert.AreEqual(1, numCallbackCalled);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator DelayFirstOverload() {
|
|
int numCallbackCalled = 0;
|
|
var t = Tween.Delay(this, getDt() * 3, () => numCallbackCalled++);
|
|
Assert.AreEqual(0, numCallbackCalled);
|
|
while (t.isAlive) {
|
|
yield return null;
|
|
}
|
|
Assert.AreEqual(1, numCallbackCalled);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator DelaySecondOverload() {
|
|
int numCallbackCalled = 0;
|
|
var t = Tween.Delay(this, getDt() * 3, _ => numCallbackCalled++);
|
|
Assert.AreEqual(0, numCallbackCalled);
|
|
while (t.isAlive) {
|
|
yield return null;
|
|
}
|
|
Assert.AreEqual(1, numCallbackCalled);
|
|
}
|
|
|
|
[UnityTest]
|
|
[SuppressMessage("ReSharper", "PossibleNullReferenceException")]
|
|
public IEnumerator NewTweenCreatedFromManualOnComplete() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
var t1 = createTween().OnComplete(() => createTween());
|
|
createTween();
|
|
t1.Complete();
|
|
Assert.AreEqual(3, tweensCount);
|
|
checkTweensAreOrdered();
|
|
yield return null;
|
|
Assert.AreEqual(2, tweensCount);
|
|
checkTweensAreOrdered();
|
|
Tween.StopAll();
|
|
}
|
|
|
|
static void checkTweensAreOrdered() {
|
|
checkOrder(PrimeTweenManager.Instance.tweens);
|
|
checkOrder(PrimeTweenManager.Instance.lateUpdateTweens);
|
|
checkOrder(PrimeTweenManager.Instance.fixedUpdateTweens);
|
|
void checkOrder(List<ReusableTween> tweens) {
|
|
Assert.IsTrue(tweens.OrderBy(_ => _.id).SequenceEqual(tweens));
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
[SuppressMessage("ReSharper", "PossibleNullReferenceException")]
|
|
public IEnumerator NewTweenCreatedFromNormalOnComplete() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
int numOnCompleteCalled = 0;
|
|
var t1 = createCustomTween(0.01f).OnComplete(() => {
|
|
numOnCompleteCalled++;
|
|
createCustomTween(0.01f);
|
|
createCustomTween(0.01f);
|
|
createCustomTween(0.01f);
|
|
});
|
|
Assert.AreEqual(1, tweensCount);
|
|
checkTweensAreOrdered();
|
|
while (t1.isAlive) {
|
|
yield return null;
|
|
}
|
|
Assert.AreEqual(1, numOnCompleteCalled);
|
|
Assert.AreEqual(3, tweensCount);
|
|
checkTweensAreOrdered();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator SetAllPaused() {
|
|
if (tweensCount != 0) {
|
|
var aliveCount = Tween.GetTweensCount();
|
|
Assert.AreEqual(Tween.StopAll(null), aliveCount);
|
|
}
|
|
Assert.AreEqual(0, tweensCount);
|
|
const int count = 10;
|
|
var tweens = new List<Tween>();
|
|
for (int i = 0; i < count; i++) {
|
|
tweens.Add(createCustomTween(1));
|
|
}
|
|
Assert.IsTrue(tweens.All(_ => !_.isPaused));
|
|
Assert.AreEqual(Tween.SetPausedAll(true, null), count);
|
|
Assert.IsTrue(tweens.All(_ => _.isPaused));
|
|
Assert.AreEqual(Tween.SetPausedAll(false, null), count);
|
|
Assert.IsTrue(tweens.All(_ => !_.isPaused));
|
|
Assert.IsTrue(tweens.All(_ => _.isAlive));
|
|
yield return null;
|
|
Assert.IsTrue(tweens.All(_ => _.isAlive));
|
|
foreach (var _ in tweens) {
|
|
_.Complete();
|
|
}
|
|
Assert.IsFalse(tweens.All(_ => _.isAlive));
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator StopAllCalledFromOnValueChange() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
int numOnValueChangeCalled = 0;
|
|
var t = Tween.Custom(this, 0, 1, 1f, delegate {
|
|
Assert.AreEqual(0, numOnValueChangeCalled);
|
|
numOnValueChangeCalled++;
|
|
var numStopped = Tween.StopAll(this);
|
|
Assert.AreEqual(1, numStopped);
|
|
});
|
|
Assert.IsTrue(t.isAlive);
|
|
yield return null;
|
|
yield return null;
|
|
Assert.IsFalse(t.isAlive);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator RecursiveCompleteCallFromOnValueChange() {
|
|
int numOnValueChangeCalled = 0;
|
|
int numOnCompleteCalled = 0;
|
|
Tween t = default;
|
|
t = Tween.Custom(this, 0, 1, 1f, delegate {
|
|
// Debug.Log(val);
|
|
numOnValueChangeCalled++;
|
|
Assert.IsTrue(numOnValueChangeCalled <= 2);
|
|
t.Complete();
|
|
}).OnComplete(() => numOnCompleteCalled++);
|
|
Assert.IsTrue(t.isAlive);
|
|
while (t.isAlive) {
|
|
yield return null;
|
|
}
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(1, numOnCompleteCalled);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator RecursiveCompleteAllCallFromOnValueChange() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
int numOnValueChangeCalled = 0;
|
|
int numOnCompleteCalled = 0;
|
|
var t = Tween.Custom(this, 0, 1, 1f, delegate {
|
|
// Debug.Log(val);
|
|
numOnValueChangeCalled++;
|
|
switch (numOnValueChangeCalled) {
|
|
case 1: {
|
|
var numCompleted = Tween.CompleteAll(this);
|
|
Assert.AreEqual(1, numCompleted);
|
|
break;
|
|
}
|
|
case 2: {
|
|
var numCompleted = Tween.CompleteAll(this);
|
|
Assert.AreEqual(0, numCompleted);
|
|
break;
|
|
}
|
|
default:
|
|
throw new Exception();
|
|
}
|
|
}).OnComplete(() => numOnCompleteCalled++);
|
|
Assert.IsTrue(t.isAlive);
|
|
while (t.isAlive) {
|
|
yield return null;
|
|
}
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(1, numOnCompleteCalled);
|
|
yield return null;
|
|
Assert.AreEqual(0, tweensCount);
|
|
Assert.AreEqual(2, numOnValueChangeCalled);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator RecursiveCompleteCallFromOnComplete() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
int numOnCompleteCalled = 0;
|
|
Tween t = default;
|
|
t = Tween.Custom(this, 0, 1, minDuration, delegate {
|
|
}).OnComplete(() => {
|
|
numOnCompleteCalled++;
|
|
t.Complete();
|
|
});
|
|
Assert.IsTrue(t.isAlive);
|
|
while (t.isAlive) {
|
|
yield return null;
|
|
}
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(1, numOnCompleteCalled);
|
|
yield return null;
|
|
Assert.AreEqual(0, tweensCount);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator RecursiveCompleteAllCallFromOnComplete() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
int numOnCompleteCalled = 0;
|
|
var t = Tween.Custom(this, 0, 1, minDuration, delegate {
|
|
}).OnComplete(() => {
|
|
numOnCompleteCalled++;
|
|
var numCompleted = Tween.CompleteAll(this);
|
|
Assert.AreEqual(0, numCompleted);
|
|
});
|
|
Assert.IsTrue(t.isAlive);
|
|
while (t.isAlive) {
|
|
yield return null;
|
|
}
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(1, numOnCompleteCalled);
|
|
yield return null;
|
|
Assert.AreEqual(0, tweensCount);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator StopAllCalledFromOnValueChange2() {
|
|
int numOnValChangedCalled = 0;
|
|
var t = Tween.Custom(this, 0, 1, 0.0001f, (_, val) => {
|
|
// Debug.Log(val);
|
|
Assert.AreEqual(0, val);
|
|
Assert.AreEqual(0, numOnValChangedCalled);
|
|
numOnValChangedCalled++;
|
|
var numStopped = Tween.StopAll(this);
|
|
Assert.AreEqual(1, numStopped);
|
|
});
|
|
Assert.IsTrue(t.isAlive);
|
|
yield return null;
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(1, numOnValChangedCalled);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenCanBeNullInProcessAllMethod() {
|
|
Assert.AreEqual(0, tweensCount);
|
|
Tween.Custom(this, 0, 1, 0.0001f, delegate {
|
|
// Debug.Log($"t1 val {val}");
|
|
});
|
|
Tween.Custom(this, 0, 1, 0.0001f, delegate {
|
|
// Debug.Log($"t2 val {val}");
|
|
Assert.AreEqual(0, getNullTweensCount());
|
|
Assert.AreEqual(Tween.StopAll(this), 2);
|
|
});
|
|
yield return null;
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenCanBeNullInOnComplete() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
int numOnCompleteCalled = 0;
|
|
Tween.Custom(this, 0, 1, 0.0001f, delegate{});
|
|
Tween.Custom(this, 0, 1, 0.0001f, delegate {
|
|
}).OnComplete(() => {
|
|
numOnCompleteCalled++;
|
|
Assert.AreEqual(1, getNullTweensCount());
|
|
var numStopped = Tween.StopAll(this);
|
|
Assert.AreEqual(0, numStopped);
|
|
});
|
|
yield return null;
|
|
Assert.AreEqual(1, numOnCompleteCalled);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenShouldBeDeadInOnValueChangeAfterCallingComplete() {
|
|
// Debug.Log(nameof(TweenShouldBeDeadInOnValueChangeAfterCallingComplete));
|
|
var target = new GameObject(nameof(TweenShouldBeDeadInOnValueChangeAfterCallingComplete));
|
|
int numOnValueChangeCalled = 0;
|
|
Tween t = default;
|
|
t = Tween.Custom(target, 0, 1, minDuration, (_, val) => {
|
|
// Debug.Log(val);
|
|
Assert.IsTrue(val == 0 || val == 1);
|
|
numOnValueChangeCalled++;
|
|
switch (numOnValueChangeCalled) {
|
|
case 1:
|
|
Assert.IsTrue(t.isAlive);
|
|
if (Random.value < 0.5f) {
|
|
t.Complete();
|
|
} else {
|
|
Assert.AreEqual(Tween.CompleteAll(target), 1);
|
|
}
|
|
break;
|
|
case 2:
|
|
// when Complete() is called, it's expected that onValueChange will be reported once again
|
|
break;
|
|
default: throw new Exception();
|
|
}
|
|
});
|
|
Assert.AreEqual(1, Tween.SetPausedAll(true, target));
|
|
Assert.AreEqual(1, Tween.SetPausedAll(false, target));
|
|
yield return null;
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(2, numOnValueChangeCalled);
|
|
}
|
|
|
|
[Test]
|
|
public void NumProcessed() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
var target1 = new object();
|
|
var target2 = new object();
|
|
|
|
createWithTarget1(); // 1
|
|
createWithTarget1(); // 2
|
|
createWithTarget1(); // 3
|
|
createWithTarget2(); // 1
|
|
createWithTarget2(); // 2
|
|
createWithTarget1(); // 4
|
|
createWithTarget2(); // 3
|
|
|
|
Assert.AreEqual(4, Tween.SetPausedAll(true, target1));
|
|
Assert.AreEqual(4, Tween.SetPausedAll(false, target1));
|
|
Assert.AreEqual(4, Tween.StopAll(target1));
|
|
Assert.AreEqual(0, Tween.StopAll(target1));
|
|
Assert.AreEqual(0, Tween.CompleteAll(target1));
|
|
Assert.AreEqual(0, Tween.SetPausedAll(true, target1));
|
|
|
|
Assert.AreEqual(3, Tween.SetPausedAll(true, target2));
|
|
Assert.AreEqual(3, Tween.SetPausedAll(false, target2));
|
|
Assert.AreEqual(3, Tween.CompleteAll(target2));
|
|
Assert.AreEqual(0, Tween.CompleteAll(target2));
|
|
Assert.AreEqual(0, Tween.StopAll(target2));
|
|
|
|
void createWithTarget1() => Tween.Custom(target1, 0, 1, 0.0001f, delegate { });
|
|
void createWithTarget2() => Tween.Custom(target2, 0, 1, 0.0001f, delegate { });
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenIsAliveForWholeDuration() {
|
|
int numOnValueChangedCalled = 0;
|
|
int numOnValueChangedCalledAfterComplete = 0;
|
|
Tween t = default;
|
|
var target = new object();
|
|
bool isCompleteCalled = false;
|
|
const float duration = 0.3f;
|
|
t = Tween.Custom(target, 0, 1, duration, (_, val) => {
|
|
// Debug.Log(val);
|
|
numOnValueChangedCalled++;
|
|
if (isCompleteCalled) {
|
|
numOnValueChangedCalledAfterComplete++;
|
|
}
|
|
Assert.AreEqual(!isCompleteCalled, t.isAlive);
|
|
if (val > duration / 2) {
|
|
isCompleteCalled = true;
|
|
t.Complete();
|
|
}
|
|
}).OnComplete(() => {
|
|
Assert.IsTrue(t.IsCreated);
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(0, Tween.StopAll(target));
|
|
});
|
|
while (t.isAlive) {
|
|
yield return null;
|
|
}
|
|
Assert.IsTrue(numOnValueChangedCalled > 1);
|
|
Assert.AreEqual(1, numOnValueChangedCalledAfterComplete);
|
|
}
|
|
|
|
[Test]
|
|
public void SetPauseAll() {
|
|
var target = new object();
|
|
var t = Tween.Custom(target, 0, 1, 1, delegate{});
|
|
Assert.AreEqual(0, Tween.SetPausedAll(false, target));
|
|
Assert.AreEqual(1, Tween.SetPausedAll(true, target));
|
|
Assert.AreEqual(0, Tween.SetPausedAll(true, target));
|
|
Assert.AreEqual(1, Tween.SetPausedAll(false, target));
|
|
Assert.AreEqual(0, Tween.SetPausedAll(false, target));
|
|
t.Stop();
|
|
Assert.AreEqual(0, Tween.SetPausedAll(true, target));
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator StopByTargetFromOnValueChange() {
|
|
var target = new GameObject();
|
|
int numOnValueChangeCalled = 0;
|
|
var t = Tween.Custom(target, 0, 1, 1, delegate {
|
|
numOnValueChangeCalled++;
|
|
var numStopped = Tween.StopAll(target);
|
|
Assert.AreEqual(1, numStopped);
|
|
});
|
|
Assert.AreEqual(0, numOnValueChangeCalled);
|
|
Assert.IsTrue(t.isAlive);
|
|
yield return null;
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(1, numOnValueChangeCalled);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenPropertiesDefault() {
|
|
if (tweensCount != 0) {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
}
|
|
{
|
|
yield return Tween.Delay(0.001f).ToYieldInstruction();
|
|
Assert.AreEqual(1, tweensCount);
|
|
yield return null;
|
|
Assert.AreEqual(0, tweensCount);
|
|
}
|
|
{
|
|
var t = Tween.Delay(0f);
|
|
Assert.IsTrue(t.isAlive);
|
|
validate(t, true);
|
|
}
|
|
{
|
|
var t = new Tween();
|
|
Assert.IsFalse(t.isAlive);
|
|
expectError(false);
|
|
Assert.AreEqual(0, t.cyclesTotal);
|
|
validate(t, false, false);
|
|
}
|
|
{
|
|
var t = Tween.Delay(1);
|
|
t.Complete();
|
|
Assert.IsFalse(t.isAlive);
|
|
expectError();
|
|
Assert.AreEqual(0, t.cyclesTotal);
|
|
validate(t, false);
|
|
}
|
|
{
|
|
var t = Tween.Delay(1);
|
|
t.Stop();
|
|
Assert.IsFalse(t.isAlive);
|
|
expectError();
|
|
Assert.AreEqual(0, t.cyclesTotal);
|
|
validate(t, false);
|
|
}
|
|
void validate(Tween t, bool isAlive, bool isCreated = true) {
|
|
if (!isAlive) {
|
|
for (int i = 0; i < 8; i++) {
|
|
expectError(isCreated);
|
|
}
|
|
}
|
|
Assert.AreEqual(0, t.elapsedTime);
|
|
Assert.AreEqual(0, t.elapsedTimeTotal);
|
|
Assert.AreEqual(0, t.cyclesDone);
|
|
Assert.AreEqual(0, t.duration);
|
|
Assert.AreEqual(0, t.durationTotal);
|
|
Assert.AreEqual(0, t.progress);
|
|
Assert.AreEqual(0, t.progressTotal);
|
|
Assert.AreEqual(0, t.interpolationFactor);
|
|
if (!isAlive) {
|
|
expectError(isCreated);
|
|
}
|
|
Assert.AreEqual(1, t.timeScale);
|
|
}
|
|
{
|
|
const float duration = 0.123f;
|
|
var t = Tween.PositionY(transform, 0, duration, Ease.Linear, -1);
|
|
Assert.AreEqual(duration, t.duration);
|
|
Assert.IsTrue(float.IsPositiveInfinity(t.durationTotal));
|
|
Assert.AreEqual(0, t.progress);
|
|
Assert.AreEqual(0, t.progressTotal);
|
|
t.Stop();
|
|
validate(t, false);
|
|
}
|
|
|
|
void expectError(bool isCreated = true) {
|
|
expectIsDeadError(isCreated);
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenProperties() {
|
|
float duration = Mathf.Max(minDuration, getDt() * Random.Range(0.5f, 5f));
|
|
int numCyclesExpected = Random.Range(1, 3);
|
|
Tween t = default;
|
|
float startDelay = getDt() * Random.Range(0.1f, 1.2f);
|
|
float endDelay = getDt() * Random.Range(0.1f, 1.2f);
|
|
float durationExpected = startDelay + duration + endDelay;
|
|
float totalDurationExpected = durationExpected * numCyclesExpected;
|
|
float timeStart = Time.time;
|
|
t = Tween.Custom(this, 1f, 2f, duration, ease: Ease.Linear, cycles: numCyclesExpected, startDelay: startDelay, endDelay: endDelay, onValueChange: (_, val) => {
|
|
val -= 1f;
|
|
var elapsedTimeTotalExpected = Time.time - timeStart;
|
|
var elapsedTimeExpected = elapsedTimeTotalExpected - durationExpected * t.cyclesDone;
|
|
// Debug.Log($"val: {val}, progress: {t.progress}, elapsedTimeExpected: {elapsedTimeExpected}, elapsedTimeTotalExpected: {elapsedTimeTotalExpected}");
|
|
const float tolerance = 0.001f;
|
|
if (val < 1) {
|
|
Assert.AreEqual(elapsedTimeExpected, t.elapsedTime, tolerance);
|
|
Assert.AreEqual(elapsedTimeTotalExpected, t.elapsedTimeTotal, tolerance, $"val: {val},duration: {duration}, numCyclesExpected: {numCyclesExpected}");
|
|
Assert.AreEqual(Mathf.Min(elapsedTimeTotalExpected / totalDurationExpected, 1f), t.progressTotal, tolerance);
|
|
Assert.AreEqual(elapsedTimeExpected / durationExpected, t.progress, tolerance);
|
|
}
|
|
Assert.AreEqual(numCyclesExpected, t.cyclesTotal);
|
|
Assert.AreEqual(durationExpected, t.duration);
|
|
Assert.AreEqual(totalDurationExpected, t.durationTotal);
|
|
Assert.AreEqual(t.interpolationFactor, val, tolerance);
|
|
});
|
|
yield return t.ToYieldInstruction();
|
|
Assert.IsFalse(t.isAlive);
|
|
for (int i = 0; i < 2; i++) {
|
|
expectIsDeadError();
|
|
}
|
|
Assert.AreEqual(0, t.progress);
|
|
Assert.AreEqual(0, t.progressTotal);
|
|
|
|
var infT = Tween.Position(transform, Vector3.one, minDuration, cycles: -1);
|
|
Assert.IsTrue(infT.isAlive);
|
|
Assert.AreEqual(-1, infT.cyclesTotal);
|
|
infT.Complete();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ZeroDurationOnTweenShouldReportValueAtLeastOnce() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
Assert.AreEqual(capacityForTest, tweensCapacity);
|
|
|
|
const float p1 = 0.345f;
|
|
Tween.PositionZ(transform, 0, p1, 0f).Complete();
|
|
UnityEngine.Assertions.Assert.AreApproximatelyEqual(p1, transform.position.z);
|
|
|
|
const float p2 = 0.123f;
|
|
Tween.PositionZ(transform, p2, 0).Complete();
|
|
UnityEngine.Assertions.Assert.AreApproximatelyEqual(p2, transform.position.z);
|
|
|
|
const float p3 = 0.456f;
|
|
Tween.PositionZ(transform, p3, 0);
|
|
yield return null;
|
|
UnityEngine.Assertions.Assert.AreApproximatelyEqual(p3, transform.position.z);
|
|
|
|
yield return Tween.PositionZ(transform, p1, 0).OnComplete(() => { }).ToYieldInstruction();
|
|
UnityEngine.Assertions.Assert.AreApproximatelyEqual(p1, transform.position.z);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator OneShouldBeReportedExactlyOnce() {
|
|
int numOneReported = 0;
|
|
const int cycles = 1;
|
|
for (int i = 0; i < 1; i++) {
|
|
numOneReported = 0;
|
|
yield return Tween.Custom(this, 0, 1, getDt() * Random.Range(0.5f, 1.5f), startDelay: getDt() * Random.Range(0.1f, 1.1f), endDelay: getDt() * Random.Range(0.5f, 3f), cycles: cycles, onValueChange: (_, val) => {
|
|
// print($"val: {val}");
|
|
if (val == 1f) {
|
|
numOneReported++;
|
|
}
|
|
}).ToYieldInstruction();
|
|
Assert.AreEqual(cycles, numOneReported);
|
|
}
|
|
|
|
numOneReported = 0;
|
|
yield return Tween.Custom(this, 0, 1, 0f, startDelay: getDt() * Random.Range(0.1f, 1.1f), endDelay: getDt() * Random.Range(0.1f, 1.1f), cycles: cycles, onValueChange: (_, val) => {
|
|
if (val == 1) {
|
|
numOneReported++;
|
|
}
|
|
}).ToYieldInstruction();
|
|
Assert.AreEqual(cycles, numOneReported);
|
|
|
|
numOneReported = 0;
|
|
yield return Tween.Custom(this, 0, 1, 0f, cycles: cycles, onValueChange: (_, val) => {
|
|
if (val == 1) {
|
|
numOneReported++;
|
|
}
|
|
}).ToYieldInstruction();
|
|
Assert.AreEqual(cycles, numOneReported);
|
|
|
|
numOneReported = 0;
|
|
yield return Tween.Custom(this, 0, 1, 0f, (_, val) => {
|
|
if (val == 1) {
|
|
numOneReported++;
|
|
}
|
|
}).ToYieldInstruction();
|
|
Assert.AreEqual(1, numOneReported);
|
|
|
|
yield return Tween.PositionY(transform, 3.14f, Mathf.Max(minDuration, getDt() * Random.Range(0.1f, 1.1f))).ToYieldInstruction();
|
|
yield return Tween.PositionY(transform, 3.14f, 0f).ToYieldInstruction();
|
|
yield return Tween.PositionY(transform, 0, 3.14f, 0f).ToYieldInstruction();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator SingleFrameTween() {
|
|
Application.targetFrameRate = 200;
|
|
for (int i = 0; i < 1; i++) {
|
|
int numOnValueChangeCalled = 0;
|
|
yield return Tween.Custom(this, 0, 1, 0.0001f, (_, val) => {
|
|
numOnValueChangeCalled++;
|
|
Assert.IsTrue(val == 0 || val == 1);
|
|
}).ToYieldInstruction();
|
|
Assert.AreEqual(2, numOnValueChangeCalled);
|
|
}
|
|
Application.targetFrameRate = targetFrameRate;
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweensWithDurationOfDeltaTime() {
|
|
for (int i = 0; i < 1; i++) {
|
|
var go = new GameObject();
|
|
go.AddComponent<TweensWithDurationOfDeltaTime>();
|
|
// ReSharper disable once LoopVariableIsNeverChangedInsideLoop
|
|
while (go != null) {
|
|
yield return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenWithExactDurationOfDeltaTime1() {
|
|
yield return Tween.Delay(this, Time.deltaTime).ToYieldInstruction();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenWithExactDurationOfDeltaTime2() {
|
|
int numOnCompleteCalled = 0;
|
|
yield return Tween.Delay(this, Time.deltaTime, () => numOnCompleteCalled++).ToYieldInstruction();
|
|
Assert.AreEqual(1, numOnCompleteCalled);
|
|
}
|
|
|
|
[Test]
|
|
public void TotalDurationWithCycles() {
|
|
var duration = Random.value;
|
|
var startDelay = Random.value;
|
|
var endDelay = Random.value;
|
|
var cycles = Random.Range(1, 10);
|
|
var t = Tween.LocalPositionY(transform, new TweenSettings<float>(0, 1, duration, cycles: cycles, startDelay: startDelay, endDelay: endDelay));
|
|
var durationTotalExpected = duration + startDelay + endDelay;
|
|
const float tolerance = 0.0001f;
|
|
Assert.AreEqual(durationTotalExpected, t.duration, tolerance);
|
|
Assert.AreEqual(durationTotalExpected * cycles, t.durationTotal, tolerance);
|
|
Assert.AreEqual(durationTotalExpected * cycles, t.durationTotal, tolerance);
|
|
t.Complete();
|
|
}
|
|
|
|
[Test]
|
|
public void DurationWithWaitDependencies() {
|
|
var t1Dur = Random.value;
|
|
var t1Cycles = Random.Range(1, 20);
|
|
var t2Dur = Random.value;
|
|
var t2Cycles = Random.Range(1, 20);
|
|
// const int t1Dur = 1;
|
|
// const int t1Cycles = 2;
|
|
// const int t2Dur = 2;
|
|
// const int t2Cycles = 2;
|
|
var t1 = Tween.LocalPositionX(transform, 1, t1Dur, cycles: t1Cycles);
|
|
var t2 = Tween.LocalPositionX(transform, 1, t2Dur, cycles: t2Cycles);
|
|
var s = t1.Chain(t2);
|
|
Assert.IsTrue(t1.isAlive);
|
|
Assert.IsTrue(t2.isAlive);
|
|
Assert.AreEqual(t1Dur * t1Cycles, t1.durationTotal);
|
|
Assert.AreEqual(t2Dur * t2Cycles, t2.durationTotal);
|
|
Assert.AreEqual(t1Dur * t1Cycles, t1.durationWithWaitDelay);
|
|
Assert.AreEqual(t1Dur * t1Cycles + t2Dur * t2Cycles, t2.durationWithWaitDelay, 0.001f);
|
|
s.Complete();
|
|
}
|
|
|
|
|
|
[Test]
|
|
public void AwaitingDeadCompletesImmediately() {
|
|
bool isCompleted = false;
|
|
AwaitingDeadCompletesImmediatelyAsync(() => isCompleted = true);
|
|
Assert.IsTrue(isCompleted);
|
|
}
|
|
|
|
static async void AwaitingDeadCompletesImmediatelyAsync([NotNull] Action callback) {
|
|
var frame = Time.frameCount;
|
|
await new Tween();
|
|
await new Sequence();
|
|
Assert.AreEqual(frame, Time.frameCount);
|
|
callback();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TestAwaitByCallback() {
|
|
bool isCompleted = false;
|
|
var t = Tween.Delay(getDt() * 5f);
|
|
waitForTweenAsync(t, () => isCompleted = true);
|
|
Assert.IsFalse(isCompleted);
|
|
yield return null;
|
|
Assert.IsFalse(isCompleted);
|
|
yield return t.ToYieldInstruction();
|
|
Assert.IsTrue(isCompleted);
|
|
}
|
|
|
|
static async void waitForTweenAsync(Tween tween, [NotNull] Action callback) {
|
|
await tween;
|
|
callback();
|
|
}
|
|
|
|
[Test]
|
|
public async Task AwaitTweenWithCallback() {
|
|
bool isCompleted = false;
|
|
var t = Tween.Delay(getDt() * 2f,() => isCompleted = true);
|
|
Assert.IsTrue(t.isAlive);
|
|
Assert.IsTrue(t.tween.HasOnComplete);
|
|
await t;
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.IsTrue(isCompleted);
|
|
}
|
|
|
|
const float minDuration = TweenSettings.minDuration;
|
|
|
|
[Test]
|
|
public async Task AwaitTweenWithCallbackDoesntPostpone() {
|
|
bool isCompleted = false;
|
|
var t = Tween.Delay(minDuration,() => isCompleted = true);
|
|
Assert.IsTrue(t.isAlive);
|
|
Assert.IsTrue(t.tween.HasOnComplete);
|
|
var frameStart = Time.frameCount;
|
|
await t;
|
|
Assert.AreEqual(1, Time.frameCount - frameStart);
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.IsTrue(isCompleted);
|
|
}
|
|
|
|
[Test]
|
|
public async Task AwaitSequence() {
|
|
bool isCompleted1 = false;
|
|
bool isCompleted2 = false;
|
|
await Sequence.Create(Tween.Delay(0.01f, () => isCompleted1 = true))
|
|
.Chain(Tween.Delay(0.02f, () => isCompleted2 = true));
|
|
Assert.IsTrue(isCompleted1);
|
|
Assert.IsTrue(isCompleted2);
|
|
}
|
|
|
|
[Test]
|
|
public async Task AwaitSequence2() {
|
|
var t1 = Tween.Delay(getDt());
|
|
var t2 = Tween.Delay(getDt());
|
|
await t1.Chain(t2);
|
|
Assert.IsFalse(t1.isAlive);
|
|
Assert.IsFalse(t2.isAlive);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ToYieldInstruction() {
|
|
var t = Tween.Delay(0.1f);
|
|
var e = t.ToYieldInstruction();
|
|
var frameStart = Time.frameCount;
|
|
while (e.MoveNext()) {
|
|
yield return e.Current;
|
|
t.Complete();
|
|
}
|
|
Assert.AreEqual(1, Time.frameCount - frameStart);
|
|
Assert.IsFalse(t.isAlive);
|
|
yield return t.ToYieldInstruction();
|
|
|
|
Tween defaultTween = default;
|
|
defaultTween.ToYieldInstruction();
|
|
|
|
Sequence defaultSequence = default;
|
|
defaultSequence.ToYieldInstruction();
|
|
|
|
t.Complete();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ImplicitConversionToIterator() {
|
|
PrimeTweenConfig.warnStructBoxingAllocationInCoroutine = true;
|
|
{
|
|
var t2 = Tween.Delay(0.0001f);
|
|
var frameStart = Time.frameCount;
|
|
expectCoroutineBoxingWarning();
|
|
yield return t2;
|
|
Assert.AreEqual(1, Time.frameCount - frameStart);
|
|
Assert.IsFalse(t2.isAlive);
|
|
}
|
|
{
|
|
var s = Sequence.Create(Tween.Delay(0.0001f));
|
|
var frameStart = Time.frameCount;
|
|
// iterator boxing warning is shown only once
|
|
yield return s;
|
|
Assert.AreEqual(1, Time.frameCount - frameStart);
|
|
Assert.IsFalse(s.isAlive);
|
|
}
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[Test]
|
|
public async Task AwaitInfiniteTweenComplete() {
|
|
Tween t = default;
|
|
int numCompleted = 0;
|
|
t = Tween.Custom(this, 0, 1, 1, cycles: -1, onValueChange: delegate { t.Complete(); })
|
|
.OnComplete(() => numCompleted++);
|
|
await t;
|
|
Assert.AreEqual(1, numCompleted);
|
|
}
|
|
|
|
[Test]
|
|
public async Task AwaitInfiniteTweenStop() {
|
|
Tween t = default;
|
|
int numOnValueChanged = 0;
|
|
t = Tween.Custom(this, 0, 1, 1f, cycles: -1, onValueChange: delegate {
|
|
// Debug.Log(numOnValueChanged);
|
|
numOnValueChanged++;
|
|
Assert.AreEqual(1, numOnValueChanged);
|
|
Assert.IsTrue(t.isAlive);
|
|
t.Stop();
|
|
});
|
|
Assert.IsTrue(t.isAlive);
|
|
await t;
|
|
Assert.IsFalse(t.isAlive);
|
|
Assert.AreEqual(1, numOnValueChanged);
|
|
}
|
|
|
|
[Test]
|
|
public async Task TweenStoppedTweenWhileAwaiting() {
|
|
var t = Tween.Delay(0.05f);
|
|
#pragma warning disable CS4014
|
|
Tween.Delay(0.01f).OnComplete(() => t.Stop());
|
|
#pragma warning restore CS4014
|
|
Assert.IsTrue(t.isAlive);
|
|
await t;
|
|
Assert.IsFalse(t.isAlive);
|
|
}
|
|
|
|
[Test]
|
|
public void InvalidDurations() {
|
|
Assert.Throws<AssertionException>(() => Tween.Delay(float.NaN), Constants.durationInvalidError);
|
|
Assert.Throws<AssertionException>(() => Tween.Delay(float.PositiveInfinity), Constants.durationInvalidError);
|
|
Assert.Throws<AssertionException>(() => Tween.Delay(float.NegativeInfinity), Constants.durationInvalidError);
|
|
Assert.Throws<AssertionException>(() => Tween.PositionZ(transform, new TweenSettings<float>(0, 1, new TweenSettings(1, startDelay: float.NaN))), Constants.durationInvalidError);
|
|
Assert.Throws<AssertionException>(() => Tween.PositionZ(transform, new TweenSettings<float>(0, 1, new TweenSettings(1, startDelay: float.PositiveInfinity))), Constants.durationInvalidError);
|
|
Assert.Throws<AssertionException>(() => Tween.PositionZ(transform, new TweenSettings<float>(0, 1, new TweenSettings(1, startDelay: float.NegativeInfinity))), Constants.durationInvalidError);
|
|
Assert.Throws<AssertionException>(() => Tween.PositionZ(transform, new TweenSettings<float>(0, 1, new TweenSettings(1, endDelay: float.NaN))), Constants.durationInvalidError);
|
|
Assert.Throws<AssertionException>(() => Tween.PositionZ(transform, new TweenSettings<float>(0, 1, new TweenSettings(1, endDelay: float.PositiveInfinity))), Constants.durationInvalidError);
|
|
Assert.Throws<AssertionException>(() => Tween.PositionZ(transform, new TweenSettings<float>(0, 1, new TweenSettings(1, endDelay: float.NegativeInfinity))), Constants.durationInvalidError);
|
|
}
|
|
|
|
[Test]
|
|
public void MaterialTweens() {
|
|
{
|
|
var s = Shader.Find("Standard");
|
|
if (s == null) {
|
|
Assert.Ignore();
|
|
return;
|
|
}
|
|
var m = new Material(s);
|
|
|
|
{
|
|
const string propName = "_EmissionColor";
|
|
#if UNITY_2021_1_OR_NEWER
|
|
Assert.IsTrue(m.HasColor(propName));
|
|
#endif
|
|
var to = Color.red;
|
|
Tween.MaterialColor(m, Shader.PropertyToID(propName), to, 1f).Complete();
|
|
Assert.AreEqual(to, m.GetColor(propName));
|
|
}
|
|
{
|
|
const string propName = "_EmissionColor";
|
|
#if UNITY_2021_1_OR_NEWER
|
|
Assert.IsTrue(m.HasColor(propName));
|
|
#endif
|
|
var iniColor = new Color(Random.value, Random.value, Random.value, Random.value);
|
|
m.SetColor(propName, iniColor);
|
|
var toAlpha = Random.value;
|
|
Tween.MaterialAlpha(m, Shader.PropertyToID(propName), toAlpha, 1f).Complete();
|
|
var col = m.GetColor(propName);
|
|
UnityEngine.Assertions.Assert.AreApproximatelyEqual(col.r, iniColor.r);
|
|
UnityEngine.Assertions.Assert.AreApproximatelyEqual(col.g, iniColor.g);
|
|
UnityEngine.Assertions.Assert.AreApproximatelyEqual(col.b, iniColor.b);
|
|
UnityEngine.Assertions.Assert.AreApproximatelyEqual(col.a, toAlpha);
|
|
}
|
|
{
|
|
const string propName = "_Cutoff";
|
|
#if UNITY_2021_1_OR_NEWER
|
|
Assert.IsTrue(m.HasFloat(propName));
|
|
#endif
|
|
var to = Random.value;
|
|
Tween.MaterialProperty(m, Shader.PropertyToID(propName), to, 1f).Complete();
|
|
UnityEngine.Assertions.Assert.AreApproximatelyEqual(to, m.GetFloat(propName));
|
|
}
|
|
{
|
|
const string propName = "_MainTex";
|
|
#if UNITY_2021_1_OR_NEWER
|
|
Assert.IsTrue(m.HasTexture(propName));
|
|
#endif
|
|
var to = Random.value * Vector2.one;
|
|
Tween.MaterialTextureOffset(m, Shader.PropertyToID(propName), to, 1f).Complete();
|
|
Assert.AreEqual(to, m.GetTextureOffset(propName));
|
|
}
|
|
{
|
|
const string propName = "_MainTex";
|
|
#if UNITY_2021_1_OR_NEWER
|
|
Assert.IsTrue(m.HasTexture(propName));
|
|
#endif
|
|
var to = Random.value * Vector2.one;
|
|
Tween.MaterialTextureScale(m, Shader.PropertyToID(propName), to, 1f).Complete();
|
|
Assert.IsTrue(to == m.GetTextureScale(propName));
|
|
}
|
|
}
|
|
|
|
{
|
|
var m = Resources.Load<Material>("Custom_TestShader");
|
|
Assert.IsNotNull(m);
|
|
const string propName = "_TestVectorProp";
|
|
var to = Random.value * Vector4.one;
|
|
Tween.MaterialProperty(m, Shader.PropertyToID(propName), to, 1f).Complete();
|
|
Assert.IsTrue(to == m.GetVector(propName));
|
|
}
|
|
}
|
|
|
|
/// passing the serialized UnityEngine.Object reference that is not populated behaves like passing destroyed object
|
|
[Test]
|
|
public void PassingDestroyedUnityTarget() {
|
|
LogAssert.NoUnexpectedReceived();
|
|
|
|
var target = new GameObject().transform;
|
|
Object.DestroyImmediate(target.gameObject);
|
|
|
|
var s = Sequence.Create();
|
|
expectError();
|
|
s.ChainCallback(target, delegate { });
|
|
|
|
expectError();
|
|
Assert.IsFalse(Tween.Delay(target, 0.1f, delegate { }).IsCreated);
|
|
expectError();
|
|
Assert.IsFalse(Tween.Delay(target, 0.1f).IsCreated);
|
|
expectError();
|
|
Assert.IsFalse(Tween.Delay(target, 0.1f, () => {}).IsCreated);
|
|
|
|
expectError();
|
|
Assert.IsFalse(Tween.Position(target, new TweenSettings<Vector3>(default, default, 0.1f)).IsCreated);
|
|
|
|
expectError();
|
|
var deadTween = Tween.Custom(target, 0f, 0, 0.1f, delegate { });
|
|
Assert.IsFalse(deadTween.isAlive);
|
|
expectAddDeadToSequenceError();
|
|
Sequence.Create(deadTween);
|
|
|
|
LogAssert.Expect(LogType.Error, "Shake's strength is (0, 0, 0).");
|
|
LogAssert.Expect(LogType.Error, new Regex("Shake's frequency should be > 0f"));
|
|
expectError();
|
|
Tween.ShakeLocalPosition(target, default);
|
|
|
|
void expectError() {
|
|
expectTargetIsNull();
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void ShakeSettings() {
|
|
{
|
|
var s = new ShakeSettings(Vector3.one, 1f, 1);
|
|
Assert.IsTrue(s.enableFalloff);
|
|
}
|
|
{
|
|
var s = new ShakeSettings(Vector3.one, 1f, 1, true, Ease.InBack);
|
|
Assert.IsTrue(s.enableFalloff);
|
|
}
|
|
{
|
|
var s = new ShakeSettings(Vector3.one, 1f, 1, AnimationCurve.Linear(0,0,1,1));
|
|
Assert.IsTrue(s.enableFalloff);
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ForceCompleteWhenWaitingForEndDelay() {
|
|
var t = Tween.ShakeLocalPosition(transform, new ShakeSettings(Vector3.one, getDt() * 2f, endDelay: 100f));
|
|
while (t.interpolationFactor < 1f) {
|
|
yield return null;
|
|
}
|
|
Assert.IsTrue(t.isAlive);
|
|
t.Complete();
|
|
Assert.IsFalse(t.isAlive);
|
|
}
|
|
|
|
static void print(object o) => Debug.Log($"[{Time.frameCount}] {o}");
|
|
|
|
[UnityTest]
|
|
public IEnumerator StopAtEvenOrOddCycle() {
|
|
for (int i = 0; i < 5; i++) {
|
|
var t = Tween.Rotation(transform, Vector3.one, getDt() * 5f, cycles: 10, cycleMode: CycleMode.Yoyo);
|
|
while (t.cyclesDone < Random.Range(2, 4)) {
|
|
yield return null;
|
|
}
|
|
t.SetRemainingCycles(true);
|
|
Assert.AreEqual(t.cyclesDone % 2 + 1, t.cyclesTotal - t.cyclesDone);
|
|
t.SetRemainingCycles(false);
|
|
Assert.AreEqual(t.cyclesDone % 2, (t.cyclesTotal - t.cyclesDone) % 2);
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator SetCycles() {
|
|
var t = Tween.Rotation(transform, Vector3.one, Mathf.Max(minDuration, getDt()) * 10, cycles: 10);
|
|
while (t.cyclesDone != 2) {
|
|
yield return null;
|
|
}
|
|
t.SetRemainingCycles(3);
|
|
Assert.AreEqual(2, t.cyclesDone);
|
|
Assert.AreEqual(5, t.cyclesTotal);
|
|
t.Complete();
|
|
}
|
|
|
|
[Test]
|
|
public void DOTweenAdapterEnabled() {
|
|
#if !PRIME_TWEEN_DOTWEEN_ADAPTER
|
|
Assert.Inconclusive();
|
|
#endif
|
|
}
|
|
|
|
[Test]
|
|
public void ExperimentalDefineSet() {
|
|
#if PRIME_TWEEN_EXPERIMENTAL
|
|
Assert.Ignore("Please remove the PRIME_TWEEN_EXPERIMENTAL define and run all tests again.");
|
|
#endif
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator RecursiveKillAllCall() {
|
|
// Calling Tween.StopAll/Complete() from onValueChange previously threw the 'Please don't call Tween.StopAll/CompleteAll() from the OnComplete() callback' exception before.
|
|
// But this no longer the case - current impl checks if Update/FixedUpdate() is safe to call
|
|
yield return Tween.Custom(0, 1, 1f, val => {
|
|
if (val != 0) {
|
|
Tween.StopAll();
|
|
}
|
|
}).ToYieldInstruction();
|
|
|
|
yield return Tween.Custom(0, 1, 0.01f, _ => {
|
|
Tween.CompleteAll();
|
|
}).ToYieldInstruction();
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator KillAllIsImmediate() {
|
|
Tween.Delay(0.01f);
|
|
Tween.StopAll(null);
|
|
Assert.AreEqual(0, tweensCount);
|
|
Tween.Delay(0.01f);
|
|
Assert.AreEqual(1, tweensCount);
|
|
Assert.AreEqual(Tween.CompleteAll(null), 1);
|
|
Assert.AreEqual(0, tweensCount);
|
|
yield return null;
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[Test]
|
|
public void SetCapacityImmediatelyAfterStopAll() {
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
PrimeTweenConfig.SetTweensCapacity(2);
|
|
Tween.Delay(0.01f);
|
|
Tween.Delay(0.01f);
|
|
Assert.AreEqual(2, tweensCount);
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, tweensCount);
|
|
PrimeTweenConfig.SetTweensCapacity(1);
|
|
PrimeTweenConfig.SetTweensCapacity(capacityForTest);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator RotationShakeEndVal() {
|
|
var target = new GameObject(nameof(RotationShakeEndVal)).transform;
|
|
var iniRot = Random.rotation.normalized;
|
|
var strength = Random.insideUnitSphere;
|
|
var freq = Random.value * 10;
|
|
target.rotation = iniRot;
|
|
var handle = Tween.ShakeLocalRotation(target, strength, 1f, freq);
|
|
// skip frame so cacheDiff() is called
|
|
yield return null;
|
|
Assert.IsTrue(handle.isAlive);
|
|
var t = handle.tween;
|
|
Assert.IsTrue(iniRot == t.startValue.QuaternionVal);
|
|
Assert.IsTrue(Quaternion.identity == t.endValue.QuaternionVal);
|
|
Assert.AreEqual(strength, t.shakeData.strengthPerAxis);
|
|
Assert.AreEqual(freq, t.shakeData.frequency);
|
|
Object.Destroy(target.gameObject);
|
|
handle.Stop();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator AtSpeed() {
|
|
var target = new GameObject(nameof(AtSpeed)).transform;
|
|
var speed = (Random.value + 0.1f) * 10f;
|
|
const double tolerance = 0.001;
|
|
var endValue = new Vector3(1, 0,0);
|
|
{
|
|
Assert.AreEqual(Vector3.zero, target.position);
|
|
var t = Tween.PositionAtSpeed(target, endValue, speed);
|
|
Assert.AreEqual(speed, 1 / t.duration, tolerance);
|
|
yield return null;
|
|
Assert.AreEqual(speed, 1 / t.duration, tolerance);
|
|
t.Stop();
|
|
}
|
|
{
|
|
target.position = Vector3.zero;
|
|
Tween.PositionAtSpeed(target, endValue, speed).Complete();
|
|
Assert.AreEqual(endValue, target.position);
|
|
}
|
|
{
|
|
target.position = Vector3.zero;
|
|
float startDelay = getDt();
|
|
var t = Tween.PositionAtSpeed(target, endValue, speed, startDelay: startDelay);
|
|
var expectedDuration = 1 / speed + startDelay;
|
|
while (t.interpolationFactor == 0) {
|
|
Assert.AreEqual(expectedDuration, t.duration, tolerance);
|
|
yield return null;
|
|
}
|
|
Assert.AreEqual(expectedDuration, t.duration, tolerance);
|
|
yield return null;
|
|
Assert.AreEqual(expectedDuration, t.duration, tolerance);
|
|
t.Stop();
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator DelayInterpolationFactor() {
|
|
for (int i = 0; i < 1; i++) {
|
|
float duration = Random.Range(0.001f, 0.1f);
|
|
var d = Tween.Delay(duration);
|
|
float timeStart = Time.time;
|
|
while (d.isAlive) {
|
|
Assert.AreEqual(Mathf.Min(1f, (Time.time - timeStart) / duration), d.interpolationFactor, 0.001f);
|
|
yield return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void TweensCount() {
|
|
Tween.StopAll();
|
|
int count = Random.Range(1, 10);
|
|
for (int i = 0; i < count; i++) {
|
|
Tween.PositionX(transform, 10, 0.01f);
|
|
}
|
|
Assert.AreEqual(count, Tween.GetTweensCount());
|
|
Assert.AreEqual(count, Tween.GetTweensCount(transform));
|
|
Tween.StopAll();
|
|
Assert.AreEqual(0, Tween.GetTweensCount());
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator StopCalledOnLastTweenFrame() {
|
|
float dt = getDt();
|
|
Tween tween = default;
|
|
tween = Tween.Custom(0, 1, dt * 3, val => {
|
|
if (val == 1f) {
|
|
tween.Stop();
|
|
Assert.IsFalse(tween.isAlive);
|
|
}
|
|
}).OnComplete(() => Assert.Fail());
|
|
yield return tween.ToYieldInstruction();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator StopCalledOnLastTweenFrameFromOnUpdate() {
|
|
Tween tween = default;
|
|
float duration = getDt() * 3f;
|
|
tween = Tween.Custom(0, 1, duration, delegate { })
|
|
.OnUpdate(this, delegate {
|
|
if (tween.interpolationFactor == 1f) {
|
|
tween.Stop();
|
|
Assert.IsFalse(tween.isAlive);
|
|
}
|
|
})
|
|
.OnComplete(() => Assert.Fail());
|
|
yield return tween.ToYieldInstruction();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator OnUpdateDestroyedTarget() {
|
|
var onUpdateTarget = new GameObject(nameof(OnUpdateDestroyedTarget));
|
|
int numUpdated = 0;
|
|
expectOnUpdateRemoved();
|
|
yield return Tween.Delay(getDt() * 5)
|
|
.OnUpdate(onUpdateTarget, (target, _) => {
|
|
Assert.AreEqual(0, numUpdated);
|
|
numUpdated++;
|
|
Object.Destroy(target);
|
|
})
|
|
.ToYieldInstruction();
|
|
Assert.AreEqual(1, numUpdated);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator OnUpdateException() {
|
|
var onUpdateTarget = new GameObject(nameof(OnUpdateDestroyedTarget));
|
|
expectOnUpdateRemoved();
|
|
int numCompleted = 0;
|
|
yield return Tween.PositionZ(transform, Random.value, 0.001f)
|
|
.OnUpdate(onUpdateTarget, delegate { throw new Exception(); })
|
|
.OnComplete(() => numCompleted++)
|
|
.ToYieldInstruction();
|
|
Assert.AreEqual(1, numCompleted);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[Test]
|
|
public void OnUpdateInvalidUsage() {
|
|
var t = Tween.Delay(0.001f);
|
|
t.OnUpdate<object>(null, delegate { }); // ok
|
|
expectException<AssertionException>(() => {
|
|
t.OnUpdate<object>(null, delegate { }); // duplicate is not allowed
|
|
}, "Only one OnUpdate() is allowed for one tween.");
|
|
Assert.Throws<AssertionException>(() => {
|
|
t.OnUpdate(this, null); // null onUpdate is not allowed
|
|
});
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator OnUpdate() {
|
|
{
|
|
// with delay
|
|
int numCalled = 0;
|
|
yield return Tween.Delay(minDuration, () => numCalled++).ToYieldInstruction();
|
|
Assert.AreEqual(1, numCalled);
|
|
}
|
|
{
|
|
var t = Tween.Position(transform, Vector3.one, getDt(), endDelay: getDt() * 5);
|
|
int numInterpolationCompleted = 0;
|
|
yield return t.OnUpdate<object>(null, delegate {
|
|
if (t.interpolationFactor == 1f) {
|
|
numInterpolationCompleted++;
|
|
}
|
|
}).ToYieldInstruction();
|
|
Assert.AreEqual(1, numInterpolationCompleted);
|
|
}
|
|
}
|
|
|
|
static void expectOnUpdateRemoved() => LogAssert.Expect(LogType.Error, new Regex("will not be called again because"));
|
|
|
|
[UnityTest]
|
|
public IEnumerator TimescaleTweenOutliveTheTarget() {
|
|
var shortTween = Tween.Delay(0.001f);
|
|
var timeScaleTween = Tween.TweenTimeScale(shortTween, 0.5f, 1)
|
|
.OnComplete(Assert.Fail);
|
|
expectOnCompleteIgnored();
|
|
yield return shortTween.ToYieldInstruction();
|
|
Assert.IsFalse(timeScaleTween.isAlive);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ConversionToEasing() {
|
|
var curve = AnimationCurve.Linear(0, 0, 1, 1);
|
|
new TweenSettings(1, curve);
|
|
new TweenSettings<float>(0, 1, curve);
|
|
new TweenSettings<float>(0, 1, 1, curve);
|
|
Tween.Position(transform, Vector3.one, 1, curve);
|
|
Tween.Position(transform, Vector3.one, 1, (Easing)Ease.InBack);
|
|
Tween.Position(transform, Vector3.zero, Vector3.one, 1, curve);
|
|
#if PRIME_TWEEN_EXPERIMENTAL
|
|
Tween.PositionAdditive(transform, Vector3.one, 1, curve);
|
|
#endif
|
|
Tween.PositionAtSpeed(transform, Vector3.one, 10, curve);
|
|
Tween.PositionAtSpeed(transform, Vector3.zero, Vector3.one, 10, curve);
|
|
yield return null;
|
|
Tween.StopAll();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator Elastic() {
|
|
for (int i = 0; i < 5; i++) {
|
|
Assert.AreEqual(0, Easing.Evaluate(0, parametricSettings(ParametricEase.Elastic, 1, 0.3f)));
|
|
Assert.AreEqual(1, Easing.Evaluate(1, parametricSettings(ParametricEase.Elastic, 1, 0.3f)));
|
|
var strength = 1 + Random.value;
|
|
var period = 0.1f + Random.value;
|
|
var t = Tween.Position(transform, Vector3.one, 1, Easing.Elastic(strength, period));
|
|
yield return null;
|
|
Assert.IsTrue(t.isAlive);
|
|
Assert.AreEqual(strength, t.tween.settings.parametricEaseStrength);
|
|
Assert.AreEqual(period, t.tween.settings.parametricEasePeriod);
|
|
Assert.AreEqual(Ease.Custom, t.tween.settings.ease);
|
|
Assert.AreEqual(ParametricEase.Elastic, t.tween.settings.parametricEase);
|
|
t.Stop();
|
|
}
|
|
}
|
|
|
|
[NotNull]
|
|
static ReusableTween parametricSettings(ParametricEase ease, float strength, float period) {
|
|
return new ReusableTween {
|
|
settings = new TweenSettings {
|
|
ease = Ease.Custom,
|
|
duration = 1,
|
|
parametricEase = ease,
|
|
parametricEaseStrength = strength,
|
|
parametricEasePeriod = period
|
|
}
|
|
};
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator Overshoot() {
|
|
Assert.AreEqual(0, Easing.Evaluate(0, parametricSettings(ParametricEase.Overshoot, 1, float.NaN)));
|
|
Assert.AreEqual(1, Easing.Evaluate(1, parametricSettings(ParametricEase.Overshoot, 1, float.NaN)));
|
|
var strength = Random.value;
|
|
var t = Tween.Position(transform, Vector3.one, 1, Easing.Overshoot(strength));
|
|
yield return null;
|
|
Assert.IsTrue(t.isAlive);
|
|
Assert.AreEqual(strength * StandardEasing.backEaseConst, t.tween.settings.parametricEaseStrength);
|
|
Assert.AreEqual(ParametricEase.Overshoot, t.tween.settings.parametricEase);
|
|
Assert.AreEqual(Ease.Custom, t.tween.settings.ease);
|
|
t.Stop();
|
|
}
|
|
|
|
[UnityTest]
|
|
[SuppressMessage("ReSharper", "AssignNullToNotNullAttribute")]
|
|
public IEnumerator NullTarget() {
|
|
const float duration = 0.05f;
|
|
Transform t = null;
|
|
|
|
expectTargetIsNull();
|
|
Tween.Position(t, Vector3.one, duration).ToYieldInstruction();
|
|
|
|
expectTargetIsNull();
|
|
Tween.Delay(null, duration);
|
|
|
|
expectTargetIsNull();
|
|
Tween.Delay(t, duration, delegate { });
|
|
|
|
expectTargetIsNull();
|
|
Sequence.Create().ChainCallback(t, delegate { });
|
|
|
|
Tween.Custom(0, 1, duration, delegate { });
|
|
Tween.Delay(duration);
|
|
Time.timeScale = 0.99f;
|
|
Tween.GlobalTimeScale(1, 0.05f);
|
|
Sequence.Create().ChainCallback(delegate { });
|
|
#if PRIME_TWEEN_DOTWEEN_ADAPTER
|
|
DOTween.Sequence().SetLoops(2).AppendCallback(delegate {});
|
|
DOTween.Sequence().PrependInterval(0.01f);
|
|
#endif
|
|
yield return null;
|
|
yield return null;
|
|
Tween.StopAll();
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator MoreThanOneCyclePerFrame() {
|
|
yield return null;
|
|
{
|
|
var zeroDurTween = Tween.ScaleY(transform, 2f, 0, cycles: int.MaxValue - 1);
|
|
yield return null;
|
|
Assert.IsFalse(zeroDurTween.isAlive, "0f duration completes all cycles immediately");
|
|
}
|
|
{
|
|
var infiniteZeroDurTween = Tween.ScaleY(transform, 2f, 0, cycles: -1);
|
|
yield return null;
|
|
Assert.AreEqual(1, infiniteZeroDurTween.cyclesDone);
|
|
Assert.IsTrue(infiniteZeroDurTween.isAlive);
|
|
}
|
|
{
|
|
float duration = 0.001f + getDt() / 10f;
|
|
Assert.IsTrue(duration >= 0.001f);
|
|
var t = Tween.ScaleY(transform, 2f, duration, cycles: int.MaxValue - 1);
|
|
yield return null;
|
|
Assert.AreEqual(Mathf.FloorToInt(Time.deltaTime / duration), t.cyclesDone);
|
|
t.Complete();
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ExecutionOrder() {
|
|
yield return null;
|
|
int i = 0;
|
|
void validate(int order) {
|
|
// Debug.Log($"-------------- validate {order}");
|
|
Assert.AreEqual(i, order);
|
|
i++;
|
|
}
|
|
{
|
|
for (int k = 0; k < 1; k++) {
|
|
yield return Sequence.Create(2)
|
|
.Chain(Tween.Custom(0, 1, getDur(), delegate { }, startDelay: getDur(), endDelay: getDur()).OnComplete(() => validate(0)))
|
|
.ChainCallback(() => validate(1))
|
|
.Chain(Tween.Delay(getDur(), () => validate(2)))
|
|
.Chain(Tween.Custom(0, 1, getDur(), delegate { }, startDelay: getDur(), endDelay: getDur()).OnComplete(() => validate(3)))
|
|
.ChainCallback(() => validate(4))
|
|
.ChainCallback(() => validate(5))
|
|
.ChainCallback(() => {
|
|
validate(6);
|
|
i = 0;
|
|
})
|
|
.ToYieldInstruction();
|
|
}
|
|
}
|
|
{
|
|
for (int k = 0; k < 1; k++) {
|
|
i = 0;
|
|
var seq = Sequence.Create();
|
|
const int iterations = 5;
|
|
for (int j = 0; j < iterations; j++) {
|
|
var expected = j;
|
|
if (Random.value > 0.5f) {
|
|
seq.Chain(Tween.Delay(getDur(), () => validate(expected)));
|
|
} else {
|
|
seq.ChainCallback(() => validate(expected));
|
|
}
|
|
}
|
|
seq.ChainCallback(() => {
|
|
validate(iterations);
|
|
i = 0;
|
|
});
|
|
seq.SetRemainingCycles(2);
|
|
yield return seq.ToYieldInstruction();
|
|
}
|
|
}
|
|
|
|
float getDur() => Mathf.Max(minDuration, getDt() * Mathf.Lerp(0.1f, 2f, Random.value));
|
|
}
|
|
|
|
static float getDt() => Application.targetFrameRate != -1 ? 1f / Application.targetFrameRate : Time.deltaTime;
|
|
|
|
[Test]
|
|
public void ShakeIsDeadOnNewReusableTween() {
|
|
var t = new ReusableTween();
|
|
Assert.IsFalse(t.shakeData.isAlive);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator SmallDurationWithInfiniteCycles() {
|
|
int numChanged = 0;
|
|
int numUpdated = 0;
|
|
const float duration = 0.001f;
|
|
var t = Tween.Custom(0f, 1f, duration, cycles: -1, onValueChange: delegate {
|
|
numChanged++;
|
|
// print("onValueChange");
|
|
})
|
|
.OnUpdate(this, delegate {
|
|
numUpdated++;
|
|
Assert.AreEqual(numChanged, numUpdated);
|
|
// print("OnUpdate()");
|
|
});
|
|
float timeStart = Time.time;
|
|
yield return null;
|
|
yield return null;
|
|
yield return null;
|
|
Assert.AreEqual(4, numChanged);
|
|
Assert.AreEqual(4, numUpdated);
|
|
var cyclesDoneExpected = Mathf.FloorToInt((Time.time - timeStart) / duration);
|
|
Assert.AreEqual(cyclesDoneExpected, t.cyclesDone);
|
|
t.Complete();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator InvalidOperationExceptionInsideCompleteAllBug() {
|
|
for (int i = 0; i < 1; i++) {
|
|
const float upper = 1.5f;
|
|
Tween.Delay(getDt() * Random.Range(0.5f, upper), () => Tween.Delay(getDt() * Random.Range(0.5f, 1.5f)));
|
|
Tween.Delay(getDt() * Random.Range(0.5f, upper), () => Tween.Delay(getDt() * Random.Range(0.5f, 1.5f)));
|
|
Tween.Delay(getDt() * Random.Range(0.5f, upper), () => Tween.Delay(getDt() * Random.Range(0.5f, 1.5f)));
|
|
Tween.Delay(getDt() * Random.Range(0.5f, upper), () => Tween.Delay(getDt() * Random.Range(0.5f, 1.5f)));
|
|
Tween.Delay(getDt() * Random.Range(0.5f, upper), () => Tween.Delay(getDt() * Random.Range(0.5f, 1.5f)));
|
|
int delayFramesBeforeCompleteAll = Random.Range(0, 0);
|
|
for (int j = 0; j < delayFramesBeforeCompleteAll; j++) {
|
|
yield return null;
|
|
}
|
|
if (Random.value >= 0.0f) {
|
|
Tween.CompleteAll();
|
|
}
|
|
}
|
|
yield return null;
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator TweenElapsedTimeTotal() {
|
|
var duration = getDt() * 2f;
|
|
var t = Tween.Custom(0f, 1f, duration, delegate { });
|
|
var s = Sequence.Create(2)
|
|
.ChainDelay(duration)
|
|
.Chain(t)
|
|
.ChainDelay(duration);
|
|
while (s.isAlive) {
|
|
Assert.IsTrue(t.elapsedTimeTotal >= 0f);
|
|
Assert.IsTrue(t.elapsedTimeTotal <= t.durationTotal);
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SetCyclesWithDelay() {
|
|
LogAssert.Expect(LogType.Error, new Regex("Applying cycles to Delay will not repeat"));
|
|
var delay = Tween.Delay(this, duration: .5f, delegate {});
|
|
delay.SetRemainingCycles(10);
|
|
delay.Stop();
|
|
}
|
|
|
|
[Test]
|
|
public void ElapsedTimeTotalIsClamped() {
|
|
for (int i = 0; i < 1; i++) {
|
|
float duration = Random.value + 0.001f;
|
|
int cycles = Random.Range(3, 20);
|
|
var t = Tween.Delay(duration);
|
|
t.SetRemainingCycles(cycles);
|
|
t.isPaused = true;
|
|
|
|
t.elapsedTime = float.MaxValue;
|
|
Assert.AreEqual(1, t.cyclesDone);
|
|
Assert.AreEqual(duration, t.tween.elapsedTimeTotal);
|
|
Assert.AreEqual(0f, t.elapsedTime); // new cycles has started, so should be 0f
|
|
Assert.AreEqual(duration, t.elapsedTimeTotal);
|
|
|
|
t.elapsedTimeTotal = 0f;
|
|
Assert.AreEqual(0, t.cyclesDone);
|
|
Assert.AreEqual(0f, t.tween.elapsedTimeTotal);
|
|
Assert.AreEqual(0f, t.elapsedTime);
|
|
Assert.AreEqual(0f, t.elapsedTimeTotal);
|
|
|
|
t.elapsedTimeTotal = float.MaxValue;
|
|
Assert.AreEqual(cycles, t.cyclesDone);
|
|
Assert.AreEqual(t.durationTotal, t.tween.elapsedTimeTotal);
|
|
Assert.AreEqual(t.duration, t.elapsedTime);
|
|
Assert.AreEqual(t.durationTotal, t.elapsedTimeTotal);
|
|
|
|
Assert.IsTrue(t.isAlive);
|
|
t.Stop();
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator WarnEndValueEqualsCurrent() {
|
|
Assert.AreEqual(0, tweensCount);
|
|
var iniPos = Vector3.one * Random.value;
|
|
|
|
{
|
|
transform.position = iniPos;
|
|
var t = Tween.Position(transform, iniPos, 1f);
|
|
yield return null;
|
|
LogAssert.Expect(LogType.Warning, new Regex("Tween's 'endValue' equals to the current animated value"));
|
|
t.Stop();
|
|
}
|
|
|
|
{
|
|
PrimeTweenConfig.warnEndValueEqualsCurrent = false;
|
|
transform.position = iniPos;
|
|
var t = Tween.Position(transform, iniPos, 1f);
|
|
yield return null;
|
|
t.Stop();
|
|
PrimeTweenConfig.warnEndValueEqualsCurrent = true;
|
|
}
|
|
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[Test]
|
|
public void SetInfiniteTweenElapsedTime() {
|
|
var t = Tween.Custom(0f, 1f, 0.01f, delegate { }, cycles: -1);
|
|
for (int i = 0; i < 8; i++) {
|
|
LogAssert.Expect(LogType.Error, new Regex("Invalid elapsedTime"));
|
|
}
|
|
t.elapsedTime = float.MaxValue; // ok
|
|
t.elapsedTime = float.PositiveInfinity; // ok
|
|
t.elapsedTime = -1f;
|
|
t.elapsedTime = float.NegativeInfinity;
|
|
t.elapsedTime = float.NaN;
|
|
|
|
t.elapsedTimeTotal = 0f; // ok
|
|
t.elapsedTimeTotal = 10f; // ok
|
|
t.elapsedTimeTotal = -1f;
|
|
t.elapsedTimeTotal = float.MaxValue;
|
|
t.elapsedTimeTotal = float.PositiveInfinity;
|
|
t.elapsedTimeTotal = float.NegativeInfinity;
|
|
t.elapsedTimeTotal = float.NaN;
|
|
t.Stop();
|
|
}
|
|
|
|
[Test]
|
|
public void SetInfiniteTweenProgress() {
|
|
var t = Tween.Custom(0f, 1f, 0.01f, delegate { }, cycles: -1);
|
|
Assert.IsTrue(float.IsPositiveInfinity(t.durationTotal));
|
|
|
|
// ok
|
|
t.progress = 0f;
|
|
t.progress = 0.5f;
|
|
t.progress = 1f;
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
LogAssert.Expect(LogType.Error, new Regex("It's not allowed to set progressTotal on infinite tween"));
|
|
}
|
|
t.progressTotal = 0f;
|
|
t.progressTotal = 0.5f;
|
|
t.progressTotal = 1f;
|
|
Assert.IsTrue(float.IsPositiveInfinity(t.durationTotal));
|
|
t.Stop();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ZZ_SceneLoadSetsUnityObjectBug1() {
|
|
var t = Tween.Delay(1f);
|
|
LoadTestScene();
|
|
yield return null;
|
|
Assert.IsTrue(t.isAlive);
|
|
t.Stop();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator ZZ_SceneLoadSetsUnityObjectBug2() {
|
|
var seq = Sequence.Create().ChainDelay(1f);
|
|
LoadTestScene();
|
|
yield return null;
|
|
Assert.IsTrue(seq.isAlive);
|
|
seq.Stop();
|
|
}
|
|
|
|
static void LoadTestScene() {
|
|
const string testScenePath = "Packages/com.kyrylokuzyk.primetween/Tests/SceneLoadSetsUnityObjectBug.unity";
|
|
#if UNITY_EDITOR
|
|
if (Application.isEditor) {
|
|
UnityEditor.SceneManagement.EditorSceneManager.LoadSceneInPlayMode(testScenePath, new LoadSceneParameters(LoadSceneMode.Single));
|
|
return;
|
|
}
|
|
#endif
|
|
SceneManager.LoadScene(testScenePath, LoadSceneMode.Single);
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator SetElapsedTimeRecursively() {
|
|
Tween t = default;
|
|
int i = 0;
|
|
t = Tween.Custom(0f, 1f, getDt() / 5f, delegate {
|
|
// print("custom");
|
|
onUpdate();
|
|
})
|
|
.OnUpdate(this, delegate {
|
|
// print("OnUpdate");
|
|
onUpdate();
|
|
});
|
|
yield return t.ToYieldInstruction();
|
|
|
|
void onUpdate() {
|
|
i++;
|
|
Assert.IsTrue(i < 100);
|
|
expectRecursiveCallError();
|
|
t.progress += 0.01f;
|
|
expectRecursiveCallError();
|
|
t.progressTotal += 0.01f;
|
|
expectRecursiveCallError();
|
|
t.elapsedTime += 0.01f;
|
|
expectRecursiveCallError();
|
|
t.elapsedTimeTotal += 0.01f;
|
|
}
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator CompleteInfiniteTween() {
|
|
int numCallbacks = 0;
|
|
var duration = Mathf.Max(minDuration, Random.Range(0f, getDt()));
|
|
Assert.IsTrue(duration >= minDuration);
|
|
var t = Tween.Position(transform, Vector3.one, duration, cycles: -1)
|
|
.OnComplete(() => numCallbacks++);
|
|
float timeStart = Time.time;
|
|
yield return null;
|
|
yield return null;
|
|
var cyclesDoneExpected = Mathf.FloorToInt((Time.time - timeStart) / duration);
|
|
Assert.AreEqual(cyclesDoneExpected, t.cyclesDone);
|
|
t.Complete();
|
|
Assert.AreEqual(1, numCallbacks);
|
|
}
|
|
|
|
[Test]
|
|
public void CompleteInfiniteTween2() {
|
|
var target = new GameObject().transform;
|
|
var iniValue = Vector3.one * 0.5f;
|
|
target.localScale = iniValue;
|
|
var endValue = Vector3.one * 2f;
|
|
Tween.Scale(target, endValue, 0.5f, cycles: -1, cycleMode: CycleMode.Yoyo).Complete();
|
|
Assert.AreEqual(endValue, target.localScale);
|
|
{
|
|
var t = Tween.Scale(target, iniValue, 0.5f, cycles: -1, cycleMode: CycleMode.Yoyo);
|
|
t.SetRemainingCycles(true);
|
|
t.Complete();
|
|
Assert.AreEqual(iniValue, target.localScale);
|
|
}
|
|
{
|
|
var t = Tween.Scale(target, endValue, 0.5f, cycles: -1, cycleMode: CycleMode.Yoyo);
|
|
t.SetRemainingCycles(false);
|
|
t.Complete();
|
|
Assert.AreEqual(iniValue, target.localScale);
|
|
}
|
|
Object.DestroyImmediate(target.gameObject);
|
|
LogAssert.NoUnexpectedReceived();
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator WarnEndValueEqualsCurrent2() {
|
|
Tween.StopAll();
|
|
yield return null;
|
|
{
|
|
transform.position = Vector3.one;
|
|
expectWarning();
|
|
var t = Tween.Position(transform, Vector3.one, 0.01f);
|
|
yield return null;
|
|
t.Stop();
|
|
}
|
|
{
|
|
transform.position = Vector3.one;
|
|
PrimeTweenConfig.warnEndValueEqualsCurrent = false;
|
|
var t = Tween.Position(transform, Vector3.one, 0.01f);
|
|
PrimeTweenConfig.warnEndValueEqualsCurrent = true;
|
|
yield return null;
|
|
t.Stop();
|
|
}
|
|
|
|
LogAssert.NoUnexpectedReceived();
|
|
static void expectWarning() => LogAssert.Expect(LogType.Warning, new Regex("Tween's 'endValue' equals to the current animated value"));
|
|
}
|
|
|
|
[UnityTest]
|
|
public IEnumerator SetPropertiesOfInfiniteTween() {
|
|
var t = Tween.Custom(0, 1, 1, _ => {
|
|
// print(_);
|
|
}, cycles: -1, cycleMode: CycleMode.Yoyo, ease: Ease.Linear);
|
|
t.elapsedTime = 0.5f;
|
|
yield return null;
|
|
t.progress = 0.75f;
|
|
yield return null;
|
|
t.elapsedTimeTotal = 2.1f;
|
|
yield return null;
|
|
t.elapsedTime = 0.5f;
|
|
yield return null;
|
|
t.Stop();
|
|
}
|
|
|
|
[Test]
|
|
public void NegativeIniCyclesBugReport() {
|
|
// https://github.com/KyryloKuzyk/PrimeTween/issues/63
|
|
Tween.StopAll();
|
|
var startValue = Vector3.one * 10;
|
|
var endValue = Vector3.one * 20;
|
|
transform.position = startValue;
|
|
var posTween = Tween.Position(transform, startValue, endValue, new TweenSettings(1f, cycles: 2, cycleMode: CycleMode.Rewind));
|
|
var seq = Sequence.Create()
|
|
.ChainDelay(1f)
|
|
.Chain(posTween);
|
|
seq.elapsedTime = 1.1f;
|
|
Assert.AreNotEqual(0f, posTween.interpolationFactor);
|
|
Assert.AreNotEqual(startValue, transform.position);
|
|
// Assert.AreEqual(-1, posTween.tween.cyclesDone);
|
|
seq.elapsedTime = 0.5f;
|
|
Assert.AreEqual(0f, posTween.interpolationFactor);
|
|
Assert.AreEqual(startValue, transform.position);
|
|
seq.Stop();
|
|
}
|
|
|
|
[Test]
|
|
public void UpdateTypes() {
|
|
var iniUpdateType = PrimeTweenConfig.defaultUpdateType;
|
|
{
|
|
Tween.StopAll();
|
|
var t = Tween.Position(transform, default, new TweenSettings(1f, updateType: default)).tween;
|
|
Assert.AreEqual(_UpdateType.Update, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.tweens.Single());
|
|
}
|
|
{
|
|
Tween.StopAll();
|
|
var t = Tween.Position(transform, default, new TweenSettings(1f, updateType: UpdateType.Update)).tween;
|
|
Assert.AreEqual(_UpdateType.Update, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.tweens.Single());
|
|
}
|
|
{
|
|
Tween.StopAll();
|
|
var t = Tween.Position(transform, default, new TweenSettings(1f, updateType: UpdateType.LateUpdate)).tween;
|
|
Assert.AreEqual(_UpdateType.LateUpdate, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.lateUpdateTweens.Single());
|
|
}
|
|
{
|
|
Tween.StopAll();
|
|
var t = Tween.Position(transform, default, new TweenSettings(1f, updateType: UpdateType.FixedUpdate)).tween;
|
|
Assert.AreEqual(_UpdateType.FixedUpdate, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.fixedUpdateTweens.Single());
|
|
}
|
|
{
|
|
Tween.StopAll();
|
|
UpdateType updateType = default;
|
|
updateType.enumValue = (_UpdateType)100;
|
|
Tween.Position(transform, default, new TweenSettings(1f, updateType: updateType));
|
|
LogAssert.Expect(LogType.Error, "Invalid update type: 100");
|
|
}
|
|
{
|
|
Tween.StopAll();
|
|
var t = Tween.ShakeLocalPosition(transform, new ShakeSettings(Vector3.one, updateType: default)).tween;
|
|
Assert.AreEqual(_UpdateType.Update, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.tweens.Single());
|
|
}
|
|
{
|
|
Tween.StopAll();
|
|
var t = Tween.ShakeLocalPosition(transform, new ShakeSettings(Vector3.one, updateType: UpdateType.Update)).tween;
|
|
Assert.AreEqual(_UpdateType.Update, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.tweens.Single());
|
|
}
|
|
{
|
|
Tween.StopAll();
|
|
var t = Tween.ShakeLocalPosition(transform, new ShakeSettings(Vector3.one, updateType: UpdateType.LateUpdate)).tween;
|
|
Assert.AreEqual(_UpdateType.LateUpdate, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.lateUpdateTweens.Single());
|
|
}
|
|
{
|
|
Tween.StopAll();
|
|
var t = Tween.ShakeLocalPosition(transform, new ShakeSettings(Vector3.one, updateType: UpdateType.FixedUpdate)).tween;
|
|
Assert.AreEqual(_UpdateType.FixedUpdate, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.fixedUpdateTweens.Single());
|
|
}
|
|
|
|
{
|
|
Tween.StopAll();
|
|
PrimeTweenConfig.defaultUpdateType = UpdateType.FixedUpdate;
|
|
var t = Tween.Position(transform, default, new TweenSettings(1f, updateType: default)).tween;
|
|
Assert.AreEqual(_UpdateType.FixedUpdate, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.fixedUpdateTweens.Single());
|
|
}
|
|
{
|
|
Tween.StopAll();
|
|
PrimeTweenConfig.defaultUpdateType = UpdateType.LateUpdate;
|
|
var t = Tween.Position(transform, default, new TweenSettings(1f, updateType: default)).tween;
|
|
Assert.AreEqual(_UpdateType.LateUpdate, t.settings._updateType);
|
|
Assert.AreEqual(t, PrimeTweenManager.Instance.lateUpdateTweens.Single());
|
|
}
|
|
Tween.StopAll();
|
|
|
|
#pragma warning disable CS0618 // Type or member is obsolete
|
|
Assert.AreEqual(false, new TweenSettings(1f, updateType: default).useFixedUpdate);
|
|
Assert.AreEqual(false, new TweenSettings(1f, updateType: UpdateType.Update).useFixedUpdate);
|
|
Assert.AreEqual(false, new TweenSettings(1f, updateType: UpdateType.LateUpdate).useFixedUpdate);
|
|
Assert.AreEqual(true, new TweenSettings(1f, updateType: UpdateType.FixedUpdate).useFixedUpdate);
|
|
#pragma warning restore CS0618 // Type or member is obsolete
|
|
|
|
Assert.AreEqual(UpdateType.Default, new TweenSettings(1f, updateType: default).updateType);
|
|
PrimeTweenConfig.defaultUpdateType = UpdateType.Update;
|
|
Assert.AreEqual(UpdateType.Default, new TweenSettings(1f, updateType: default).updateType);
|
|
PrimeTweenConfig.defaultUpdateType = UpdateType.LateUpdate;
|
|
Assert.AreEqual(UpdateType.Update, new TweenSettings(1f, updateType: UpdateType.Update).updateType);
|
|
Assert.AreEqual(UpdateType.FixedUpdate, new TweenSettings(1f, updateType: UpdateType.FixedUpdate).updateType);
|
|
PrimeTweenConfig.defaultUpdateType = iniUpdateType;
|
|
}
|
|
}
|
|
#endif
|