Unity AssetBundle 网格丢失顶点色

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/akof1314/article/details/80291799

原因

在将资源打包成 AssetBundle 进行加载时,发现有一些特效没有达到预期的效果,如下可以看到圆形的硬边:


分析

将这个特效资源导出到另一个工程,单独打包 AssetBundle 进行加载,发现没有问题,如下所示:


对比原 AssetBundle 文件,发现特效里使用的模型因为也被其他特效使用,所以单独打成了依赖的 AssetBundle 包。然后用解包工具解包,用 3D MAX 打开,可以看到:


单独打包的模型 AssetBundle 里面,其模型信息不带有有顶点色。


跟特效一起打包的 AssetBundle 里面,其模型信息带有顶点色。

解决

经了解,是 Unity 的 【 Optimize Mesh Data】功能导致打包 AssetBundle 的时候,自动去除了模型上多余的数据。当模型单独打包的时候,不会检测到特效使用了顶点色数据,所以不保留顶点色数据,详细说明见《 针对移动平台打assetbundle 时,optimize mesh data 选项开启会造成mesh 顶点色不可用的问题》。

文章里面也提到可以将模型开启【 Import Materials】,然后将其默认材质换成使用顶点色的着色器,这样即使单独打包,也不会丢失顶点色。

但是,工程里面对特效的模型都做了导入时统一处理,全部关闭了【Import Materials】,如果将这个处理关闭的话,那么就会产生很多无用的材质。所以这里协定,当导入的设置【Material Naming】为【Model Name + Model’s Material】时,则不强制关闭【Import Materials】,如下所示:

另外,模型的默认材质名称不规范,会使得工程乱七八糟,如果再让美术去重新导模型的话,工作量太大,而且也不能保证之后材质名称会规范命名,所以这里使用 OnAssignMaterialModel 接口来拦截模型的附加材质生成。

代码如下:

using System.IO;
using UnityEditor;
using UnityEngine;

public class MyMeshPostprocessor : AssetPostprocessor
{
    private bool IsEffectModel()
    {
        return assetPath.StartsWith("Assets/AB/Effects/Model");
    }

    private void OnPreprocessModel()
    {
        if (IsEffectModel())
        {
            ModelImporter modelImporter = assetImporter as ModelImporter;
            if (modelImporter && modelImporter.materialName != ModelImporterMaterialName.BasedOnModelNameAndMaterialName)
            {
                modelImporter.importMaterials = false;
            }
        }
    }

    private Material OnAssignMaterialModel(Material material, Renderer renderer)
    {
        if (IsEffectModel())
        {
            ModelImporter modelImporter = assetImporter as ModelImporter;
            if (modelImporter && modelImporter.importMaterials)
            {
                string matPath = Path.GetDirectoryName(assetPath) + "/" + Path.GetFileNameWithoutExtension(assetPath) + ".mat";
                Material mat = AssetDatabase.LoadAssetAtPath<Material>(matPath);
                if (mat)
                {
                    return mat;
                }
                AssetDatabase.CreateAsset(material, matPath);
                return material;
            }
        }

        return null;
    }
}

更近一步,为了不需要记住操作的步骤,增加菜单一键功能,代码如下:

 C# Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using  System.IO;
using  UnityEditor;
using  UnityEngine;

namespace  Tools
{
    
public   static   class  FbxPrefabTool
    {
        [MenuItem(
"Assets/FbxTool/特效模型-保留顶点色" )]
        
private   static   void  HoldOnFbxPrefabsVertexColor()
        {
            
foreach  (var o  in  Selection.objects)
            {
                ModifyFbxPrefabVertexColor(o, 
true );
            }
        }

        [MenuItem(
"Assets/FbxTool/特效模型-去除顶点色" )]
        
private   static   void  GiveUpFbxPrefabsVertexColor()
        {
            
foreach  (var o  in  Selection.objects)
            {
                ModifyFbxPrefabVertexColor(o, 
false );
            }
        }

        [MenuItem(
"Assets/FbxTool/特效模型-保留顶点色" true )]
        [MenuItem(
"Assets/FbxTool/特效模型-去除顶点色" true )]
        
private   static   bool  ValidateFbxPrefabsVertexColor()
        {
            
foreach  (var obj  in  Selection.objects)
            {
                
if  (!obj)
                {
                    
return   false ;
                }
                
if  (PrefabUtility.GetPrefabType(obj) != PrefabType.ModelPrefab)
                {
                    
return   false ;
                }

                
string  fbxPath = AssetDatabase.GetAssetPath(obj);
                
if  (!fbxPath.StartsWith( "Assets/AB/Effects/Model" ))
                {
                    
return   false ;
                }
            }
            
return   true ;
        }

        
private   static   void  ModifyFbxPrefabVertexColor(Object obj,  bool  holdOn)
        {
            
if  (!obj)
            {
                
return ;
            }
            
if  (PrefabUtility.GetPrefabType(obj) != PrefabType.ModelPrefab)
            {
                
return ;
            }

            
string  fbxPath = AssetDatabase.GetAssetPath(obj);
            
if  (!fbxPath.StartsWith( "Assets/AB/Effects/Model" ))
            {
                
return ;
            }
            AssetImporter ai = AssetImporter.GetAtPath(fbxPath);
            
if  (!ai)
            {
                
return ;
            }
            ModelImporter modelImporter = ai 
as  ModelImporter;
            
if  (!modelImporter)
            {
                
return ;
            }
            
string  matPath = Path.GetDirectoryName(fbxPath) +  "/"  + Path.GetFileNameWithoutExtension(fbxPath) +  ".mat" ;

            
if  (holdOn)
            {
                
if  (modelImporter.materialName != ModelImporterMaterialName.BasedOnModelNameAndMaterialName
                    || !modelImporter.importMaterials)
                {
                    modelImporter.materialName = ModelImporterMaterialName.BasedOnModelNameAndMaterialName;
                    modelImporter.importMaterials = 
true ;
                    AssetDatabase.ImportAsset(modelImporter.assetPath, ImportAssetOptions.ForceUpdate);

                    Material mat = AssetDatabase.LoadAssetAtPath<Material>(matPath);
                    
if  (mat)
                    {
                        mat.shader = Shader.Find(
"Mobile/Particles/Alpha Blended" );
                    }
                }
            }
            
else
            {
                
if  (modelImporter.materialName == ModelImporterMaterialName.BasedOnModelNameAndMaterialName)
                {
                    modelImporter.materialName = ModelImporterMaterialName.BasedOnTextureName;
                    modelImporter.SaveAndReimport();
                    AssetDatabase.DeleteAsset(matPath);
                }
            }
        }
    }
}

最后自动生成效果如下所示:


猜你喜欢

转载自blog.csdn.net/akof1314/article/details/80291799
今日推荐