换装原理初探

换装系列文章:
换装原理初探
换装原理中篇
换装原理实践
换装英文中称为Character Customization,在游戏中很常见。换装的基本步骤如下。

  • MaleModel预设制作,此模型包括所有样式的SkinnedMeshRenderer和骨骼,并以一定规则命名,比如eye有三种,则命名为eye-1,eye-2,eye-3。
  • MaleTarget预设制作,此模型只包含骨骼。
  • 加载MaleModel和MaleTarget。
  • 保存数据,将MaleModel中的所有样式SkinnedMeshRenderer组件保存在字典中maleData,将MaleTarget中的骨骼保存在数组maleHips中,为MaleTarget添加所有身体部件,例如eye、body,并将此保存到另一个字典中targetData。
  • 换装,在给定身体部件名称和序号的情况下,从maleData数组中找到相应的SkinnedMeshRenderer组件part,从中提取骨骼信息,遍历骨骼,在MaleTarget中的骨骼中找到对应骨骼,并保存为数组bones。将MaleTarget相应的SkinnedMeshRenderer组件中的骨骼绑定为bones,网格替换为part的网格,材质替换为part的材质。
    最后,给出相应的代码如下。
using System.Collections.Generic;
using UnityEngine;

public class AvataCustomization : MonoBehaviour
{
    private Transform maleModelTrans;
    private Transform maleTargetTrans;

    private Dictionary<string, Dictionary<string, SkinnedMeshRenderer>> maleData = new Dictionary<string, Dictionary<string, SkinnedMeshRenderer>>();
    private Dictionary<string, SkinnedMeshRenderer> targetData = new Dictionary<string, SkinnedMeshRenderer>();
    private Transform[] maleHips;

    private void Start()
    {
        InitiateModel();
        InitiateTarget();
        SaveData();
    }

    void InitiateModel()
    {
        GameObject maleModel = GameObject.Instantiate(Resources.Load("MaleModel")) as GameObject;
        maleModelTrans = maleModel.transform;
        maleModel.SetActive(false);
    }

    void InitiateTarget()
    {
        GameObject maleTarget = GameObject.Instantiate(Resources.Load("MaleTarget")) as GameObject;
        maleTargetTrans = maleTarget.transform;       
    }

    void SaveData()
    {
        SkinnedMeshRenderer[] parts = maleModelTrans.GetComponentsInChildren<SkinnedMeshRenderer>();
        maleHips = maleTargetTrans.GetComponentsInChildren<Transform>();
        foreach (SkinnedMeshRenderer part in parts)
        {
            string[] names = part.name.Split('-');

            if(!maleData.ContainsKey(names[0]))
            {
                GameObject partGo = new GameObject();
                partGo.name = names[0];
                partGo.transform.SetParent(maleTargetTrans);
                maleData.Add(names[0], new Dictionary<string, SkinnedMeshRenderer>());
                targetData.Add(names[0], partGo.AddComponent<SkinnedMeshRenderer>());
            }
            maleData[names[0]].Add(names[1], part);
        }
    }

    void ChangeStyle(string partName, string num)
    {
        SkinnedMeshRenderer part = maleData[partName][num];
        List<Transform> bones = new List<Transform>();
        foreach(var trans in part.bones)
        {
            foreach(var bone in maleHips)
            {
                if(bone.name == trans.name)
                {
                    bones.Add(bone);
                    break;
                }
            }
        }
        targetData[partName].bones = bones.ToArray();
        targetData[partName].sharedMesh = part.sharedMesh;
        targetData[partName].material = part.material;
    }
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值