版本:3.7.4
一、无动画材质切换
使用两个演示案例
1:喷图
在这个git地址之上进行修改
注意:对一个模型进行喷图时,由于是对材质进行操作,所以需要场景模型是整个模型。
效果如下:
改动:在Canvas上添加一个按钮,替代原本点击喷图事件,用来喷图,
这里有两种方式进行资源的引用:
1.使用上面git地址的方式@property(Material),将材质直接拖入引用到控制器中
2.在assets目录下新建resources目录,创建材质->引用图片,通过代码的方式动态创建喷图。
在addDecal方法中最后地方改为
if (dmr) {
const newMat = new Material();
this.sprayMat((res) => {
newMat.copy(res);
//贴图背景颜色
// newMat.setProperty('albedo', new Vec4(Math.random(), Math.random(), Math.random(), 1));
dmr.material = newMat;
})
}
sprayMat(callback) {
resources.load("spray/" + this.matName, Material, (err, prefab) => {
return callback(prefab)
});
}
2.换皮
这里只能针对无动画模型,添加一个换皮的操作按钮,
同上述引入方式一样,
1:通过将材质和网格直接拖入引用到控制器中,可直接引用
此时为:
this.node.getComponent(MeshRenderer).material=this.lianyi;
this.node.getComponent(MeshRenderer).mesh=this.lianyimesh
2:将皮肤模型放到resources目录下,
此时为:
resources.load("lianyi/DR_182_shd", Material, (err, prefab) => {
this.node.getComponent(MeshRenderer).material=prefab;
});
resources.load("lianyi/mesh", Mesh, (err, prefab) => {
this.node.getComponent(MeshRenderer).mesh=prefab;
});
如果模型材质为多个:
上面材质改为:
let path=["box_model_honglianyi_body_no/BTM_shd","box_model_honglianyi_body_no/PANTS_shd","box_model_honglianyi_body_no/TOP_shd"]
resources.load(path, Material, (err, prefab) => {
no.getComponent(MeshRenderer).materials=prefab;
});
二、有动画
如果是人物模型动画进行换肤,可能是由于动画绑定的原因,上述方式操作绑定不了网格,
我是在制作模型时,挑选几个衣服版型套入到人物模型上,只保留网格即可,然后绑定骨骼和T动画,再制作动画,然后给衣服制作多种多样的样式。
将人物模型和衣服(这里只需要贴图就可以)做好后导入到cocos中,再在resources目录下给衣服制作材质,(如果选择不制作,将衣服的fbx放到resources也可以的)
在资源中引入模型,隐藏所有的衣服网格。最后只需要在使用的时候显示衣服版型的网格,和选择resources下的材质即可。目前也只能想到这种方式。
装配动作:外部定义了角色动作组manAnim,将动作放在resources目录下,只需要在start方法中执行下面方法即可装配动作,因为load的是AnimationClip,所以path路径是到fbx文件下的动作,所以制作动作资源时命名要规范。
//根据角色装配动作库
public static assAnimByRole(node){
let arr=manAnim
for(let i=0;i<arr.length;i++){
let path = "anim/"+role+"/"+arr[i].code+'/'+arr[i].code
resources.load(path, AnimationClip, (err, prefab) => {
let clips=node.getComponent(SkeletalAnimation).clips
clips.push(prefab)
node.getComponent(SkeletalAnimation).clips=clips
});
}
}
三、模型透视
模型透视:无法正确移植自己项目中:在材质中勾选下图设置,是重要的一步
扩展:原项目需要手动设定透视模型的pass主贴图
let children = node.children
for (let i = 0; i < children.length; i++) {
if (children[i].active && children[i].getComponent(SkinnedMeshRenderer) && this.person_filter_list.indexOf(children[i].name) < 0) {
resources.load(build_mate_path, Material, (err, res) => {
//获取原始mate
let orgmate = children[i].getComponent(SkinnedMeshRenderer).materials[0]
let pa0t = orgmate.getProperty('mainTexture', 0) as Texture2D
if (pa0t) {
//指定pass 的主贴图
let newMat = new Material();
newMat.copy(res);
newMat.setProperty('mainTexture', pa0t, 1)
//替换mate
console.log(children[i].name)
children[i].getComponent(SkinnedMeshRenderer).materials = [newMat]
}
});
}
}
使用上述方法实现自动设定,node为角色,person_filter_list为需要排除的模型部件,比如,人体的眼睛,睫毛,牙齿等不需要透视的部件模型。