using UnityEngine; /// /// 材质渲染模式助手类 /// 用于设置材质的正确渲染模式以支持透明度 /// public static class MaterialRenderModeHelper { public enum BlendMode { Opaque, Cutout, Fade, // Traditional transparency (ZWrite OFF) Transparent, // Physically based transparency (ZWrite OFF) AlphaBlendWithDepth // Alpha blend with depth write (ZWrite ON) - 解决Body显示问题 } /// /// 设置材质的渲染模式 /// /// 要设置的材质 /// 渲染模式 public static void SetMaterialRenderMode(Material material, BlendMode blendMode) { switch (blendMode) { case BlendMode.Opaque: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = -1; break; case BlendMode.Cutout: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt("_ZWrite", 1); material.EnableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest; break; case BlendMode.Fade: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.SetInt("_ZWrite", 0); material.DisableKeyword("_ALPHATEST_ON"); material.EnableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; break; case BlendMode.Transparent: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.SetInt("_ZWrite", 0); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; break; case BlendMode.AlphaBlendWithDepth: // 关键修复:保持深度写入的透明混合模式 material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.SetInt("_ZWrite", 1); // 保持深度写入,这样Body即使单独存在也能正确显示 material.DisableKeyword("_ALPHATEST_ON"); material.EnableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); // 使用较早的渲染队列,确保在其他透明物体之前渲染 material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry + 450; break; } } /// /// 自动检测并设置合适的渲染模式 /// /// 材质 /// 透明度值 public static void AutoSetRenderMode(Material material, float alpha) { if (alpha >= 1.0f) { SetMaterialRenderMode(material, BlendMode.Opaque); } else { SetMaterialRenderMode(material, BlendMode.AlphaBlendWithDepth); } } /// /// 专门为Body设置渲染模式 /// 确保Body在单独显示时也能正确显示 /// /// Body材质 /// 透明度值 public static void SetBodyRenderMode(Material material, float alpha) { if (alpha >= 1.0f) { SetMaterialRenderMode(material, BlendMode.Opaque); } else { // 对于Body,始终使用保持深度写入的透明模式 SetMaterialRenderMode(material, BlendMode.AlphaBlendWithDepth); } } }