Unity AssetBundle 网格丢失顶点色

原因

在将资源打包成 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);
                }
            }
        }
    }
}

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity AssetBundle Browser是Unity引擎的一款插件,它可以帮助游戏开发者在编辑器内浏览和管理AssetBundle资源。AssetBundle资源是游戏制作过程中必需的一种资源,它可以将一些预制件、贴图、声音和代码等打包成二进制文件,并在运行时通过代码加载到游戏中,从而实现动态加载资源和减少加载时间的效果。 Unity AssetBundle Browser插件提供了一个可视化的资源管理界面,用户可以通过它对资源进行打包、解包、浏览、删除等操作。在使用AssetBundle资源时,由于资源文件的二进制格式与编辑器内资源格式不同,开发者需要将资源文件打包成AssetBundle进行加载。Unity AssetBundle Browser将这个过程简化了,用户只需选择需要打包的资源,设置相关参数,并点击打包按钮,就可以轻松地创建AssetBundle文件,并将其加载到游戏中。 此外,Unity AssetBundle Browser还支持实时预览AssetBundle资源,开发者可以通过它快速地浏览预制件、纹理、材质球等资源,从而提高开发效率。总的来说,Unity AssetBundle Browser是一款十分实用的插件,它为开发者提供了一种便捷的方式去管理和使用AssetBundle资源,使游戏制作变得更加高效和便捷。 ### 回答2: Unity AssetBundle Browser是一个Unity扩展工具,用于在IDE中浏览和管理AssetBundle。AssetBundle是一种Unity资源包,可以使开发者轻松创建和管理资源,如纹理、声音和模型等。 Unity AssetBundle Browser可以让开发者直观地查看AssetBundle文件的内容,包括资源列表、依赖关系和预览功能。此外,它还提供了打包、解包、压缩和解压缩AssetBundle文件的功能,使开发者可以更灵活地使用AssetBundle,以满足项目需求。 使用Unity AssetBundle Browser,开发者可以快速地浏览和编辑AssetBundle,节省了大量的时间和精力。它还可以帮助开发者更好地理解AssetBundle的工作原理,为开发者深入学习Unity提供了一个重要的工具。 总之,Unity AssetBundle Browser是一个非常有用的工具,可以帮助Unity开发者更高效地管理和使用AssetBundle,提高项目开发效率和质量。 ### 回答3: Unity AssetBundle Browser是Unity游戏引擎中的一个工具,可以用于浏览和导出AssetBundle资源包。AssetBundle是一种Unity的资源打包方式,可以将游戏中的资源打包成一个文件,方便后续的版本管理和部署。 使用AssetBundle Browser可以很方便地管理和处理AssetBundle资源包,包括在游戏中动态加载和卸载资源,减小游戏的内存占用和优化游戏性能。通过AssetBundle Browser,我们可以查看和编辑资源包中的资源,例如模型、贴图、音频等,并提供了一套完整的编辑工具,支持资源导入、复制、删改等操作。 在游戏开发中,AssetBundle Browser可以用于优化游戏的资源处理方式,提高游戏性能,同时也可以帮助开发者更加高效地管理和打包游戏资源。值得注意的是,AssetBundle Browser只适用于Unity游戏引擎,需要Unity开发环境的支持。因此,开发者在使用AssetBundle Browser时,需要提前了解Unity的相关知识和技术,否则会影响到开发效率和质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值