资源优化篇:1、清理序列化冗余文件

2020-06-07  本文已影响0人  APP4x

前提:切换资源序列化模式为Force Text
(一般在公司就是这个,因为git只能用text)

1.清理序列化文件冗余引用
材质的shader,gameobject组建的Monobehavior
开发过程中,可能之前已经赋值过,但是后来又把 shader的property或者代码的序列化参数删掉了
但是这些参数删除后,材质或者GameObject的Prefab文件中,该参数的序列化数据并未被删除
会导致AssetDataBase.GetDependencies之类的方法,取得引用时,会带入不需要的资源

a.对于一般的prefab,可以拖出来点一下apply,也就是setDirty一下,再保存就行了

EditorUtility.SetDirty(obj);
AssetDatabase.SaveAssets();

b.对于particleSystem中的mesh
如果renderType选过mesh,又切换到其他方式,这个mesh就会保存在meta文件里面

ParticleSystemRenderer[] renders = gameObj.GetComponentsInChildren<ParticleSystemRenderer>(true);
            foreach(var renderItem in renders)
            {
                if(renderItem.renderMode != ParticleSystemRenderMode.Mesh)
                {
                    renderItem.mesh = null;
                    EditorUtility.SetDirty(gameObj);
                }
            }

c.对于材质球里的参数
如果给纹理参数选了一个引用,即使把这个参数都删了,还是会存在meta里面
(unity的机制,方便切换shader使用)

 public static void ClearMaterial()
    {

        UnityEngine.Object[] objs = Selection.GetFiltered(typeof(Material), SelectionMode.DeepAssets);
        for (int i = 0; i < objs.Length; ++i)
        {
            Material mat = objs[i] as Material;

            if (mat)
            {
                SerializedObject psSource = new SerializedObject(mat);
                SerializedProperty emissionProperty = psSource.FindProperty("m_SavedProperties");//代表存储的属性
                SerializedProperty texEnvs = emissionProperty.FindPropertyRelative("m_TexEnvs");//存储所有纹理的结点,还有m_Floats、m_Colors等等。
                if (CleanMaterialSerializedProperty(texEnvs, mat))
                {
                    Debug.LogError("Find and clean useless texture propreties in " + mat.name);
                }
                psSource.ApplyModifiedProperties();
                EditorUtility.SetDirty(mat);
            }
        }

        AssetDatabase.SaveAssets();
    }

    //true: has useless propeties
    private static bool CleanMaterialSerializedProperty(SerializedProperty property, Material mat)
    {
        bool res = false;

        for (int j = property.arraySize - 1; j >= 0; j--)
        {
            string propertyName =   property.GetArrayElementAtIndex(j).FindPropertyRelative("first").stringValue;

            if (!mat.HasProperty(propertyName))//如果没有了,就删除
            {
                if(propertyName.Equals("_MainTex"))     
                {
                    //_MainTex是内建属性,是置空不删除,否则UITexture等控件在获取mat.maintexture的时候会报错
                    if (property.GetArrayElementAtIndex (j).FindPropertyRelative ("second").FindPropertyRelative ("m_Texture").objectReferenceValue != null) 
                    {
                        property.GetArrayElementAtIndex (j).FindPropertyRelative ("second").FindPropertyRelative ("m_Texture").objectReferenceValue = null;
                        Debug.Log("Set _MainTex is null");
                        res = true;
                    }
                }
                else
                {
                    property.DeleteArrayElementAtIndex(j);
                    Debug.Log("Delete property in serialized object : " + propertyName);
                    res = true;
                }
            }
        }
        return res;
    }
上一篇下一篇

猜你喜欢

热点阅读