Esempio n. 1
0
        public void Prepare(AnimationInfo[] pinfos, ExtraBoneInfo extraBoneInfo)
        {
            //extraBoneInfo = extraBoneInfo;
            List <Matrix4x4> bindPose = new List <Matrix4x4>(150);

            // to optimize, MergeBone don't need to call every time
            Transform[] bones = RuntimeHelper.MergeBone(lodInfo[0].skinnedMeshRenderer, bindPose);
            allTransforms = bones;

            if (extraBoneInfo != null)
            {
                List <Transform> list = new List <Transform>();
                list.AddRange(bones);
                Transform[] transforms = gameObject.GetComponentsInChildren <Transform>();
                for (int i = 0; i != extraBoneInfo.extraBone.Length; ++i)
                {
                    for (int j = 0; j != transforms.Length; ++j)
                    {
                        if (extraBoneInfo.extraBone[i] == transforms[j].name)
                        {
                            list.Add(transforms[j]);
                        }
                    }
                    bindPose.Add(extraBoneInfo.extraBindPose[i]);
                }
                allTransforms = list.ToArray();
            }


            AnimationInstancingMgr.Instance.AddMeshVertex(aniFilename,
                                                          lodInfo,
                                                          allTransforms,
                                                          bindPose,
                                                          bonePerVertex);

            foreach (var lod in lodInfo)
            {
                foreach (var cache in lod.vertexCacheList)
                {
                    cache.shadowcastingMode = shadowCastingMode;
                    cache.receiveShadow     = receiveShadow;
                    cache.layer             = layer;
                }
            }

            Destroy(GetComponent <Animator>());
        }
Esempio n. 2
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;
            }
        }
Esempio n. 3
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();
                    }
                }
            }
        }