• 合并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();
            }
        }
        
    }
  • 相关阅读:
    Apache Ant自动化脚本
    使用Mybatis Generator结合Ant脚本快速自动生成Model、Mapper等文件的方法
    Maven Pom文件标签详解
    JAVA正则表达式语法大全
    RSA加密算法--Java实现详细案例:
    Java加密技术(一)——BASE64与单向加密算法MD5&SHA&MAC
    Base64算法的使用
    ElasticSearch使用IK中文分词---安装步骤记录
    ElasticSearch Java api 详解_V1.0
    HBase入门
  • 原文地址:https://www.cnblogs.com/weiqiangwaideshijie/p/15650524.html
Copyright © 2020-2023  润新知