Beispiel #1
0
 public static T GetColumnUnsafe <T>(this ConfigLine self, string column)
 {
     try
     {
         return(self.GetColumn <T>(column));
     }
     catch (Exception e)
     { }
     return(default(T));
 }
Beispiel #2
0
        public static void AutoClip2()
        {
            /*
             *  读取excel表,获取动画的信息:名字,起始帧,结束帧
             *  再读取fbx的动画信息,对名字相同的进行信息merge
             *      merge:起始帧,结束帧
             *      保留:event信息,mask信息,curve信息
             *      如果有新加的,那么加入新的信息
             * **/

            // 匿名函数

            System.Func <bool, ConfigLine, SerializedProperty, int> SetPropertyFunction = delegate(bool IsHumanClip, ConfigLine csv_line, SerializedProperty sp)
            {
                sp.FindPropertyRelative("firstFrame").floatValue = csv_line.GetColumnUnsafe <float>("firstFrame");
                sp.FindPropertyRelative("lastFrame").floatValue  = csv_line.GetColumnUnsafe <float>("lastFrame");

                // LoopTime, LoopPose
                sp.FindPropertyRelative("loopTime").boolValue  = csv_line.GetColumnUnsafe <int>("loopTime") > 0;
                sp.FindPropertyRelative("loopBlend").boolValue = csv_line.GetColumnUnsafe <int>("loopBlend") > 0;

                // Rotation_BakeIntoPose, Rotation_BaseUpon
                sp.FindPropertyRelative("loopBlendOrientation").boolValue    = csv_line.GetColumnUnsafe <int>("loopBlendOrientation") > 0;
                sp.FindPropertyRelative("keepOriginalOrientation").boolValue = csv_line.GetColumnUnsafe <int>("keepOriginalOrientation") == 0;

                // PositionY_BakeIntoPose, PositionY_BaseUpon
                sp.FindPropertyRelative("loopBlendPositionY").boolValue = csv_line.GetColumnUnsafe <int>("loopBlendPositionY") > 0;
                if (IsHumanClip)
                {
                    // 如果是humanoid类型的动画,那么keepOriginalPositionY的取值为0,1,2三种。
                    sp.FindPropertyRelative("keepOriginalPositionY").boolValue = csv_line.GetColumnUnsafe <int>("keepOriginalPositionY") == 0;
                    sp.FindPropertyRelative("heightFromFeet").boolValue        = csv_line.GetColumnUnsafe <int>("keepOriginalPositionY") == 2;
                }
                else
                {
                    sp.FindPropertyRelative("keepOriginalPositionY").boolValue = csv_line.GetColumnUnsafe <int>("keepOriginalPositionY") == 0;
                }

                // PositionXZ_BakeIntoPose, PositionXZ_BaseUpon
                sp.FindPropertyRelative("loopBlendPositionXZ").boolValue    = csv_line.GetColumnUnsafe <int>("loopBlendPositionXZ") > 0;
                sp.FindPropertyRelative("keepOriginalPositionXZ").boolValue = csv_line.GetColumnUnsafe <int>("keepOriginalPositionXZ") == 0;
                return(0);
            };


            // 读取excel
            string[] files = Directory.GetFiles(Application.dataPath + "/Art/", "animations*.xls", SearchOption.AllDirectories);
            foreach (var fileName in files)
            {
                DateTime excelTime = File.GetLastWriteTime(fileName);
                Debug.Log("读取xls文件:" + fileName + ", file-write-time=" + excelTime.ToString());
                Dictionary <string, ConfigFile> excels = ReadXML(fileName);// ReadXML(Application.dataPath + "/Art/animations.xls");
                foreach (var it in excels)
                {
                    Debug.Log("处理:" + it.Key);
                    ConfigFile csv    = it.Value;
                    string[]   assets = AssetDatabase.FindAssets(it.Key, new string[] { "Assets/Art" });
                    if (assets.Length > 0)
                    {
                        string asset = AssetDatabase.GUIDToAssetPath(assets[0]);

                        // 如果.meta时间和excel时间不一样,说明有变化,否则没变化的就直接跳过
                        DateTime assetMetaTime = File.GetLastWriteTime(asset + ".meta");
                        if (DateTime.Equals(assetMetaTime, excelTime))
                        {
                            // 文件没有变化,不处理
                            Debug.Log("文件没有变化,不处理啦:" + asset);
                            continue;
                        }
                        File.SetLastWriteTime(asset + ".meta", excelTime);

                        ModelImporter modelImporter = (ModelImporter)AssetImporter.GetAtPath(asset);

                        SerializedObject           serializedObject = modelImporter == null ? null : new SerializedObject(modelImporter);
                        ModelImporterAnimationType m_AnimationType  = (ModelImporterAnimationType)serializedObject.FindProperty("m_AnimationType").intValue;
                        bool             IsHumanClip    = m_AnimationType == ModelImporterAnimationType.Human;
                        HashSet <string> processed_clip = new HashSet <string>();
                        if (serializedObject == null)
                        {
                            Debug.Log("无法处理该文件:" + asset);
                        }
                        else
                        {
                            // 压缩方式
                            serializedObject.FindProperty("m_AnimationCompression").intValue = (int)ModelImporterAnimationCompression.Optimal;

                            // 切割或者merge动画
                            SerializedProperty m_ClipAnimations = serializedObject.FindProperty("m_ClipAnimations");
                            for (int i = 0; i < m_ClipAnimations.arraySize; i++)
                            {
                                SerializedProperty sp        = m_ClipAnimations.GetArrayElementAtIndex(i);
                                string             clip_name = sp.FindPropertyRelative("name").stringValue;
                                if (clip_name.Contains("@"))
                                {
                                    clip_name = clip_name.Substring(clip_name.LastIndexOf("@") + 1);
                                }
                                ConfigLine csv_line = csv.FindData(clip_name);
                                if (csv_line != null)
                                {
                                    processed_clip.Add(clip_name);

                                    // merge基本属性
                                    SetPropertyFunction(IsHumanClip, csv_line, sp);

                                    // 其他属性,如event,mask,都不处理,保持原来信息
                                }
                            }

                            // 把剩下没处理的内容,作为新的动画,分割到fbx中
                            Dictionary <string, ConfigLine> csv_data = csv.GetLines();
                            foreach (var kt in csv_data)
                            {
                                if (processed_clip.Contains(kt.Key))
                                {
                                    continue;
                                }
                                processed_clip.Add(kt.Key);
                                ConfigLine csv_line = kt.Value;

                                m_ClipAnimations.InsertArrayElementAtIndex(m_ClipAnimations.arraySize);
                                SerializedProperty sp = m_ClipAnimations.GetArrayElementAtIndex(m_ClipAnimations.arraySize - 1);

                                sp.FindPropertyRelative("name").stringValue     = it.Key + "@" + kt.Key;
                                sp.FindPropertyRelative("takeName").stringValue = "Take 001";

                                // 处理基本属性
                                SetPropertyFunction(IsHumanClip, csv_line, sp);

                                // 设置mask
                                UnityEditorInternal.AvatarMask mask = new UnityEditorInternal.AvatarMask();
                                mask.transformCount = modelImporter.transformPaths.Length;
                                for (int i = 0; i < modelImporter.transformPaths.Length; i++)
                                {
                                    mask.SetTransformPath(i, modelImporter.transformPaths[i]);
                                    mask.SetTransformActive(i, true);
                                }
                                SerializedProperty bodyMask = sp.FindPropertyRelative("bodyMask");
                                if (bodyMask != null && bodyMask.isArray)
                                {
                                    for (int i = 0; i < mask.humanoidBodyPartCount; i++)
                                    {
                                        if (i >= bodyMask.arraySize)
                                        {
                                            bodyMask.InsertArrayElementAtIndex(i);
                                        }
                                        bodyMask.GetArrayElementAtIndex(i).intValue = mask.GetHumanoidBodyPartActive(i) ? 1 : 0;
                                    }
                                }
                                SerializedProperty transformMask = sp.FindPropertyRelative("transformMask");
                                //ModelImporter.UpdateTransformMask(mask, transformMask);
                                Type       ty = typeof(ModelImporter);
                                MethodInfo mi = ty.GetMethod("UpdateTransformMask", BindingFlags.Static | BindingFlags.NonPublic);
                                if (mi != null)
                                {
                                    mi.Invoke(null, new object[] { mask, transformMask });
                                }
                                else
                                {
                                    Debug.LogError("无法找到此方法!");
                                }
                            }

                            serializedObject.ApplyModifiedProperties();
                            AssetDatabase.WriteImportSettingsIfDirty(asset);
                            AssetDatabase.ImportAsset(asset);
                        }
                    }
                    else
                    {
                        Debug.LogError("无法找到这个FBX文件:" + it.Key);
                    }
                }
            }
        }