void AnalyzeStateMachine(UnityEditor.Animations.AnimatorStateMachine stateMachine,
                                 Animator animator,
                                 SkinnedMeshRenderer[] meshRender,
                                 int layer,
                                 int bakeFPS,
                                 int animationIndex)
        {
            AnimationInstancing instance = generatedPrefab.GetComponent <AnimationInstancing>();

            if (instance == null)
            {
                Debug.LogError("You should select a prefab with AnimationInstancing component.");
                return;
            }
            if (string.IsNullOrEmpty(instance.cfgName))
            {
                instance.cfgName = generatedPrefab.name;
            }

            for (int i = 0; i != stateMachine.states.Length; ++i)
            {
                ChildAnimatorState state = stateMachine.states[i];
                if (state.state == null || state.state.motion == null) // add by chenbin
                {
                    continue;                                          // add by chenbin
                }                                                      // add by chenbin
                bool needBake = false;
                if (!generateAnims.TryGetValue(state.state.motion.name, out needBake))
                {
                    continue;
                }
                foreach (var obj in generateInfo)
                {
                    if (obj.info.animationName == state.state.motion.name)
                    {
                        needBake = false;
                        break;
                    }
                }

                if (!needBake)
                {
                    continue;
                }

                AnimationBakeInfo bake = new AnimationBakeInfo();
                bake.length               = state.state.motion.averageDuration;
                bake.animator             = animator;
                bake.animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
                bake.meshRender           = meshRender;
                bake.layer = layer;
                bake.info  = new AnimationInfo();
                bake.info.animationName     = state.state.motion.name;
                bake.info.animationNameHash = state.state.nameHash;
                bake.info.animationIndex    = animationIndex;
                bake.info.totalFrame        = (int)(state.state.motion.averageDuration * bakeFPS);
                bake.info.fps        = bakeFPS;
                bake.info.rootMotion = true;
                if (bake.info.rootMotion)
                {
                    bake.info.velocity        = new Vector3[bake.info.totalFrame];
                    bake.info.angularVelocity = new Vector3[bake.info.totalFrame];
                }
                generateInfo.Add(bake);
                animationIndex += bake.info.totalFrame;
                totalFrame     += bake.info.totalFrame;

                bake.info.eventList = new List <AnimationEvent>();
                AnimationClip clip = state.state.motion as AnimationClip;
                foreach (var evt in clip.events)
                {
                    AnimationEvent aniEvent = new AnimationEvent();
                    aniEvent.function        = evt.functionName;
                    aniEvent.floatParameter  = evt.floatParameter;
                    aniEvent.intParameter    = evt.intParameter;
                    aniEvent.stringParameter = evt.stringParameter;
                    aniEvent.time            = evt.time;
                    if (evt.objectReferenceParameter != null)
                    {
                        aniEvent.objectParameter = evt.objectReferenceParameter.name;
                    }
                    else
                    {
                        aniEvent.objectParameter = "";
                    }
                    bake.info.eventList.Add(aniEvent);
                }

                cacheTransition.Add(state.state, state.state.transitions);
                state.state.transitions = null;
                cacheAnimationEvent.Add(clip, clip.events);
                UnityEngine.AnimationEvent[] tempEvent = new UnityEngine.AnimationEvent[0];
                UnityEditor.AnimationUtility.SetAnimationEvents(clip, tempEvent);
            }
            for (int i = 0; i != stateMachine.stateMachines.Length; ++i)
            {
                AnalyzeStateMachine(stateMachine.stateMachines[i].stateMachine, animator, meshRender, layer, bakeFPS, animationIndex);
            }
        }
        void GenerateAnimation()
        {
            if (generateInfo.Count > 0 && workingInfo == null)
            {
                workingInfo = generateInfo[0];
                generateInfo.RemoveAt(0);

                workingInfo.animator.gameObject.SetActive(true);
                workingInfo.animator.Play(workingInfo.info.animationNameHash);
                workingInfo.workingFrame = 0;
                workingInfo.animator.Update(workingInfo.length / workingInfo.info.totalFrame);
                return;
            }
            if (workingInfo != null)
            {
                workingInfo.info.velocity[workingInfo.workingFrame]        = workingInfo.animator.velocity;
                workingInfo.info.angularVelocity[workingInfo.workingFrame] = workingInfo.animator.angularVelocity * Mathf.Rad2Deg;
                float deltaTime = workingInfo.length / workingInfo.info.totalFrame;
                workingInfo.animator.Update(deltaTime);

                for (int j = 0; j != workingInfo.meshRender.Length; ++j)
                {
                    GenerateBoneMatrix(workingInfo.meshRender[j].name.GetHashCode(),
                                       workingInfo.info.animationNameHash,
                                       workingInfo.workingFrame,
                                       Matrix4x4.identity,
                                       false);
                }

                EditorUtility.DisplayProgressBar("Generating Animations",
                                                 string.Format("Animation '{0}' is Generating.", workingInfo.info.animationName),
                                                 ((float)(generateCount - generateInfo.Count) / generateCount));
                //Debug.Log(string.Format("Animation '{0}' is Generating. Current frame is {1}", workingInfo.info.animationName, workingInfo.workingFrame));
                if (++workingInfo.workingFrame >= workingInfo.info.totalFrame)
                {
                    aniInfo.Add(workingInfo.info);
                    if (generateInfo.Count == 0)
                    {
                        foreach (var obj in cacheTransition)
                        {
                            obj.Key.transitions = obj.Value;
                        }
                        cacheTransition.Clear();
                        foreach (var obj in cacheAnimationEvent)
                        {
                            UnityEditor.AnimationUtility.SetAnimationEvents(obj.Key, obj.Value);
                        }
                        cacheAnimationEvent.Clear();
                        PrepareBoneTexture(aniInfo);
                        SetupAnimationTexture(aniInfo);
                        SaveAnimationInfo(generatedPrefab.name);
                        DestroyImmediate(workingInfo.animator.gameObject);
                        EditorUtility.ClearProgressBar();
                    }

                    if (workingInfo.animator != null)
                    {
                        workingInfo.animator.gameObject.transform.position = Vector3.zero;
                        workingInfo.animator.gameObject.transform.rotation = Quaternion.identity;
                    }
                    workingInfo = null;
                }
            }
        }
示例#3
0
        void AnalyzeStateMachine(AnimationLayerInfo pLayerInfo,
                                 UnityEditor.Animations.AnimatorControllerLayer ownerLayer,
                                 UnityEditor.Animations.AnimatorStateMachine stateMachine,
                                 Animator animator,
                                 SkinnedMeshRenderer[] meshRender,
                                 int layer,
                                 int bakeFPS,
                                 int animationIndex)
        {
            var tmachineInfo = new AnimationStateMachineInfo()
            {
                layerIndex  = pLayerInfo.index, index = pLayerInfo.machines.Count,
                defaultName = stateMachine.defaultState != null ? stateMachine.defaultState.name : "",
                machineName = stateMachine.name
            };

            pLayerInfo.machines.Add(tmachineInfo);

            for (int i = 0; i != stateMachine.states.Length; ++i)
            {
                ChildAnimatorState state = stateMachine.states[i];
                var tstateinfo           = new AnimationStateInfo()
                {
                    layerIndex = pLayerInfo.index, machineIndex = tmachineInfo.index, index = i
                };
                tstateinfo.SetData(state.state);
                tmachineInfo.stateInfos.Add(tstateinfo);

                AnimationClip clip     = state.state.motion as AnimationClip;
                bool          needBake = false;
                if (clip == null)
                {
                    continue;
                }
                if (!generateAnims.TryGetValue(clip.name, out needBake))
                {
                    continue;
                }
                foreach (var obj in generateInfo)
                {
                    if (obj.info.animationName == clip.name)
                    {
                        needBake = false;
                        break;
                    }
                }

                if (!needBake)
                {
                    continue;
                }

                AnimationBakeInfo bake = new AnimationBakeInfo();
                bake.length               = clip.averageDuration;
                bake.animator             = animator;
                bake.animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;
                bake.meshRender           = meshRender;
                bake.layer = layer;
                bake.info  = new AnimationInfo();
                bake.info.animationName     = clip.name;
                bake.info.animationNameHash = state.state.nameHash;
                bake.info.animationIndex    = animationIndex;
                bake.info.totalFrame        = (int)(bake.length * bakeFPS + 0.5f) + 1;
                bake.info.totalFrame        = Mathf.Clamp(bake.info.totalFrame, 1, bake.info.totalFrame);
                bake.info.fps        = bakeFPS;
                bake.info.rootMotion = true;
                bake.info.wrapMode   = clip.isLooping ? WrapMode.Loop : clip.wrapMode;
                if (bake.info.rootMotion)
                {
                    bake.info.velocity        = new Vector3[bake.info.totalFrame];
                    bake.info.angularVelocity = new Vector3[bake.info.totalFrame];
                }

                generateInfo.Add(bake);
                animationIndex += bake.info.totalFrame;
                totalFrame     += bake.info.totalFrame;

                bake.info.eventList = new List <AnimationEvent>();
                //AnimationClip clip = state.state.motion as AnimationClip;
                foreach (var evt in clip.events)
                {
                    AnimationEvent aniEvent = new AnimationEvent();
                    aniEvent.function        = evt.functionName;
                    aniEvent.floatParameter  = evt.floatParameter;
                    aniEvent.intParameter    = evt.intParameter;
                    aniEvent.stringParameter = evt.stringParameter;
                    aniEvent.time            = evt.time;
                    if (evt.objectReferenceParameter != null)
                    {
                        aniEvent.objectParameter = evt.objectReferenceParameter.name;
                    }
                    else
                    {
                        aniEvent.objectParameter = "";
                    }
                    bake.info.eventList.Add(aniEvent);
                }

                cacheTransition.Add(state.state, state.state.transitions);
                state.state.transitions = null;

                cacheAnimationEvent.Add(clip, clip.events);
                UnityEngine.AnimationEvent[] tempEvent = new UnityEngine.AnimationEvent[0];
                UnityEditor.AnimationUtility.SetAnimationEvents(clip, tempEvent);
            }
            for (int i = 0; i != stateMachine.stateMachines.Length; ++i)
            {
                AnalyzeStateMachine(pLayerInfo, ownerLayer, stateMachine.stateMachines[i].stateMachine, animator, meshRender, layer, bakeFPS, animationIndex);
            }
        }
示例#4
0
        private void SaveAnimationInfo(string name, AnimationBakeInfo pWorkInfo)
        {
            string path = GetFilePath();

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            UnityEditor.Animations.AnimatorController controller = pWorkInfo.animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
            //AssetDatabase.CreateFolder("Assets/Resources", folderName);
            FileStream   file   = File.Open(GetFullPahtFile(name), FileMode.Create);
            BinaryWriter writer = new BinaryWriter(file);

            //存储参数
            int tpamCount = controller.parameters != null ? controller.parameters.Length : 0;

            writer.Write(tpamCount);
            if (controller.parameters != null && controller.parameters.Length > 0)
            {
                AssetParameter.Parameter[] tparms = new AssetParameter.Parameter[tpamCount];
                for (int i = 0; i < tpamCount; i++)
                {
                    AssetParameter.Parameter tpamdata = new AssetParameter.Parameter();
                    tpamdata.CopyData(controller.parameters[i]);
                    tpamdata.WriteToFile(writer);
                }
            }

            writer.Write(layerInfos.Count);
            foreach (var item in layerInfos)
            {
                item.WriteToFile(writer);
            }

            //存储animation State
            writer.Write(aniInfo.Count);
            foreach (var obj in aniInfo)
            {
                AnimationInfo info = (AnimationInfo)obj;
                //writer.Write(info.animationNameHash);
                writer.Write(info.animationName);
                writer.Write(info.animationIndex);
                writer.Write(info.textureIndex);
                writer.Write(info.totalFrame);
                writer.Write(info.fps);
                writer.Write(info.rootMotion);
                writer.Write((int)info.wrapMode);
                if (info.rootMotion)
                {
                    Debug.Assert(info.totalFrame == info.velocity.Length);
                    for (int i = 0; i != info.velocity.Length; ++i)
                    {
                        writer.Write(info.velocity[i].x);
                        writer.Write(info.velocity[i].y);
                        writer.Write(info.velocity[i].z);

                        writer.Write(info.angularVelocity[i].x);
                        writer.Write(info.angularVelocity[i].y);
                        writer.Write(info.angularVelocity[i].z);
                    }
                }
                writer.Write(info.eventList.Count);
                foreach (var evt in info.eventList)
                {
                    writer.Write(evt.function);
                    writer.Write(evt.floatParameter);
                    writer.Write(evt.intParameter);
                    writer.Write(evt.stringParameter);
                    writer.Write(evt.time);
                    writer.Write(evt.objectParameter);
                }
            }

            //attach
            writer.Write(exposeAttachments);
            if (exposeAttachments)
            {
                writer.Write(extraBoneInfo.extraBone.Length);
                for (int i = 0; i != extraBoneInfo.extraBone.Length; ++i)
                {
                    writer.Write(extraBoneInfo.extraBone[i]);
                }
                for (int i = 0; i != extraBoneInfo.extraBindPose.Length; ++i)
                {
                    for (int j = 0; j != 16; ++j)
                    {
                        writer.Write(extraBoneInfo.extraBindPose[i][j]);
                    }
                }
            }

            //boneTexture
            Texture2D[] texture = bakedBoneTexture;
            writer.Write(texture.Length);
            writer.Write(textureBlockWidth);
            writer.Write(textureBlockHeight);
            for (int i = 0; i != texture.Length; ++i)
            {
                byte[] bytes = texture[i].GetRawTextureData();
                writer.Write(texture[i].width);
                writer.Write(texture[i].height);
                writer.Write(bytes.Length);
                writer.Write(bytes);
            }

            file.Close();
            aniInfo.Clear();
        }
示例#5
0
        void GenerateAnimation()
        {
            if (generateInfo.Count > 0 && workingInfo == null)
            {
                workingInfo = generateInfo[0];
                generateInfo.RemoveAt(0);

                workingInfo.animator.gameObject.SetActive(true);
                workingInfo.animator.Update(0);
                workingInfo.animator.Play(workingInfo.info.animationNameHash);
                workingInfo.animator.Update(0);
                workingInfo.workingFrame = 0;
                return;
            }
            if (workingInfo != null)
            {
                //float time = workingInfo.animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
                //Debug.Log("The time is" + time);
                for (int j = 0; j != workingInfo.meshRender.Length; ++j)
                {
                    GenerateBoneMatrix(workingInfo.meshRender[j].name.GetHashCode(),
                                       workingInfo.info.animationNameHash,
                                       workingInfo.workingFrame,
                                       Matrix4x4.identity,
                                       false);
                }
                //Debug.Log("The length is" + workingInfo.animator.velocity.magnitude);
                workingInfo.info.velocity[workingInfo.workingFrame]        = workingInfo.animator.velocity;
                workingInfo.info.angularVelocity[workingInfo.workingFrame] = workingInfo.animator.angularVelocity * Mathf.Rad2Deg;

                EditorUtility.DisplayProgressBar("Brake Animation" + workingInfo.info.animationName, string.Format("curFrame {0}", workingInfo.workingFrame), (float)workingInfo.workingFrame / workingInfo.info.totalFrame);

                if (++workingInfo.workingFrame >= workingInfo.info.totalFrame)
                {
                    aniInfo.Add(workingInfo.info);
                    if (generateInfo.Count == 0)
                    {
                        foreach (var obj in cacheTransition)
                        {
                            obj.Key.transitions = obj.Value;
                        }
                        cacheTransition.Clear();

                        foreach (var obj in cacheAnimationEvent)
                        {
                            UnityEditor.AnimationUtility.SetAnimationEvents(obj.Key, obj.Value);
                        }
                        cacheAnimationEvent.Clear();
                        try
                        {
                            PrepareBoneTexture(aniInfo);
                            SetupAnimationTexture(aniInfo);
                            SaveAnimationInfo(generatedScript.aniFilename, workingInfo);

                            Debug.Log("Complete !!!!");
                        }
                        catch (System.Exception erro)
                        {
                            Debug.LogError(erro);
                        }

                        DestroyImmediate(workingInfo.animator.gameObject);
                        EditorUtility.ClearProgressBar();
                        AssetDatabase.Refresh();
                    }

                    if (workingInfo.animator != null)
                    {
                        workingInfo.animator.gameObject.transform.position = Vector3.zero;
                        workingInfo.animator.gameObject.transform.rotation = Quaternion.identity;
                    }
                    workingInfo = null;
                    return;
                }

                float deltaTime = workingInfo.length / (workingInfo.info.totalFrame - 1);
                workingInfo.animator.Update(deltaTime);
            }
        }