void TryUpdateReferenceClip(Object obj, ReferencedSpritesheet spritesheet)
 {
     if (obj && (obj is AnimationClip animationClip))
     {
         spritesheet.ReferenceClip = animationClip;
     }
 }
 void TryUpdateSpritesheet(Object obj, ReferencedSpritesheet spritesheet)
 {
     if (obj && (obj is Texture2D))
     {
         var sprites = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(obj)).Select(x => {
             if (x && (x is Sprite sprite))
             {
                 return(sprite);
             }
             return(null);
         }).Where(x => (x != null)).ToList();
         var zeroName = sprites[0].name;
         var prefix   = zeroName.Substring(0, zeroName.LastIndexOf('_') + 1);
         sprites.Sort((a, b) => {
             var aIndex = int.Parse(a.name.Replace(prefix, ""));
             var bIndex = int.Parse(b.name.Replace(prefix, ""));
             return(aIndex.CompareTo(bIndex));
         });
         if (sprites.Count > 0)
         {
             spritesheet.Sprites = sprites;
         }
     }
 }
        void GenerateSimpleAnim(string animName, int spritesheetSize, Func <int, int> spriteChooser,
                                Func <AnimatorCondition[]> conditionFactory, AnimatorController animatorController,
                                ReferencedSpritesheet spritesheet, GameObject targetGameObject, bool silent)
        {
            if (!spritesheet.IsValid)
            {
                if (!silent)
                {
                    Debug.LogErrorFormat("Spritesheet for anim '{0}' is invalid", animName);
                }
                return;
            }
            var sprites = spritesheet.Sprites;

            if (sprites.Count != spritesheetSize)
            {
                Debug.LogErrorFormat("Invalid spritesheet size for anim '{0}': '{1}'", animName, spritesheetSize);
                return;
            }

            var referenceClip = spritesheet.ReferenceClip;

            var stateMachine = animatorController.layers[0].stateMachine;

            var clip = new AnimationClip {
                name     = animName,
                wrapMode = WrapMode.Loop
            };

            var bindings = AnimationUtility.GetObjectReferenceCurveBindings(referenceClip);

            Debug.Assert(bindings.Length == 1);
            foreach (var referenceBinding in bindings)
            {
                var referenceCurve = AnimationUtility.GetObjectReferenceCurve(referenceClip, referenceBinding);

                var mod = new PropertyModification {
                    propertyPath = referenceBinding.path,
                };
                AnimationUtility.PropertyModificationToEditorCurveBinding(mod, targetGameObject, out var binding);
                binding.propertyName = referenceBinding.propertyName;
                binding.path         = referenceBinding.path;
                binding.type         = referenceBinding.type;

                var curve = new ObjectReferenceKeyframe[referenceCurve.Length];
                for (var i = 0; i < referenceCurve.Length; ++i)
                {
                    curve[i] = new ObjectReferenceKeyframe {
                        time  = referenceCurve[i].time,
                        value = sprites[spriteChooser(i)]
                    };
                }
                AnimationUtility.SetObjectReferenceCurve(clip, binding, curve);
            }

            foreach (var referenceBinding in AnimationUtility.GetCurveBindings(referenceClip))
            {
                var referenceCurve = AnimationUtility.GetEditorCurve(referenceClip, referenceBinding);
                var mod            = new PropertyModification {
                    propertyPath = referenceBinding.path,
                };
                AnimationUtility.PropertyModificationToEditorCurveBinding(mod, targetGameObject, out var binding);
                var curve = new AnimationCurve();
                for (var j = 0; j < referenceCurve.length; ++j)
                {
                    var referenceKey = referenceCurve.keys[j];
                    curve.AddKey(new Keyframe(referenceKey.time, referenceKey.value));
                }
                AnimationUtility.SetEditorCurve(clip, binding, curve);
            }

            if (AddEvents)
            {
                var clipEvents = new List <AnimationEvent>();
                foreach (var referenceEvent in AnimationUtility.GetAnimationEvents(referenceClip))
                {
                    var ev = new AnimationEvent {
                        time                     = referenceEvent.time,
                        functionName             = referenceEvent.functionName,
                        floatParameter           = referenceEvent.floatParameter,
                        intParameter             = referenceEvent.intParameter,
                        messageOptions           = referenceEvent.messageOptions,
                        stringParameter          = referenceEvent.stringParameter,
                        objectReferenceParameter = referenceEvent.objectReferenceParameter
                    };
                    clipEvents.Add(ev);
                }
                if (clipEvents.Count > 0)
                {
                    AnimationUtility.SetAnimationEvents(clip, clipEvents.ToArray());
                }
            }

            AssetDatabase.CreateAsset(clip, AssetDatabase.GetAssetPath(animatorController).Replace("Controller.asset", animName + ".anim"));
            var animatorState = animatorController.AddMotion(clip);

            animatorState.name = $"{animName}";

            var transition = stateMachine.AddAnyStateTransition(animatorState);

            transition.duration    = 0f;
            transition.hasExitTime = false;
            transition.conditions  = conditionFactory();
        }