internal void CreateAnimation()

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();
		}