CombineSkinnedMeshes.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. public class CombineSkinnedMeshes : MonoBehaviour
  6. {
  7. public Transform[] DontCombineRender;
  8. /// <summary>
  9. /// 是否启用合并网格
  10. /// </summary>
  11. public bool EnableCombined = false;
  12. /// <summary>
  13. /// 是否启用离屏更新
  14. /// </summary>
  15. public bool EnableUpdateWhenOffscreen = false;
  16. Material mMat = null;
  17. Vector3 mOrgPos = Vector3.zero;
  18. Quaternion mOrgRot = Quaternion.identity;
  19. SkinnedMeshRenderer mSMR = null;
  20. Mesh mNormalMesh = null;
  21. Mesh mHidedWeaponMesh = null;
  22. public SkinQuality skinQuality = SkinQuality.Auto;
  23. void Awake()
  24. {
  25. mOrgPos = transform.localPosition;
  26. mOrgRot = transform.localRotation;
  27. mSMR = GetComponent<SkinnedMeshRenderer>();
  28. if (EnableCombined)
  29. CombineToMesh();
  30. }
  31. void Start()
  32. {
  33. if (mSMR != null)
  34. SetMat();
  35. }
  36. void OnDestroy()
  37. {
  38. if (mNormalMesh) {
  39. mNormalMesh.Destroy ();
  40. mNormalMesh = null;
  41. }
  42. if (mHidedWeaponMesh) {
  43. mHidedWeaponMesh.Destroy ();
  44. mHidedWeaponMesh = null;
  45. }
  46. DontCombineRender = null;
  47. }
  48. public SkinnedMeshRenderer GetRenderer()
  49. {
  50. return mSMR;
  51. }
  52. /// <summary>
  53. /// 模型处理函数
  54. /// </summary>
  55. void CombineToMesh()
  56. {
  57. List<CombineInstance> combineInstances = new List<CombineInstance>();
  58. List<Transform> bones = new List<Transform>();
  59. SkinnedMeshRenderer[] smrList = GetComponentsInChildren<SkinnedMeshRenderer>();
  60. if (DontCombineRender != null && DontCombineRender.Length > 0)
  61. {
  62. List<SkinnedMeshRenderer> tempList = new List<SkinnedMeshRenderer>(smrList.Length);
  63. tempList.AddRange(smrList);
  64. for (int idx = 0; idx < DontCombineRender.Length; idx++)
  65. {
  66. for (int jdx = 0; jdx < tempList.Count; jdx++)
  67. {
  68. if (tempList[jdx] == null || tempList[jdx].transform == DontCombineRender[idx])
  69. {
  70. tempList.RemoveAt(jdx);
  71. break;
  72. }
  73. }
  74. }
  75. smrList = tempList.ToArray();
  76. }
  77. for (int idx = 0; idx < smrList.Length; idx++)
  78. {
  79. SkinnedMeshRenderer smr = smrList[idx];
  80. if (mMat == null)
  81. mMat = smr.material;
  82. Mesh mesh = smr.sharedMesh;
  83. if (mesh == null)
  84. continue;
  85. CombineInstance ci = new CombineInstance();
  86. ci.mesh = mesh;
  87. ci.subMeshIndex = 0;
  88. combineInstances.Add(ci);
  89. bones.AddRange(smr.bones);
  90. Object.Destroy(smr.gameObject);
  91. }
  92. if(mSMR == null)
  93. mSMR = gameObject.AddComponent<SkinnedMeshRenderer>();
  94. mNormalMesh = new Mesh ();
  95. mNormalMesh.CombineMeshes(combineInstances.ToArray(), true, false);
  96. mSMR.quality = skinQuality;
  97. mSMR.sharedMesh = mNormalMesh;
  98. mSMR.bones = bones.ToArray();
  99. if (EnableUpdateWhenOffscreen)
  100. mSMR.updateWhenOffscreen = EnableUpdateWhenOffscreen;
  101. Bounds bounds = mSMR.localBounds;
  102. bounds.center = new Vector3(0, 0.5f, 0);
  103. bounds.extents = Vector3.one;
  104. mSMR.localBounds = bounds;
  105. for (int idx = 0; idx < smrList.Length; idx++)
  106. {
  107. SkinnedMeshRenderer mr = smrList[idx];
  108. Resources.UnloadAsset(mr.sharedMesh);
  109. mr.sharedMesh = null;
  110. }
  111. }
  112. void SetMat()
  113. {
  114. mSMR.material = mMat;
  115. }
  116. }