unity 3d模型换装的实现与相关注意点

1 做好裸模,绑好骨骼,k好动作。

2 做出模型需要更换的装备,刷好权重。每个部位需要拆分成单独的模型。比如衣服,鞋子,裤子等。

3 导出裸模与装备模型到unity,每种模型都需要包含骨骼,因为换装依赖的组件是SkinnedMeshRenderer,只有包含骨骼的模型,导入到unity中才会生成该组件。不包含骨骼的模型,导入到unity中只会生成Mesh Renderer。

 一定不要忘记勾选Read/Write Enabled,不勾选就不能读取模型中的顶点数据,从而无法正常实现换装功能了。

4 将导入的模型做成预制体,放到Resources目录下备用。

5 将裸模拖动到场景中,增加换装脚本。

 

换装具体思路为,从resources中加载各装备的预制文件,并生成相应的gameobject,再从生成的gameobject的SkinnedMeshRenderer组件中读取当前装备模型的顶点,材质,骨骼等数据。待所有需要更换的数据读取完成后,更新场景中裸模的skinnedMeshRenderer组件信息,从而实现换装。

因为没有正式代码,都是测试用的,就不贴代码了,用伪代码代替吧。

GameObject baseModel;
Transform[] allBones;
void Start(){
    baseModel=this.gameObject;

    //获取裸模所有的子物体数据(主要是裸模包含的骨骼数据)
    allBones=baseModel.GetComponentsInChildren<Transform>();

    //新建一个集合,用来存储各部件装备的实例化对象
    List<GameObject> equips=new List<GameObject>();
    equips.add(GameObject.Instantiate(Resources.Load("衣服模型预制") as GameObject));
    equips.add(GameObject.Instantiate(Resources.Load("裤子模型预制") as GameObject));
    equips.add(GameObject.Instantiate(Resources.Load("鞋子模型预制") as GameObject));


    List<CombineInstance> combines=new List<CombineInstance>();
    List<Transform> combineBones=new List<Transform>();
    List<Material> materials=new List<>(Material);
    //遍历实例化对象的SkinnedMeshRenderer组件,取出顶点骨骼材质数据
    foreach(GameObject equip in equips){

        //获取实例化装备对象的skinnedMeshRenderer组件进行后续操作
        //可能存在一个模型包含多个物体,也就会出现多个skinnedmeshrenderer对象,所以要获取全部的smr并进行处理
        SkinnedMeshRenderer[] smrs=equip.getComponentsInChildren<SkinnedMeshRenderer>();
        foreach(SkinnedMeshRenderer smr in smrs){
            materials.AddRange(smr.materials);
            //获取smr对象中包含的网格数据 存储到combineInstance对象中,以便后续进行合并操作
            for(int x=0;x<smr.sharedMesh.subMeshCount;x++){
                CombineInstance cInstance=new CombineInstance();
                cInstance.subMeshIndex=x;
                cInstance.mesh=smr.sharedMesh;
                combines.Add(cInstance);
            }
            //遍历骨骼信息
            for(int x=0;x<smr.bones.Length;x++){
                foreach(Transform bone in allBones){
                    if(smr.bones[x].name==bone.name){
                        combineBones.Add(bone);
                    }
                }
            }
        }
        //数据处理完成后,销毁生成的装备预制体
        Destory(equip);
    }    
    
    //合并提取的数据,生成新的SkinnedMeshRender,设置到裸模中
    SkinnedMeshRenderer newSmr = baseModel.AddComponent<SkinnedMeshRenderer>();
    newSmr.sharedMesh = new Mesh();
    newSmr.bones = combineBones.ToArray();
    newSmr.sharedMesh.CombineMeshes(combines.ToArray(), false, false);
    newSmr.materials = mats.ToArray();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值