zoukankan      html  css  js  c++  java
  • 合并SkinnedMeshRender实现换装

    using System.Collections;
    using System.Collections.Generic;
    using UnityEditor;
    using UnityEngine;
    
    public class CombineSkinnedMeshMananger
    {
    
        private const int MAXTEXTURESIZE = 512;
        public void CombineSkinnedMeshRender(GameObject instance, SkinnedMeshRenderer[] skinnedMeshRenderers,bool isCombine =false)
        {
            if (instance == null)
            {
                return;
            }
            List<Transform> transforms = new List<Transform>();
            transforms.AddRange(instance.GetComponentsInChildren<Transform>(true));
            
            List<CombineInstance> combineInstances = new List<CombineInstance>(); //网格
            List<Transform> bones = new List<Transform>(); //骨骼
            List<Material> materials= new List<Material>(); //材质
    
            if (skinnedMeshRenderers == null || skinnedMeshRenderers.Length == 0)
            {
                return;
            }
    
            for (int i = 0; i < skinnedMeshRenderers.Length; i++)
            {
                SkinnedMeshRenderer smr = skinnedMeshRenderers[i];
                //收集材质
                materials.AddRange(smr.materials);
                //收集网格
                for (int j = 0; j < smr.sharedMesh.subMeshCount; j++)
                {
                    CombineInstance combineInstance = new CombineInstance();
                    combineInstance.mesh = smr.sharedMesh;
                    combineInstance.subMeshIndex = j;
                    combineInstances.Add(combineInstance);
                }
                
                //收集骨骼
                for (int j = 0; j < smr.bones.Length; j++)
                {
                    for (int k = 0; k < transforms.Count; k++)
                    {
                        if (smr.bones[j].name.Equals(transforms[k].name))
                        {
                            bones.Add(transforms[k]);
                            break;
                        }
                    }
                }
            }
    
            List<Vector2[]> oldUV = null;
            Material newMaterila = null;
            Texture2D newDiffuseTex = null;
            //合并材质
            if (isCombine)
            {
                //这里材质类型和没有合并之前的材质类型要保持一直
                newMaterila = new Material(Shader.Find("Mobile/Diffuse"));
                oldUV = new List<Vector2[]>();
                
                //合并贴图
                List<Texture2D> textures = new List<Texture2D>();
                for (int i = 0; i < materials.Count; i++)
                {
                    textures.Add(materials[i].GetTexture("_MainTex") as Texture2D);
                }
                newDiffuseTex = new Texture2D(MAXTEXTURESIZE,MAXTEXTURESIZE,TextureFormat.RGBA32,true);
                Rect[] uvs = newDiffuseTex.PackTextures(textures.ToArray(), 0);
                newMaterila.mainTexture = newDiffuseTex;
                
                //重置UV ???
                Vector2[] uva, uvb;
                for (int j = 0; j < combineInstances.Count; j++)
                {
                    uva = combineInstances[j].mesh.uv;
                    uvb = new Vector2[uva.Length];
                    for (int k = 0; k < uva.Length; k++)
                    {
                        uvb[k] = new Vector2((uva[k].x * uvs[j].width) + uvs[j].x, (uva[k].y * uvs[j].height) + uvs[j].y);
                    }
                    oldUV.Add(combineInstances[j].mesh.uv);
                    combineInstances[j].mesh.uv = uvb;
                }
            }
    
            //重新绑定SkinnedMeshRenderer
            SkinnedMeshRenderer oldSkinnedMeshRenderer = instance.GetComponent<SkinnedMeshRenderer>();
            if (oldSkinnedMeshRenderer != null)
            {
                GameObject.DestroyImmediate(oldSkinnedMeshRenderer);
            }
            SkinnedMeshRenderer skinnedMeshRenderer = instance.AddComponent<SkinnedMeshRenderer>();
            skinnedMeshRenderer.sharedMesh = new Mesh();
            skinnedMeshRenderer.sharedMesh.CombineMeshes(combineInstances.ToArray(), isCombine,false);
            skinnedMeshRenderer.bones = bones.ToArray();
            if (isCombine)
            {
                skinnedMeshRenderer.material = newMaterila;
                //??? 这里为啥又换回来了
                for (int i = 0 ; i < combineInstances.Count ; i ++)
                {
                    combineInstances[i].mesh.uv = oldUV[i];
                }
            }
            else
            {
                skinnedMeshRenderer.materials = materials.ToArray();
            }
        }
        
    }
  • 相关阅读:
    前端必看的数据可视化入门指南
    win10下查看进程,杀死进程
    前端如何使用proxyTable和nginx解决跨域问题
    vue-wechat-title动态修改title
    npm与cnpm混用导致的问题
    sass与less对比学习
    nginx,作为前端的你会多少?
    Ubuntu16.04安装python3.7及相应的pip
    漫游Kafka设计篇之性能优化(7)
    漫游Kafka设计篇之消息传输的事务定义(5)
  • 原文地址:https://www.cnblogs.com/weiqiangwaideshijie/p/15650524.html
Copyright © 2011-2022 走看看