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();
            }
        }
        
    }
  • 相关阅读:
    缺少环境变量导致Xilinx Platform Studio无法打开之解决方法
    PS利用EMIO控制LED灯
    利用zedboard添加自定义IP核完成简易计算器
    读后感 关于 《不要一辈子靠技术混饭吃》(挪窝第一篇)
    挪窝了,再谈blog
    windows server 2008 无法打开角色,角色错误,刷新服务器时出现意外错误,HRESULT:0x80070422
    Linux 基础正则表达式和扩展正则表达式
    Linux 基础正则表达式
    Linux 通配符与特殊符号
    Linux 基础命令
  • 原文地址:https://www.cnblogs.com/weiqiangwaideshijie/p/15650524.html
Copyright © 2011-2022 走看看