public InstanceAnimationInfo FindAnimationInfo(string pFileName, AnimationInstancing instance)
        {
            Debug.Assert(pFileName != null);
            InstanceAnimationInfo info = null;

            if (m_animationInfo.TryGetValue(pFileName, out info))
            {
                return(info);
            }

            // #if UNITY_IPHONE || UNITY_ANDROID
            //             Debug.Assert(m_useBundle);
            //          if (m_mainBundle == null)
            //              Debug.LogError("You should call LoadAnimationAssetBundle first.");
            // #endif
            //             if (m_useBundle)
            //             {
            //                 CreateAnimationRequest request = new CreateAnimationRequest();
            //                 request.prefab = prefab;
            //                 request.instance = instance;
            //                 if (m_mainBundle != null)
            //                 {
            //                     StartCoroutine(LoadAnimationInfoFromAssetBundle(request));
            //                 }
            //                 else
            //                 {
            //                     m_requestList.Add(request);
            //                 }
            //                 return null;
            //             }
            //             else
            return(CreateAnimationInfoFromFile(pFileName));
        }
示例#2
0
 public void Deattach(AnimationInstancing attachment)
 {
     attachment.visible        = false;
     attachment.parentInstance = null;
     RefreshAttachmentAnimation(-1);
     listAttachment.Remove(attachment);
 }
        public void AddInstance(GameObject obj)
        {
            AnimationInstancing script = obj.GetComponent <AnimationInstancing>();

            Debug.Assert(script != null);
            if (script == null)
            {
                Debug.LogError("The prefab you created doesn't attach the script 'AnimationInstancing'.");
                Destroy(obj);
                return;
            }

            try
            {
                bool success = script.InitializeAnimation();
                if (success)
                {
                    aniInstancingList.Add(script);
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e.ToString());
                Debug.Log("Initialize animation failed. Please check out the backed animation infos and regenerate it.");
                script.enabled = false;
            }
        }
        public GameObject CreateInstance(GameObject prefab)
        {
            Debug.Assert(prefab != null);
            GameObject          obj             = Instantiate(prefab, Vector3.zero, Quaternion.identity);
            AnimationInstancing script          = obj.GetComponent <AnimationInstancing>();
            AnimationInstancing prototypeScript = prefab.GetComponent <AnimationInstancing>();

            return(obj);
        }
 public override void InitNode(AnimationInstancing pAnimator)
 {
     motionIndex         = pAnimator.FindAnimationInfo(motionHash);
     animatorTransitions = new AnimatorTransition[transLength];
     for (int i = 0; i < transLength; i++)
     {
         var item = stateInfo.transtionList[i];
         AnimatorTransition item2 = new AnimatorTransition(parameters, item, i);
         animatorTransitions[i] = item2;
     }
 }
示例#6
0
        private void Initialize()
        {
            AnimationInstancing instance = GetComponent <AnimationInstancing>();

            if (instance)
            {
                int count = instance.GetAnimationCount();
                //instance.PlayAnimation(Random.Range(0, count));
                AnimationInstancing attachmentScript = attachment.GetComponent <AnimationInstancing>();
                instance.Attach("ik_hand_r", attachmentScript);
            }

            updateObject = new UpdateObject(this, UpdateRender);
            PlayableUpdateManager.Reg(updateObject);
        }
        public void RemoveInstance(AnimationInstancing instance)
        {
            Debug.Assert(aniInstancingList != null);
            bool removed = aniInstancingList.Remove(instance);

            if (removed)
            {
                --usedBoundingSphereCount;
                cullingGroup.SetBoundingSphereCount(usedBoundingSphereCount);
                Debug.Assert(usedBoundingSphereCount >= 0);
                if (usedBoundingSphereCount < 0)
                {
                    Debug.DebugBreak();
                }
            }
        }
        public override void InitNode(AnimationInstancing pAnimator)
        {
            var tpam = parameters;

            layerLength = layerListInfo.Count;
            LayerList   = new RuntimeAnimatorLayer[layerLength];
            for (int i = 0; i < layerLength; i++)
            {
                var item     = layerListInfo[i];
                var trtlayer = new RuntimeAnimatorLayer(item)
                {
                    parameters = tpam
                };
                trtlayer.InitNode(pAnimator);
                LayerList[i] = trtlayer;
            }
        }
示例#9
0
 private void RefreshAttachmentAnimation(int index)
 {
     for (int k = 0; k != listAttachment.Count; ++k)
     {
         AnimationInstancing attachment = listAttachment[k];
         //attachment.aniIndex = aniIndex;
         for (int i = 0; i != attachment.lodInfo.Length; ++i)
         {
             LodInfo info = attachment.lodInfo[i];
             for (int j = 0; j != info.meshRenderer.Length; ++j)
             {
                 //MeshRenderer render = info.meshRenderer[j];
                 VertexCache cache = info.vertexCacheList[info.skinnedMeshRenderer.Length + j];
                 cache.boneTextureIndex = index;
             }
         }
     }
 }
示例#10
0
        static void DrawGizmo(AnimationInstancing instance, GizmoType gizmoType)
        {
            //Gizmos.DrawSphere(instance.gameObject.transform.position, 3);
            if (!instance.enabled)
            {
                return;
            }
            if (EditorApplication.isPlaying)
            {
                return;
            }

            GameObject obj = instance.gameObject;

            SkinnedMeshRenderer[] render = obj.GetComponentsInChildren <SkinnedMeshRenderer>();
            for (int i = 0; i != render.Length; ++i)
            {
                Gizmos.DrawMesh(render[i].sharedMesh, obj.transform.position, obj.transform.rotation);
            }
        }
        private void ApplyRootMotion(AnimationInstancing instance)
        {
            AnimationInfo info = instance.GetCurrentAnimationInfo();

            if (info == null || !info.rootMotion)
            {
                return;
            }

            int preSampleFrame  = (int)instance.curFrame;
            int nextSampleFrame = (int)(instance.curFrame + 1.0f);

            if (nextSampleFrame >= info.totalFrame)
            {
                return;
            }

            Vector3 preVelocity     = info.velocity[preSampleFrame];
            Vector3 nextVelocity    = info.velocity[nextSampleFrame];
            Vector3 velocity        = Vector3.Lerp(preVelocity, nextVelocity, instance.curFrame - preSampleFrame);
            Vector3 angularVelocity = Vector3.Lerp(info.angularVelocity[preSampleFrame], info.angularVelocity[nextSampleFrame], instance.curFrame - preSampleFrame);

            {
                Quaternion localQuaternion = instance.worldTransform.localRotation;
                Quaternion delta           = Quaternion.Euler(angularVelocity * Time.deltaTime);
                localQuaternion = localQuaternion * delta;

                Vector3 offset = velocity * Time.deltaTime;
                offset = localQuaternion * offset;
                //offset.y = 0.0f;
                Vector3 localPosition = instance.worldTransform.localPosition;
                localPosition += offset;
#if UNITY_5_6_OR_NEWER
                instance.worldTransform.SetPositionAndRotation(localPosition, localQuaternion);
#else
                instance.worldTransform.localPosition = localPosition;
                instance.worldTransform.localRotation = localQuaternion;
#endif
            }
        }
        public override void InitNode(AnimationInstancing pAnimator)
        {
            var tpam = parameters;

            machineCount = layerInfo.machines.Count;
            machineList  = new RuntimeAnimatorMachine[machineCount];
            for (int i = 0; i < machineCount; i++)
            {
                var item     = layerInfo.machines[i];
                var tmachine = new RuntimeAnimatorMachine(item)
                {
                    parameters = tpam
                };
                tmachine.InitNode(pAnimator);
                machineList[i] = tmachine;
                hashMap.Add(tmachine.machineHashName, i);
            }
            if (machineCount > 0)
            {
                defaultStateMachine = machineList[0];
            }
        }
        public override void InitNode(AnimationInstancing pAnimator)
        {
            var tpam = parameters;

            stateLength = machineInfo.stateInfos.Count;
            stateList   = new RuntimeAnimatorState[stateLength];
            for (int i = 0; i < stateLength; i++)
            {
                var item   = machineInfo.stateInfos[i];
                var tstate = new RuntimeAnimatorState(item)
                {
                    parameters = tpam
                };
                tstate.InitNode(pAnimator);

                if (tstate.nameHash == machineInfo.defaultHashName)
                {
                    defaultState = tstate;
                }
                stateList[i] = tstate;

                hashMap.Add(tstate.nameHash, i);
            }
        }
示例#14
0
        void BakeWithAnimator()
        {
            if (generatedPrefab != null)
            {
                generatedObject                    = Instantiate(generatedPrefab);
                Selection.activeGameObject         = generatedObject;
                generatedObject.transform.position = Vector3.zero;
                generatedObject.transform.rotation = Quaternion.identity;
                Animator animator = generatedObject.GetComponentInChildren <Animator>();

                AnimationInstancing script = generatedObject.GetComponent <AnimationInstancing>();
                Debug.Assert(script);
                SkinnedMeshRenderer[] meshRender    = generatedObject.GetComponentsInChildren <SkinnedMeshRenderer>();
                List <Matrix4x4>      bindPose      = new List <Matrix4x4>(150);
                Transform[]           boneTransform = RuntimeHelper.MergeBone(meshRender, bindPose);

                // calculate the bindpose of attached points
                if (generatedFbx)
                {
                    List <Transform> listExtra  = new List <Transform>();
                    Transform[]      trans      = generatedFbx.GetComponentsInChildren <Transform>();
                    Transform[]      bakedTrans = generatedObject.GetComponentsInChildren <Transform>();
                    foreach (var obj in selectExtraBone)
                    {
                        if (!obj.Value)
                        {
                            continue;
                        }

                        for (int i = 0; i != trans.Length; ++i)
                        {
                            Transform tran = trans[i] as Transform;
                            if (tran.name == obj.Key)
                            {
                                bindPose.Add(tran.localToWorldMatrix);
                                listExtra.Add(bakedTrans[i]);
                            }
                        }
                    }

                    Transform[] totalTransform = new Transform[boneTransform.Length + listExtra.Count];
                    System.Array.Copy(boneTransform, totalTransform, boneTransform.Length);
                    System.Array.Copy(listExtra.ToArray(), 0, totalTransform, boneTransform.Length, listExtra.Count);
                    boneTransform = totalTransform;
                    //boneTransform = boneTransform;

                    extraBoneInfo               = new ExtraBoneInfo();
                    extraBoneInfo.extraBone     = new string[listExtra.Count];
                    extraBoneInfo.extraBindPose = new Matrix4x4[listExtra.Count];
                    for (int i = 0; i != listExtra.Count; ++i)
                    {
                        extraBoneInfo.extraBone[i]     = listExtra[i].name;
                        extraBoneInfo.extraBindPose[i] = bindPose[bindPose.Count - listExtra.Count + i];
                    }
                }
                Reset();
                AddMeshVertex2Generate(meshRender, boneTransform, bindPose.ToArray());

                Transform rootNode = meshRender[0].rootBone;
                for (int j = 0; j != meshRender.Length; ++j)
                {
                    meshRender[j].enabled = true;
                }
                animator.applyRootMotion = true;
                totalFrame = 0;

                //初始化数据
                cacheTransition.Clear();
                cacheAnimationEvent.Clear();
                layerInfos.Clear();

                AnimationInstancing instance = generatedPrefab.GetComponent <AnimationInstancing>();
                if (instance == null)
                {
                    Debug.LogError("You should select a prefab with AnimationInstancing component.");
                    return;
                }
                SetFileName(generatedPrefab);

                var controller = animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController;
                var tlayers    = controller.layers;
                for (int i = 0; i < tlayers.Length; i++)
                {
                    var layer = tlayers[i];
                    var tinfo = new AnimationLayerInfo()
                    {
                        name = layer.name, index = i
                    };
                    AnalyzeStateMachine(tinfo, layer, layer.stateMachine, animator, meshRender, 0, aniFps, 0);
                    layerInfos.Add(tinfo);
                }
                // UnityEditor.Animations.AnimatorControllerLayer layer = controller.layers[0];
                //AnalyzeStateMachine(layer.stateMachine, animator, meshRender, 0, aniFps, 0);
                generateCount = generateInfo.Count;
            }
        }
示例#15
0
        public void Attach(string boneName, AnimationInstancing attachment)
        {
            int index    = -1;
            int hashBone = boneName.GetHashCode();

            for (int i = 0; i != allTransforms.Length; ++i)
            {
                if (allTransforms[i].name.GetHashCode() == hashBone)
                {
                    index = i;
                    break;
                }
            }
            Debug.Assert(index >= 0);
            if (index < 0)
            {
                Debug.LogError("Can't find the bone.");
                return;
            }
            if (attachment.lodInfo[0].meshRenderer.Length == 0 && attachment.lodInfo[0].skinnedMeshRenderer.Length == 0)
            {
                Debug.LogError("The attachment doesn't have a Renderer");
                return;
            }

            attachment.parentInstance = this;
            VertexCache parentCache = AnimationInstancingMgr.Instance.FindVertexCache(lodInfo[0].skinnedMeshRenderer[0].name.GetHashCode());

            listAttachment.Add(attachment);

            int nameCode = boneName.GetHashCode();

            nameCode += attachment.lodInfo[0].meshRenderer.Length > 0 ? attachment.lodInfo[0].meshRenderer[0].name.GetHashCode() : 0;
            if (attachment.lodInfo[0].meshRenderer.Length == 0)
            {
                //todo, to support the attachment that has skinnedMeshRenderer;
                int skinnedMeshRenderCount = attachment.lodInfo[0].skinnedMeshRenderer.Length;
                nameCode += skinnedMeshRenderCount > 0 ? attachment.lodInfo[0].skinnedMeshRenderer[0].name.GetHashCode() : 0;
            }
            VertexCache cache = AnimationInstancingMgr.Instance.FindVertexCache(nameCode);

            // if we can reuse the VertexCache, we don't need to create one
            if (cache != null)
            {
                cache.boneTextureIndex = parentCache.boneTextureIndex;
                return;
            }

            AnimationInstancingMgr.Instance.AddMeshVertex(attachment.aniFilename,
                                                          attachment.lodInfo,
                                                          null,
                                                          null,
                                                          attachment.bonePerVertex,
                                                          boneName);

            for (int i = 0; i != attachment.lodInfo.Length; ++i)
            {
                LodInfo info = attachment.lodInfo[i];
                for (int j = 0; j != info.meshRenderer.Length; ++j)
                {
                    cache = info.vertexCacheList[info.skinnedMeshRenderer.Length + j];
                    Debug.Assert(cache != null);
                    if (cache == null)
                    {
                        Debug.LogError("Can't find the VertexCache.");
                        continue;
                    }
                    Debug.Assert(cache.boneTextureIndex < 0 || cache.boneIndex[0].x != index);

                    AnimationInstancingMgr.Instance.BindAttachment(parentCache, cache, info.meshFilter[j].sharedMesh, index);
                    AnimationInstancingMgr.Instance.SetupAdditionalData(cache);
                    cache.boneTextureIndex = parentCache.boneTextureIndex;
                }
            }
        }
示例#16
0
        public void UpdateAnimation()
        {
            if (aniInfo == null || IsPause())
            {
                return;
            }

            if (isInTransition)
            {
                transitionTimer += Time.deltaTime;
                float weight = transitionTimer / transitionDuration;
                transitionProgress = Mathf.Min(weight, 1.0f);
                if (transitionProgress >= 1.0f)
                {
                    isInTransition = false;
                    preAniIndex    = -1;
                    preAniFrame    = -1;
                }
            }
            float speed = playSpeed * speedParameter;

            curFrame += speed * Time.deltaTime * aniInfo[aniIndex].fps;
            int totalFrame = aniInfo[aniIndex].totalFrame;

            curProcess = Mathf.Clamp01(curFrame / totalFrame);
            switch (wrapMode)
            {
            case WrapMode.Loop:
            {
                if (curFrame < 0f)
                {
                    curFrame += (totalFrame - 1);
                }
                else if (curFrame > totalFrame - 1)
                {
                    curProcess = 1;
                    curFrame  -= (totalFrame - 1);
                }
                break;
            }

            case WrapMode.PingPong:
            {
                if (curFrame < 0f)
                {
                    speedParameter = Mathf.Abs(speedParameter);
                    curFrame       = Mathf.Abs(curFrame);
                }
                else if (curFrame > totalFrame - 1)
                {
                    speedParameter = -Mathf.Abs(speedParameter);
                    curFrame       = 2 * (totalFrame - 1) - curFrame;
                    curProcess     = 1;
                }
                break;
            }

            case WrapMode.Default:
            case WrapMode.Once:
            {
                if (curFrame < 0f || curFrame > totalFrame - 1.0f)
                {
                    Pause();
                    curProcess = 1;
                }
                break;
            }
            }

            curFrame = Mathf.Clamp(curFrame, 0f, totalFrame - 1);
            for (int i = 0; i != listAttachment.Count; ++i)
            {
                AnimationInstancing attachment = listAttachment[i];
                attachment.transform.position = transform.position;
                attachment.transform.rotation = transform.rotation;
            }
            UpdateAnimationEvent();
            UpdateState();
        }
 public void AddBoundingSphere(AnimationInstancing instance)
 {
     boundingSphere[usedBoundingSphereCount++] = instance.boundingSpere;
     cullingGroup.SetBoundingSphereCount(usedBoundingSphereCount);
     instance.visible = cullingGroup.IsVisible(usedBoundingSphereCount - 1);
 }
        void ApplyBoneMatrix()
        {
            Vector3 cameraPosition = cameraTransform.position;

            for (int i = 0; i != aniInstancingList.Count; ++i)
            {
                AnimationInstancing instance = aniInstancingList[i];
                if (!instance.IsPlaying())
                {
                    continue;
                }
                if (instance.aniIndex < 0 && instance.parentInstance == null)
                {
                    continue;
                }

                if (instance.applyRootMotion)
                {
                    ApplyRootMotion(instance);
                }

                instance.UpdateAnimation();
                instance.boundingSpere.position = instance.worldTransform.position;
                boundingSphere[i] = instance.boundingSpere;

                if (!instance.visible)
                {
                    continue;
                }
                instance.UpdateLod(cameraPosition);

                AnimationInstancing.LodInfo lod = instance.lodInfo[instance.lodLevel];
                int aniTextureIndex             = -1;
                if (instance.parentInstance != null)
                {
                    aniTextureIndex = instance.parentInstance.aniTextureIndex;
                }
                else
                {
                    aniTextureIndex = instance.aniTextureIndex;
                }

                Matrix4x4 worldMat = instance.worldTransform.localToWorldMatrix;
                for (int j = 0; j != lod.vertexCacheList.Length; ++j)
                {
                    VertexCache   cache = lod.vertexCacheList[j];
                    MaterialBlock block = lod.materialBlockList[j];
                    Debug.Assert(block != null);
                    int packageIndex = block.runtimePackageIndex[aniTextureIndex];
                    Debug.Assert(packageIndex < block.packageList[aniTextureIndex].Count);
                    InstancingPackage package = block.packageList[aniTextureIndex][packageIndex];
                    if (package.instancingCount + 1 > instancingPackageSize)
                    {
                        ++block.runtimePackageIndex[aniTextureIndex];
                        packageIndex = block.runtimePackageIndex[aniTextureIndex];
                        if (packageIndex >= block.packageList[aniTextureIndex].Count)
                        {
                            InstancingPackage newPackage = CreatePackage(block.instanceData,
                                                                         cache.mesh,
                                                                         cache.materials,
                                                                         aniTextureIndex);
                            block.packageList[aniTextureIndex].Add(newPackage);
                            PreparePackageMaterial(newPackage, cache, aniTextureIndex);
                            newPackage.instancingCount = 1;
                        }
                        block.packageList[aniTextureIndex][packageIndex].instancingCount = 1;
                    }
                    else
                    {
                        ++package.instancingCount;
                    }

                    {
                        VertexCache       vertexCache = cache;
                        InstanceData      data        = block.instanceData;
                        int               index       = block.runtimePackageIndex[aniTextureIndex];
                        InstancingPackage pkg         = block.packageList[aniTextureIndex][index];
                        int               count       = pkg.instancingCount - 1;
                        if (count >= 0)
                        {
                            Matrix4x4[] arrayMat = data.worldMatrix[aniTextureIndex][index];
                            arrayMat[count].m00 = worldMat.m00;
                            arrayMat[count].m01 = worldMat.m01;
                            arrayMat[count].m02 = worldMat.m02;
                            arrayMat[count].m03 = worldMat.m03;
                            arrayMat[count].m10 = worldMat.m10;
                            arrayMat[count].m11 = worldMat.m11;
                            arrayMat[count].m12 = worldMat.m12;
                            arrayMat[count].m13 = worldMat.m13;
                            arrayMat[count].m20 = worldMat.m20;
                            arrayMat[count].m21 = worldMat.m21;
                            arrayMat[count].m22 = worldMat.m22;
                            arrayMat[count].m23 = worldMat.m23;
                            arrayMat[count].m30 = worldMat.m30;
                            arrayMat[count].m31 = worldMat.m31;
                            arrayMat[count].m32 = worldMat.m32;
                            arrayMat[count].m33 = worldMat.m33;
                            float frameIndex = 0, preFrameIndex = -1, transition = 0f;
                            if (instance.parentInstance != null)
                            {
                                frameIndex = instance.parentInstance.aniInfo[instance.parentInstance.aniIndex].animationIndex + instance.parentInstance.curFrame;
                                if (instance.parentInstance.preAniIndex >= 0)
                                {
                                    preFrameIndex = instance.parentInstance.aniInfo[instance.parentInstance.preAniIndex].animationIndex + instance.parentInstance.preAniFrame;
                                }
                                transition = instance.parentInstance.transitionProgress;
                            }
                            else
                            {
                                frameIndex = instance.aniInfo[instance.aniIndex].animationIndex + instance.curFrame;
                                if (instance.preAniIndex >= 0)
                                {
                                    preFrameIndex = instance.aniInfo[instance.preAniIndex].animationIndex + instance.preAniFrame;
                                }
                                transition = instance.transitionProgress;
                            }
                            data.frameIndex[aniTextureIndex][index][count]         = frameIndex;
                            data.preFrameIndex[aniTextureIndex][index][count]      = preFrameIndex;
                            data.transitionProgress[aniTextureIndex][index][count] = transition;
                        }
                    }
                }
            }
        }
示例#19
0
        private void OnGUI()
        {
            GUI.skin.label.richText = true;
            GUILayout.BeginHorizontal();
            {
                GUILayout.FlexibleSpace();
            }
            GUILayout.EndHorizontal();

            GameObject prefab = EditorGUILayout.ObjectField("Asset to Generate", generatedPrefab, typeof(GameObject), true) as GameObject;

            if (prefab != generatedPrefab)
            {
                generateAnims.Clear();
                customClips.Clear();
                generatedPrefab = prefab;
                SetFileName(generatedPrefab);
                generatedScript = generatedPrefab?.GetComponent <AnimationInstancing>();
                SkinnedMeshRenderer[] meshRender = generatedPrefab.GetComponentsInChildren <SkinnedMeshRenderer>();
                List <Matrix4x4>      bindPose   = new List <Matrix4x4>(150);
                boneTransform = RuntimeHelper.MergeBone(meshRender, bindPose);
            }

            if (generatedPrefab == null)
            {
                EditorGUILayout.LabelField("Error: the object is null");
                return;
            }

            if (generatedScript != null)
            {
                generatedScript.aniFilename = EditorGUILayout.TextField("aniFilename", generatedScript.aniFilename);
            }
            else
            {
                EditorGUILayout.LabelField("Error: the object is not have AnimationInstancing");
                return;
            }

            bool error = false;

            if (generatedPrefab)
            {
                exposeAttachments = EditorGUILayout.Toggle("Enable Attachments", exposeAttachments);
                if (exposeAttachments)
                {
                    showAttachmentSetting = EditorGUILayout.Foldout(showAttachmentSetting, "Attachment setting");
                    if (showAttachmentSetting)
                    {
                        EditorGUI.BeginChangeCheck();
                        GameObject fbx = EditorGUILayout.ObjectField("FBX refrenced by Prefab:", generatedFbx, typeof(GameObject), false) as GameObject;
                        if (EditorGUI.EndChangeCheck())
                        {
                            if (fbx != generatedFbx)
                            {
                                SkinnedMeshRenderer[] meshRender = generatedPrefab.GetComponentsInChildren <SkinnedMeshRenderer>();
                                List <Matrix4x4>      bindPose   = new List <Matrix4x4>(150);
                                boneTransform = RuntimeHelper.MergeBone(meshRender, bindPose);

                                generatedFbx = fbx;
                                var allTrans = generatedPrefab.GetComponentsInChildren <Transform>().ToList();
                                allTrans.RemoveAll(q => boneTransform.Contains(q));

                                //var allTrans = boneTransform;
                                selectExtraBone.Clear();
                                for (int i = 0; i != allTrans.Count; ++i)
                                {
                                    selectExtraBone.Add(allTrans[i].name, false);
                                }
                            }
                            else if (fbx == null)
                            {
                                selectExtraBone.Clear();
                            }
                        }
                        if (selectExtraBone.Count > 0)
                        {
                            var temp = new Dictionary <string, bool>();
                            foreach (var obj in selectExtraBone)
                            {
                                temp[obj.Key] = obj.Value;
                            }
                            scrollPosition2 = GUILayout.BeginScrollView(scrollPosition2);
                            foreach (var obj in temp)
                            {
                                bool value = EditorGUILayout.Toggle(string.Format("   {0}", obj.Key), obj.Value);
                                selectExtraBone[obj.Key] = value;
                            }
                            GUILayout.EndScrollView();
                        }
                    }
                }
                else
                {
                    generatedFbx = null;
                }

                aniFps = EditorGUILayout.IntSlider("FPS", aniFps, 1, 120);

                Animator animator = generatedPrefab.GetComponentInChildren <Animator>();
                if (animator == null)
                {
                    EditorGUILayout.LabelField("Error: The prefab should have a Animator Component.");
                    return;
                }
                if (animator.runtimeAnimatorController == null)
                {
                    EditorGUILayout.LabelField("Error: The prefab's Animator should have a Animator Controller.");
                    return;
                }
                var        clips       = GetClips(animator);
                string[]   clipNames   = generateAnims.Keys.ToArray();
                int        totalFrames = 0;
                List <int> frames      = new List <int>();
                foreach (var clipName in clipNames)
                {
                    if (!generateAnims[clipName])
                    {
                        continue;
                    }

                    AnimationClip clip = clips.Find(delegate(AnimationClip c)
                    {
                        if (c != null)
                        {
                            return(c.name == clipName);
                        }
                        return(false);
                    });
                    int framesToBake = clip ? (int)(clip.length * aniFps / 1.0f) : 1;
                    framesToBake = Mathf.Clamp(framesToBake, 1, framesToBake);
                    totalFrames += framesToBake;
                    frames.Add(framesToBake);
                }

                int textureCount = 1;
                int textureWidth = CalculateTextureSize(out textureCount, frames.ToArray(), boneTransform);
                error = textureCount == 0;
                if (textureCount == 0)
                {
                    EditorGUILayout.LabelField("Error: There is certain animation's frames which is larger than a whole texture.");
                }
                else if (textureCount == 1)
                {
                    EditorGUILayout.LabelField(string.Format("Animation Texture will be one {0} X {1} texture", textureWidth, textureWidth));
                }
                else
                {
                    EditorGUILayout.LabelField(string.Format("Animation Texture will be {2} 1024 X 1024 and one {0} X {1} textures", textureWidth, textureWidth, textureCount - 1));
                }

                scrollPosition = GUILayout.BeginScrollView(scrollPosition);
                foreach (var clipName in clipNames)
                {
                    AnimationClip clip = clips.Find(delegate(AnimationClip c)
                    {
                        if (c != null)
                        {
                            return(c.name == clipName);
                        }
                        return(false);
                    });
                    int framesToBake = clip ? (int)(clip.length * aniFps / 1.0f) : 1;
                    framesToBake = Mathf.Clamp(framesToBake, 1, framesToBake);
                    GUILayout.BeginHorizontal();
                    {
                        generateAnims[clipName] = EditorGUILayout.Toggle(string.Format("({0}) {1} ", framesToBake, clipName), generateAnims[clipName]);
                        GUI.enabled             = generateAnims[clipName];
                        //frameSkips[clipName] = Mathf.Clamp(EditorGUILayout.IntField(frameSkips[clipName]), 1, fps);
                        GUI.enabled = true;
                    }
                    GUILayout.EndHorizontal();
                    if (framesToBake > 5000)
                    {
                        GUI.skin.label.richText = true;
                        EditorGUILayout.LabelField("<color=red>Long animations degrade performance, consider using a higher frame skip value.</color>", GUI.skin.label);
                    }
                }
                GUILayout.EndScrollView();
            }

            if (generatedPrefab && !error)
            {
                if (GUILayout.Button(string.Format("Generate")))
                {
                    if (string.IsNullOrEmpty(generatedScript.aniFilename))
                    {
                        if (EditorUtility.DisplayDialog("Setting FileName for Animation ", string.Format("Set AniFileName To {0} ?.", generatedPrefab.name), "Set ", "cancel"))
                        {
                            SetFileName(generatedPrefab);
                        }
                        else
                        {
                            return;
                        }
                    }

                    string tfile = GetFullPahtFile(generatedScript.aniFilename);
                    if (File.Exists(tfile))
                    {
                        if (EditorUtility.DisplayDialog("Export To Animation", string.Format("{0} is already in path {1}.", generatedScript.aniFilename, tfile), "OverWrite", "cancel"))
                        {
                            BakeWithAnimator();
                        }
                    }
                    else
                    {
                        BakeWithAnimator();
                    }
                }
            }
        }