当前位置:   article > 正文

Unity 换装方式_unity换装

unity换装

   unity换装方式一般分为三种,第一种是:直接更换物体的prefb,第二种:更换Material,第三种:更改mesh,再合并网格,做到与骨骼绑定

第一种:换模型

第二种:更换材质或者贴图

第一第二方式,如下图所示,不做过多介绍

 第三种:换蒙皮

 可以发现红框标注部分,骨骼虽然是同一种,但是所用网格是不同的,那么为了实现这种样式的换装,就需要做两种不一样的mesh,同时要保证两个mesh属于同一个骨骼,最后通过代码合并网格,代码如下

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. /// <summary>
  6. /// 角色皮肤组件
  7. /// </summary>
  8. public class RoleSkinComponent : MonoBehaviour
  9. {
  10. /// <summary>
  11. /// 根骨骼
  12. /// </summary>
  13. [SerializeField]
  14. private Transform m_RootBone;
  15. /// <summary>
  16. /// 角色身上的SkinnedMeshRenderer 一个角色只有一个SkinnedMeshRenderer
  17. /// </summary>
  18. [SerializeField]
  19. private SkinnedMeshRenderer m_CurrSkinnedMeshRenderer;
  20. /// <summary>
  21. /// 部件
  22. /// </summary>
  23. [SerializeField]
  24. private SkinnedMeshRendererPart[] Parts;
  25. /// <summary>
  26. /// 组件数组长度
  27. /// </summary>
  28. private int m_PartsLen;
  29. /// <summary>
  30. /// 角色当前穿戴的部件列表
  31. /// </summary>
  32. private List<SkinnedMeshRenderer> m_CurrPartList;
  33. /// <summary>
  34. /// 合并网格对象集合
  35. /// </summary>
  36. private List<CombineInstance> m_CombineInstances;
  37. /// <summary>
  38. /// 材质集合
  39. /// </summary>
  40. private List<Material> m_Materials;
  41. /// <summary>
  42. /// SkinnedMeshRenderer对应的骨骼信息
  43. /// </summary>
  44. private List<Transform> m_Bones;
  45. /// <summary>
  46. /// 角色身上的骨骼数组
  47. /// </summary>
  48. private Transform[] m_BoneTransforms; //角色身上的骨骼数组
  49. private void Awake()
  50. {
  51. m_CurrPartList = new List<SkinnedMeshRenderer>();
  52. m_CombineInstances = new List<CombineInstance>();
  53. m_Materials = new List<Material>();
  54. m_Bones = new List<Transform>();
  55. }
  56. private void OnDestroy()
  57. {
  58. m_CurrPartList.Clear();
  59. m_CurrPartList = null;
  60. m_CombineInstances.Clear();
  61. m_CombineInstances = null;
  62. m_Materials.Clear();
  63. m_Materials = null;
  64. m_Bones.Clear();
  65. m_Bones = null;
  66. m_RootBone = null;
  67. m_CurrSkinnedMeshRenderer = null;
  68. }
  69. void Start()
  70. {
  71. m_PartsLen = Parts.Length;
  72. m_BoneTransforms = m_RootBone.GetComponentsInChildren<Transform>(); //获取角色跟骨骼
  73. m_CurrSkinnedMeshRenderer.sharedMesh = new Mesh();
  74. LoadPart(new List<int> { 1, 2 });
  75. }
  76. /// <summary>
  77. /// 加载部件
  78. /// </summary>
  79. /// <param name="parts"></param>
  80. public void LoadPart(List<int> parts)
  81. {
  82. m_CombineInstances.Clear();
  83. m_Materials.Clear();
  84. m_Bones.Clear();
  85. m_CurrPartList.Clear();
  86. int len = parts.Count;
  87. for (int i = 0; i < len; i++)
  88. {
  89. SkinnedMeshRenderer skinnedMeshRenderer = GetPartByNo(parts[i]);
  90. if (skinnedMeshRenderer != null)
  91. {
  92. m_CurrPartList.Add(skinnedMeshRenderer);
  93. }
  94. }
  95. for (int i = 0; i < m_CurrPartList.Count; i++)
  96. {
  97. SkinnedMeshRenderer skinnedMeshRenderer = m_CurrPartList[i];
  98. m_Materials.AddRange(skinnedMeshRenderer.materials);
  99. //添加合并网格
  100. for (int sub = 0; sub < skinnedMeshRenderer.sharedMesh.subMeshCount; sub++)
  101. {
  102. CombineInstance ci = new CombineInstance();
  103. ci.mesh = skinnedMeshRenderer.sharedMesh;
  104. ci.subMeshIndex = sub;
  105. m_CombineInstances.Add(ci);
  106. }
  107. //======================此处是加载SkinnedMeshRenderer对应的骨骼 也就是bones的数量实际上会大于玩家身上的骨骼数量============================
  108. for (int sub = 0; sub < skinnedMeshRenderer.bones.Length; sub++)
  109. {
  110. int lenBoneTrans = m_BoneTransforms.Length;
  111. for (int m = 0; m < lenBoneTrans; m++)
  112. {
  113. Transform transform = m_BoneTransforms[m];
  114. if (transform.name != skinnedMeshRenderer.bones[sub].name) continue;
  115. m_Bones.Add(transform);
  116. break;
  117. }
  118. }
  119. }
  120. m_CurrSkinnedMeshRenderer.sharedMesh.CombineMeshes(m_CombineInstances.ToArray(), false, false); //合并模型
  121. m_CurrSkinnedMeshRenderer.bones = m_Bones.ToArray(); //赋予骨骼
  122. m_CurrSkinnedMeshRenderer.materials = m_Materials.ToArray(); //赋予材质
  123. }
  124. #region GetPartByNo 根据编号获取部件
  125. /// <summary>
  126. /// 根据编号获取部件
  127. /// </summary>
  128. /// <param name="no">编号</param>
  129. /// <returns></returns>
  130. private SkinnedMeshRenderer GetPartByNo(int no)
  131. {
  132. for (int i = 0; i < m_PartsLen; i++)
  133. {
  134. SkinnedMeshRendererPart skinnedMeshRendererPart = Parts[i];
  135. if (skinnedMeshRendererPart.No == no)
  136. {
  137. return skinnedMeshRendererPart.Part;
  138. }
  139. }
  140. return null;
  141. }
  142. #endregion
  143. [Serializable]
  144. /// <summary>
  145. /// 皮肤配置
  146. /// </summary>
  147. public class SkinnedMeshRendererPart
  148. {
  149. /// <summary>
  150. /// 编号
  151. /// </summary>
  152. public int No;
  153. /// <summary>
  154. /// 皮肤部件
  155. /// </summary>
  156. public SkinnedMeshRenderer Part;
  157. }
  158. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/223516
推荐阅读
相关标签
  

闽ICP备14008679号