Unity 换装

本文介绍了一种基于Unity的游戏角色换装系统实现方案。通过使用SkinnedMeshRenderer组件及骨骼绑定技术,实现了角色不同部位(头部、身体、武器)的外观替换。此方法能够高效地更新角色外观,并保持动画一致性。
摘要由CSDN通过智能技术生成
using UnityEngine;
using System.Collections.Generic;

/// <summary>
/// http://bbs.9ria.com/thread-185477-1-1.html
/// </summary>

public class ChangeAvatar : MonoBehaviour
{
    public enum AvatarPart
    {
        HEAD,
        BODY,
        WEAPON,
    }

    public GameObject mBaseModel;              //基准骨骼
    public GameObject mElementAvatar;        //待替换的元素

    private Transform[] mBaseHips;   //基准骨架。

    private Dictionary<string, SkinnedMeshRenderer> mBaseSkins = new Dictionary<string, SkinnedMeshRenderer>();  //标准蒙皮网格信息
    private Dictionary<string, SkinnedMeshRenderer> mElementSkins = new Dictionary<string, SkinnedMeshRenderer>();      //要替代的蒙皮网格信息

    void Start()
    {
        ChangePart(mBaseModel, mElementAvatar);
    }

    private void ChangePart(string part)
    {
        SkinnedMeshRenderer smr = mElementSkins[part].GetComponent<SkinnedMeshRenderer>();  //从资料中取得各部位指定编号的 SkinnedMeshRenderer
        List<Transform> bones = new List<Transform>();//取得相对应名称的骨架物件来建立新的骨架列表

        foreach (Transform bone in smr.bones)
        {
            foreach (Transform hip in mBaseHips)
            {
                if (hip.name != bone.name) continue;
                bones.Add(hip);
                break;
            }
        }

        mBaseSkins[part].sharedMesh = smr.sharedMesh;
        mBaseSkins[part].bones = bones.ToArray();
        mBaseSkins[part].materials = smr.materials;
        GameObject.Destroy(smr.gameObject);
    }

    void ChangePart(GameObject baseModel, GameObject element)
    {
        LoadBaseBips(baseModel);
        LoadAvatarData(element);

        foreach (string partName in mElementSkins.Keys)
        {
            List<Transform> bones = new List<Transform>();
            SkinnedMeshRenderer elementSkin = mElementSkins[partName];

            foreach (Transform bone in elementSkin.bones)
            {
                foreach (Transform hip in mBaseHips)
                {
                    if (hip.name != bone.name) continue;
                    bones.Add(hip);
                    break;
                }
            }

            mBaseSkins[partName].sharedMesh = elementSkin.sharedMesh;
            mBaseSkins[partName].sharedMaterials = elementSkin.sharedMaterials;
            mBaseSkins[partName].bones = bones.ToArray();
            GameObject.DestroyObject(elementSkin.gameObject);
        }
    }

    private void LoadBaseBips(GameObject baseModel)
    {
        mBaseHips = baseModel.GetComponentsInChildren<Transform>();         //初始化骨骼信息。

        foreach (SkinnedMeshRenderer part in baseModel.GetComponentsInChildren<SkinnedMeshRenderer>())  //初始化蒙皮信息
        {
            string partName = SimplifyName(part.name);
            if (!mBaseSkins.ContainsKey(partName))
            {
                mBaseSkins.Add(partName, part);
            }
        }
    }

    private void LoadAvatarData(GameObject elemetAvatar)
    {
        SkinnedMeshRenderer[] parts = elemetAvatar.GetComponentsInChildren<SkinnedMeshRenderer>();    //从来源模型资源取出各部位的 SkinnedMeshRenderer

        foreach (SkinnedMeshRenderer part in parts)
        {
            string partName = SimplifyName(part.name);
            if (!mElementSkins.ContainsKey(partName))
            {
                mElementSkins.Add(partName, part);
            }
        }
    }

    private string SimplifyName(string strName)
    {
        string[] nameArray = strName.Split('_');
        string partName = nameArray[nameArray.Length - 1];
        return partName;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值