[Unity实战]详解换装系统(二)
来源:互联网 发布:js div弹出层 编辑:程序博客网 时间:2024/06/01 07:28
首先推荐一些关于换装的好东西:
文章:http://bbs.9ria.com/thread-185477-1-1.html
视频:http://www.unitytrain.cn/course/55
其中代码很大程度上是参考以上两个的。。
首先在场景中我们要有一套带有所有部位的模型,以及一副骨架,前者在场景中时隐藏的,换装的时候,我们就从前者找部位给骨架。
模型的层次:
模型带有所有的部位,如上图所示,有两套face、hair等等,注意一下命名规则。
骨架的层次:
其实就是把模型的Female_Hips取出来了。
模型主要由mesh和骨架组成,因为target已经有骨架了,所以换装时只需要添加或替换mesh,然后将mesh绑定到target的骨架上即可。
代码如下:
using UnityEngine;using System.Collections;using System.Collections.Generic;public class AvatarSys : MonoBehaviour { public static AvatarSys instance; //来源模型 private Transform source; //目标骨架 private Transform target; //存放来源模型的信息,分别为部位名字,部位编号,部位的SkinnedMeshRenderer组件 //根据部位名字,部位编号取得想要的部位 private Dictionary<string, Dictionary<string, SkinnedMeshRenderer>> sourceData = new Dictionary<string, Dictionary<string, SkinnedMeshRenderer>>(); //存放目标骨架的信息,分别为部位名字,部位上的SkinnedMeshRenderer组件 //没有编号是因为target上只有一套 private Dictionary<string, SkinnedMeshRenderer> targetSmr = new Dictionary<string, SkinnedMeshRenderer>(); //存放目标骨架的骨架信息,用于mesh绑定骨架 private Transform[] hips; //部位信息,目标骨架初始化为模型时需要的部位,注意命名是依据来源模型上的部位命名的 string[,] avatarStr = new string[,]{{"face","1"},{"hair","1"}, {"pants","1"},{"shoes","1"},{"top","1"}};// Use this for initializationvoid Start () { instance = this; InstantiateSource();//实例化来源模型 InstantiateTarget();//实例化目标骨架 SaveData();//存储来源模型和目标骨架的信息 InitAvatar();//将目标骨架初始化为模型 target.animation.PlayQueued("walk");} void InstantiateSource() { GameObject sourceObj = Instantiate(Resources.Load("Source")) as GameObject; source = sourceObj.transform; sourceObj.SetActive(false); } void InstantiateTarget() { GameObject targetObj = Instantiate(Resources.Load("Target")) as GameObject; target = targetObj.transform; hips = target.GetComponentsInChildren<Transform>(); } void SaveData() { if ((source == null) || (target == null)) return; SkinnedMeshRenderer[] parts = source.GetComponentsInChildren<SkinnedMeshRenderer>(true);//true表示把隐藏部位的组件也获得 foreach (SkinnedMeshRenderer part in parts) { string[] partName = part.name.Split('-'); if (!sourceData.ContainsKey(partName[0]))//每有一种新类型的部位 { //每有一种新类型的部位就在骨架下生成一个空GameObject GameObject partobj = new GameObject(); partobj.name = partName[0]; partobj.transform.parent = target; //部位类型只记录一次 sourceData.Add(partName[0], new Dictionary<string, SkinnedMeshRenderer>()); //targetSmr只记录一套部位的信息,例如裤子有两套模型,只记录一套的 //因为target是用来展示的,各种部位只要一套即可 targetSmr.Add(partName[0],partobj.AddComponent<SkinnedMeshRenderer>()); } //sourceData记录所有部位信息 sourceData[partName[0]].Add(partName[1], part); } } public void ChangeMesh(string part,string num)//传入部位名字,编号 { //因为sourceData记录所有部位信息,所以可以查找到所要的新的部位 SkinnedMeshRenderer smr = sourceData[part][num]; List<Transform> bones = new List<Transform>(); //根据新的部位绑定的骨架信息,在target的骨架上找到相应的位置 //例如头发mesh,在source中它绑定在脑袋上,那么我们在target上也要找到脑袋这个位置 foreach (Transform bone in smr.bones) { foreach(Transform hip in hips) { if (hip.name == bone.name) { bones.Add(hip); break; } } } targetSmr[part].materials = smr.materials;//更换材质 targetSmr[part].sharedMesh = smr.sharedMesh;//更换mesh targetSmr[part].bones = bones.ToArray();//将mesh绑定到合适的骨架中 } void InitAvatar() { int length = avatarStr.GetLength(0); for (int i = 0; i < length; i++) { ChangeMesh(avatarStr[i, 0], avatarStr[i, 1]); } }}
要注意的是要将target上的Animation组件的Play Automatically取消掉才能播放动画。
效果图:
模型下载地址:
http://yun.baidu.com/s/1o6FVqCM
0 0
- [Unity实战]详解换装系统(二)
- [Unity实战]详解换装系统(一)
- [Unity实战]详解换装系统(三)
- [Unity实战]详解换装系统(四)
- [Unity实战]换装系统的原理
- Unity换装系统设计
- Unity换装系统(1)
- Unity换装系统(2)
- unity人物模型换装系统浅析
- Unity换装
- Unity 换装
- Unity换装
- Unity 3D Avatar换装系统 SkinnedMeshRenderer皮肤渲染
- Unity游戏换装
- Unity 角色换装原理
- Unity游戏换装
- Unity之角色换装
- Unity换装的实现
- Python补充02 Python小技巧
- spring的占位符
- Java 正则表达式详解
- Rails中Array转为ActiveRecord::Relation
- MongoDB学习笔记(索引)
- [Unity实战]详解换装系统(二)
- 智慧城市包含的内容
- JSF--javax.faces.context.FacesContext
- css属性介绍
- 安卓面试宝典
- qemu-kvm虚拟机live迁移源代码解读
- 《人生智慧录》摘抄
- hdu 1281 二分图-匈牙利算法
- MongoDB学习笔记(数据操作)