zoukankan      html  css  js  c++  java
  • unity换装系统+网格合并

    这里的做法是模型把所有衣服全部穿上作为一个资源

    然后还有一个只有骨骼信息的骨架资源

    将这2个制作好了Prefab

    模型部件数据

    资源数据

    【代码】

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class AvatarSystem : MonoBehaviour {
    
        //模型全文件
        GameObject modelObject;
        Transform modelSource;
        //骨骼文件
        GameObject targetSource;
        Transform targetTrans;
        //Data字典 存储source的各种信息;
        private Dictionary<string, Dictionary<string, Transform>> data = new Dictionary<string, Dictionary<string, Transform>>();
        //targetSmr字典 存储目标的骨骼信息
        private Dictionary<string, SkinnedMeshRenderer> targetSmr = new Dictionary<string, SkinnedMeshRenderer>();
        //骨骼数组
        private Transform[] hips;
        //套装数据
        string[,] avatarStr = new string[,] { { "Glove", "suit01" }, { "Head", "suit01" }, { "Hair", "suit01" }, { "Body", "suit02" }, { "Leg", "suit03" }, { "Shoe", "suit03" } };
    
        // Use this for initialization
        void Start () {
            InstantiateAvatar("Prefab/Model_girl");//读取模型文件
            InstantiateSkeleton("Prefab/Target_girl");//读取骨架文件
            LoadAvatarData(modelSource);//读取模型所有衣服数据,并且存储
            hips = targetTrans.GetComponentsInChildren<Transform>();//拿取人物骨骼信息
            Inivatar(avatarStr);//换上套装
            //targetSource.AddComponent<Animator>();
        }
        
        // Update is called once per frame
        void Update () {
            
        }
    
    
        //实例化来源
        void InstantiateAvatar(string modelName)
        {
            //必需得实例化出来,不然无法获得数据
            modelObject = (Instantiate(Resources.Load<GameObject>(modelName)));
            modelSource = modelObject.transform;
            modelSource.gameObject.SetActive(false);//隐藏
            //Destroy(modelObject);//销毁
        }
        //实例化骨架(换装就是在骨架上加衣服)
        void InstantiateSkeleton(string targetName)
        {
            targetSource = Instantiate(Resources.Load<GameObject>(targetName));
            targetTrans = targetSource.transform;
        }
        //读取来源的各种信息(source模型源文件)
        void LoadAvatarData(Transform source)
        {
            if (source == null)
            {
                return;
            }
            SkinnedMeshRenderer[] parts = source.GetComponentsInChildren<SkinnedMeshRenderer>(true);
            foreach (SkinnedMeshRenderer part in parts)
            {
                string[] partName = part.name.Split('_');
                if (!data.ContainsKey(partName[0]))
                {
                    data.Add(partName[0], new Dictionary<string, Transform>());
                    GameObject partObj = new GameObject();
                    partObj.name = partName[0];
                    partObj.transform.parent = targetTrans;
                    targetSmr.Add(partName[0], partObj.AddComponent<SkinnedMeshRenderer>());
                }
                data[partName[0]].Add(partName[1], part.transform);
            }
        }
        //更改Mesh
        public void ChangeMesh(string part, string item)
        {
            SkinnedMeshRenderer smr = data[part][item].GetComponent<SkinnedMeshRenderer>();
            //网格合并
            List<CombineInstance> combineInstances = new List<CombineInstance>();
            for (int i = 0; i < smr.sharedMesh.subMeshCount; i++)
            {
                CombineInstance ci = new CombineInstance();
                ci.mesh = smr.sharedMesh;
                ci.subMeshIndex = i;
                combineInstances.Add(ci);
            }
            List<Transform> bones = new List<Transform>();
            foreach (Transform bone in smr.bones)
            {
                foreach (Transform hip in hips)
                {
                    if (hip.name != bone.name)
                    {
                        continue;
                    }
                    bones.Add(hip);
                    break;
                }
            }
    
            //网格合并方式
            targetSmr[part].sharedMesh = new Mesh();
            targetSmr[part].sharedMesh.CombineMeshes(combineInstances.ToArray(), false, false);
            //非网格合并方式
            //targetSmr[part].sharedMesh = smr.sharedMesh;
            targetSmr[part].bones = bones.ToArray();
            targetSmr[part].materials = smr.materials;
    
    
        }
    
        /// <summary>
        /// 换装(换1件到多件)
        /// </summary>
        /// <param name="avatarStr"></param>
        public void Inivatar(string[,] avatarStr)
        {
            int nLength = avatarStr.GetLength(0);
            for (int i = 0; i < nLength; i++)
            {
                ChangeMesh(avatarStr[i, 0], avatarStr[i, 1]);
            }
        }
    }
  • 相关阅读:
    linux grep命令
    PHP 利用simplexml_load_file 读取XML对应的字段 然后存入mysql数据库
    php 设计模式之单类模式
    Mac C#开发工具Rider安利与环境配置教程
    模拟,贪心,枚举(二)
    模拟,贪心,枚举
    10.10 review
    review 10.9
    10.6 review
    9.28 review
  • 原文地址:https://www.cnblogs.com/sanyejun/p/9110886.html
Copyright © 2011-2022 走看看