使用 PackTextures

来源:互联网 发布:mac tower 破解版下载 编辑:程序博客网 时间:2024/06/03 17:50
using UnityEngine;using System.Collections.Generic;using System;public partial class Test {    public GameObject Test(GameObject target, UnityEngine.Object[] partsPrefabs, bool isPartGo = false) {        //float startTime = Time.realtimeSinceStartup;        if (target == null) {            target = new GameObject();        }        // 寻找骨头根节点        Transform rootBoneTrans = target.transform.Find(ROOT_BONE_NAME);        if (null == rootBoneTrans) {            return target;        }        GameObject rootBone = rootBoneTrans.gameObject;        // 收集所有部件的 SkinnedMeshRenderer        List<SkinnedMeshRenderer> smrs = new List<SkinnedMeshRenderer>();        for (int i = 0; i < partsPrefabs.Length; i++) {            UnityEngine.Object partPerfab = partsPrefabs[i];            GameObject partObj = null;            if (isPartGo) {                partObj = partPerfab as GameObject;            } else {                partObj = (GameObject)GameObject.Instantiate(partPerfab);            }            SkinnedMeshRenderer partObjSmr = partObj.GetComponentInChildren<SkinnedMeshRenderer>();            smrs.Add(partObjSmr);        }        List<CombineInstance> combineInstances = new List<CombineInstance>();        List<Material> materials = new List<Material>();        Transform[] transforms = rootBone.GetComponentsInChildren<Transform>();        List<Texture2D> textures = new List<Texture2D>();        int width = 0;        int height = 0;                List<Transform> bones = new List<Transform>();        Material material = null;        int uvCount = 0;        List<Vector2[]> uvList = new List<Vector2[]>();        SkinnedMeshRenderer smr = null;        for (int i = 0; i < smrs.Count; i++) {            smr = smrs[i];            if (material == null) //要求部件的材质都一致,新合成的mesh也用一样的材质                material = GameObject.Instantiate(smr.sharedMaterial) as Material;            for (int sub = 0; sub < smr.sharedMesh.subMeshCount; sub++) {                CombineInstance ci = new CombineInstance();                ci.mesh = smr.sharedMesh;                ci.subMeshIndex = sub;                combineInstances.Add(ci);            }            uvList.Add(smr.sharedMesh.uv);            uvCount += smr.sharedMesh.uv.Length;            if (smr.sharedMaterial.mainTexture != null) {                Renderer render = smr.GetComponent<Renderer>();                textures.Add(render.sharedMaterial.mainTexture as Texture2D);                width += render.sharedMaterial.mainTexture.width;                height += render.sharedMaterial.mainTexture.height;            }            //收集合并的骨骼            foreach (Transform bone in smr.bones) {                foreach (Transform transform in transforms) {                    if (transform.name != bone.name)                        continue;                    bones.Add(transform);                    break;                }            }            //删掉部件#if UNITY_EDITOR            if (!Application.isPlaying) {                GameObject.DestroyImmediate(smr.transform.parent.gameObject);            } else {                GameObject.Destroy(smr.transform.parent.gameObject);            }#else             GameObject.Destroy(smr.transform.parent.gameObject);#endif        }        //创建合成图集        Texture2D skinnedMeshAtlas = new Texture2D(2048, 1024);        Rect[] packingResult = skinnedMeshAtlas.PackTextures(textures.ToArray(), 0);        skinnedMeshAtlas.name = string.Format("--- {0}, w:{1}, h:{2}", target.name, skinnedMeshAtlas.width, skinnedMeshAtlas.height);        //重新映射uv到合成图集        Vector2[] atlasUVs = new Vector2[uvCount];        int j = 0;        for (int i = 0; i < uvList.Count; i++) {            foreach (Vector2 uv in uvList[i]) {                atlasUVs[j].x = Mathf.Lerp(packingResult[i].xMin, packingResult[i].xMax, uv.x);                atlasUVs[j].y = Mathf.Lerp(packingResult[i].yMin, packingResult[i].yMax, uv.y);                j++;            }        }        //添加GO mesh_root,用来放合成后的网格SkinnedMeshRenderer        GameObject mesh = null;        SkinnedMeshRenderer r = null;        Transform meshT = target.transform.Find("mesh_root");        if (meshT != null) {            mesh = meshT.gameObject;            r = mesh.GetComponent<SkinnedMeshRenderer>();        } else {            mesh = new GameObject("mesh_root");            mesh.transform.position = Vector3.zero;            mesh.transform.rotation = Quaternion.identity;            mesh.transform.localScale = Vector3.one;            mesh.transform.SetParent(target.transform, false);        }        if (r == null) {            r = mesh.AddComponent<SkinnedMeshRenderer>();        }        r.sharedMesh = new Mesh();        r.sharedMesh.CombineMeshes(combineInstances.ToArray(), true, false);        r.bones = bones.ToArray();        r.rootBone = rootBone.transform;        //r.sharedMesh.bounds = new Bounds(Vector3.zero, r.sharedMesh.bounds.extents);        material.mainTexture = skinnedMeshAtlas;        r.sharedMesh.uv = atlasUVs;#if UNITY_EDITOR        if (!Application.isPlaying) {            r.sharedMaterial = material;        } else {            r.material = material;        }#else        r.material = material;#endif        //Debug.Log("combine meshes takes : " + (Time.realtimeSinceStartup - startTime) * 1000 + " ms");        return target;    }}