public virtual void Initialize() { foreach (var animation in animations.Values) { int cachedAnimations = 0; var curves = new List <IAnimationCurve>(animation.Curves); foreach (IAnimationCurve curve in curves) { object realTarget; if (string.IsNullOrEmpty(curve.TargetName)) { realTarget = target; } else { var resourceProvider = target as IResourceProvider; if (resourceProvider != null) { realTarget = resourceProvider.GetResource <IResource>(curve.TargetName); } else { throw new InvalidOperationException(string.Format("'Target' does not implement {0}", typeof(IResourceProvider))); } } if (realTarget == null) { throw new InvalidOperationException("'Target' cannot be null"); } name = string.Format("{0}.Animator", ((IResource)realTarget).Name); ObjectWalker walker = new ObjectWalker(realTarget, curve.TargetProperty); var requiresCaching = realTarget as IRequiresCaching; string curveKey = curve.Key; if (requiresCaching != null) { var newCurve = requiresCaching.CacheAnimation(walker.CurrentMember.DeclaringType, walker.CurrentMember.Name, curve); if (newCurve != null) { animation.RemoveCurve(curve.TargetProperty); animation.AddCurve(newCurve); walker.SetTarget(requiresCaching, newCurve.TargetProperty); curveKey = newCurve.Key; cachedAnimations++; } } var animatable = walker.CurrentMember.GetCustomAttribute <AnimatableAttribute>(); if (animatable == null) { throw new InvalidOperationException(string.Format("'{0}' is not marked as {1}", walker.CurrentMember.Name, typeof(AnimatableAttribute).Name)); } walkers.Add(curveKey, walker); } if (cachedAnimations > 0 && cachedAnimations != curves.Count) { throw new InvalidOperationException(string.Format("Mixing cached and uncached animations is not supported")); } } }