in MREUnityRuntimeLib/Core/Components/AnimationComponent.cs [72:204]
internal void CreateAnimation(
string animationName,
IEnumerable<MWAnimationKeyframe> keyframes,
IEnumerable<MWAnimationEvent> events,
MWAnimationWrapMode wrapMode,
MWSetAnimationStateOptions initialState,
bool isInternal,
bool managed,
Action onCreatedCallback)
{
var continuation = new MWContinuation(AttachedActor, null, (result) =>
{
var clip = new AnimationClip
{
legacy = true,
wrapMode = wrapMode.ToUnityWrapMode(),
};
var curves = new Dictionary<string, CurveInfo>();
CurveInfo GetOrCreateCurve(Type type, string propertyName)
{
if (!curves.TryGetValue(propertyName, out CurveInfo info))
{
info = new CurveInfo()
{
Curve = new AnimationCurve(),
Type = type
};
curves.Add(propertyName, info);
}
return info;
}
void AddFloatPatch(Type type, string propertyName, float time, float? value)
{
if (value.HasValue)
{
var curveInfo = GetOrCreateCurve(type, propertyName);
var keyframe = new UnityEngine.Keyframe(time, value.Value, 0, 0, 0, 0);
curveInfo.Curve.AddKey(keyframe);
}
}
void AddVector3Patch(Type type, string propertyName, float time, Vector3Patch value)
{
AddFloatPatch(type, String.Format("{0}.x", propertyName), time, value?.X);
AddFloatPatch(type, String.Format("{0}.y", propertyName), time, value?.Y);
AddFloatPatch(type, String.Format("{0}.z", propertyName), time, value?.Z);
}
void AddQuaternionPatch(Type type, string propertyName, float time, QuaternionPatch value)
{
AddFloatPatch(type, String.Format("{0}.x", propertyName), time, value?.X);
AddFloatPatch(type, String.Format("{0}.y", propertyName), time, value?.Y);
AddFloatPatch(type, String.Format("{0}.z", propertyName), time, value?.Z);
AddFloatPatch(type, String.Format("{0}.w", propertyName), time, value?.W);
}
void AddTransformPatch(float time, ScaledTransformPatch value)
{
// Work around a Unity bug/feature where all position components must be specified
// in the keyframe or the missing fields get set to zero.
Vector3Patch position = value?.Position;
if (position != null && position.IsPatched())
{
if (!position.X.HasValue) { position.X = transform.localPosition.x; }
if (!position.Y.HasValue) { position.Y = transform.localPosition.y; }
if (!position.Z.HasValue) { position.Z = transform.localPosition.z; }
}
// Work around a Unity bug/feature where all scale components must be specified
// in the keyframe or the missing fields get set to one.
Vector3Patch scale = value?.Scale;
if (scale != null && scale.IsPatched())
{
if (!scale.X.HasValue) { scale.X = transform.localScale.x; }
if (!scale.Y.HasValue) { scale.Y = transform.localScale.y; }
if (!scale.Z.HasValue) { scale.Z = transform.localScale.z; }
}
AddVector3Patch(typeof(Transform), "m_LocalPosition", time, value?.Position);
AddQuaternionPatch(typeof(Transform), "m_LocalRotation", time, value?.Rotation);
AddVector3Patch(typeof(Transform), "m_LocalScale", time, value?.Scale);
}
void AddActorPatch(float time, ActorPatch value)
{
AddTransformPatch(time, value?.Transform.Local);
}
void AddKeyframe(MWAnimationKeyframe keyframe)
{
AddActorPatch(keyframe.Time, keyframe.Value);
}
foreach (var keyframe in keyframes)
{
AddKeyframe(keyframe);
}
foreach (var kv in curves)
{
clip.SetCurve("", kv.Value.Type, kv.Key, kv.Value.Curve);
}
_animationData[animationName] = new AnimationData()
{
IsInternal = isInternal,
Managed = managed
};
float initialTime = 0f;
float initialSpeed = 1f;
bool initialEnabled = false;
if (initialState != null)
{
initialTime = initialState.Time ?? initialTime;
initialSpeed = initialState.Speed ?? initialSpeed;
initialEnabled = initialState.Enabled ?? initialEnabled;
}
var animation = GetOrCreateUnityAnimationComponent();
animation.AddClip(clip, animationName);
SetAnimationState(animationName, initialTime, initialSpeed, initialEnabled);
onCreatedCallback?.Invoke();
});
continuation.Start();
}