РЕЗЮМЕ
Я столкнулся с неожиданной проблемой при попытке выполнить следующие операции с использованием AnimationCurve UnityCurve:
x = A (via serialization/deserialization)
y = x
x = B (via serialization/deserialization)
Assert that y equals A
Как показано на рисункепсевдокод, я ожидаю, что y будет равен A. Однако, похоже, что это не работает для типа AnimationCurve
. Почему это так?
ПОЛНОЕ ОБЪЯСНЕНИЕ
Чтобы проиллюстрировать происходящее, я настроил тестовый пример для этого с помощью NUnit. Тест, реализованный ниже, НЕ ПРОЙДЕТ.
public class AnimationCurveMonoBehaviour: MonoBehaviour
{
public AnimationCurve myCurve;
}
[Test]
public void SetValueViaSerialization_SetsAThenB_HasValueAInTheMiddle()
{
// INITIALIZATION
GameObject gameObject = new GameObject();
AnimationCurveMonoBehaviour animationCurveMonoBehaviour = gameObject.AddComponent<AnimationCurveMonoBehaviour>();
AnimationCurve animationCurveA = new AnimationCurve(new Keyframe(0, 1));
AnimationCurve animationCurveB = new AnimationCurve(new Keyframe(0, 2));
// EXECUTION
this.SetAnimationCurveValue(animationCurveMonoBehaviour, animationCurveA);
AnimationCurve sample = animationCurveMonoBehaviour.myCurve;
this.SetAnimationCurveValue(animationCurveMonoBehaviour, animationCurveB);
// ASSERTION
Assert.AreEqual(animationCurveA, sample); // FAILS
}
private void SetAnimationCurveValue(AnimationCurveMonoBehaviour animationCurveMonoBehaviour, AnimationCurve animationCurve)
{
SerializedObject serializedObject = new SerializedObject(animationCurveMonoBehaviour);
SerializedProperty sut = serializedObject.FindProperty("myCurve");
sut.animationCurveValue = animationCurve;
serializedObject.ApplyModifiedProperties();
}
При выполнении одного и того же теста (с соответствующими модификациями типов) для всех перечисленных ниже типов выполняются тесты PASSES.
int
bool
float
string
Color
Vector2
Vector3
Vector4
Rect
Bounds
Quaternion
Vector2Int
Vector3Int
RectInt
BoundsInt
GameObject
TMP_FontAsset
Sprite
Но что действительно странно, так это то, что следующие аналогичные тесты также работают, как и предполагалось, при использовании AnimationCurve
:
//...
// EXECUTION
this.SetAnimationCurveValue(animationCurveMonoBehaviour, animationCurveA);
AnimationCurve sample = animationCurveMonoBehaviour.myCurve;
Assert.AreEqual(animationCurveA, sample); // PASSES
//...
//...
// EXECUTION
this.SetAnimationCurveValue(animationCurveMonoBehaviour, animationCurveA);
this.SetAnimationCurveValue(animationCurveMonoBehaviour, animationCurveB);
AnimationCurve sample = animationCurveMonoBehaviour.myCurve;
Assert.AreEqual(animationCurveB, sample); // PASSES
//...
Чем отличается AnimationCurve
и что происходитв моем примере?