Unity 框架

Outline.cs 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. using System;
  2. using System.Linq;
  3. using UnityEngine;
  4. namespace TFramework
  5. {
  6. [DisallowMultipleComponent]
  7. public class Outline : MonoBehaviour
  8. {
  9. public enum Mode
  10. {
  11. /// <summary>
  12. /// 描边所有轮廓
  13. /// </summary>
  14. OutlineAll,
  15. /// <summary>
  16. /// 仅描边可见部分
  17. /// </summary>
  18. OutlineVisible,
  19. /// <summary>
  20. /// 仅描边隐藏部分
  21. /// </summary>
  22. OutlineHidden,
  23. /// <summary>
  24. /// 描边且剪影
  25. /// </summary>
  26. OutlineAndSilhouette,
  27. /// <summary>
  28. /// 仅描边
  29. /// </summary>
  30. SilhouetteOnly
  31. }
  32. /// <summary>
  33. /// 描边模式
  34. /// </summary>
  35. public Mode OutlineMode
  36. {
  37. get { return outlineMode; }
  38. set
  39. {
  40. outlineMode = value;
  41. _isChange = true;
  42. }
  43. }
  44. /// <summary>
  45. /// 描边颜色
  46. /// </summary>
  47. public Color OutlineColor
  48. {
  49. get { return outlineColor; }
  50. set
  51. {
  52. outlineColor = value;
  53. _isChange = true;
  54. }
  55. }
  56. /// <summary>
  57. /// 描边宽度
  58. /// </summary>
  59. public float OutlineWidth
  60. {
  61. get { return outlineWidth; }
  62. set
  63. {
  64. outlineWidth = value;
  65. _isChange = true;
  66. }
  67. }
  68. [SerializeField]
  69. private Mode outlineMode;
  70. [SerializeField]
  71. private Color outlineColor;
  72. [SerializeField, Range(0f, 10f)]
  73. private float outlineWidth = 2f;
  74. private Renderer[] renderers;
  75. private Material outlineMaskMaterial;
  76. private Material outlineFillMaterial;
  77. private bool _isChange=false;
  78. void Awake()
  79. {
  80. renderers = GetComponentsInChildren<Renderer>();
  81. // Instantiate outline materials
  82. outlineMaskMaterial = Instantiate(Main.GetMagr<EffectManager>().m_outlineMaskMaterial);
  83. outlineFillMaterial = Instantiate(Main.GetMagr<EffectManager>().m_outlineFillMaterial);
  84. outlineMaskMaterial.name = "OutlineMask (Instance)";
  85. outlineFillMaterial.name = "OutlineFill (Instance)";
  86. }
  87. void OnEnable()
  88. {
  89. foreach (var renderer in renderers)
  90. {
  91. var materials = renderer.sharedMaterials.ToList();
  92. materials.Add(outlineMaskMaterial);
  93. materials.Add(outlineFillMaterial);
  94. renderer.materials = materials.ToArray();
  95. }
  96. _isChange = true;
  97. }
  98. private void Update()
  99. {
  100. if(_isChange)
  101. {
  102. _isChange = false;
  103. UpdateMaterialProperties();
  104. }
  105. }
  106. void OnDisable()
  107. {
  108. foreach (var renderer in renderers)
  109. {
  110. // Remove outline shaders
  111. var materials = renderer.sharedMaterials.ToList();
  112. materials.Remove(outlineMaskMaterial);
  113. materials.Remove(outlineFillMaterial);
  114. renderer.materials = materials.ToArray();
  115. }
  116. }
  117. void OnDestroy()
  118. {
  119. Destroy(outlineMaskMaterial);
  120. Destroy(outlineFillMaterial);
  121. }
  122. void UpdateMaterialProperties()
  123. {
  124. // Apply properties according to mode
  125. outlineFillMaterial.SetColor("_OutlineColor", outlineColor);
  126. switch (outlineMode)
  127. {
  128. case Mode.OutlineAll:
  129. outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
  130. outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
  131. outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
  132. break;
  133. case Mode.OutlineVisible:
  134. outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
  135. outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
  136. outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
  137. break;
  138. case Mode.OutlineHidden:
  139. outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
  140. outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Greater);
  141. outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
  142. break;
  143. case Mode.OutlineAndSilhouette:
  144. outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
  145. outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Always);
  146. outlineFillMaterial.SetFloat("_OutlineWidth", outlineWidth);
  147. break;
  148. case Mode.SilhouetteOnly:
  149. outlineMaskMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
  150. outlineFillMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.Greater);
  151. outlineFillMaterial.SetFloat("_OutlineWidth", 0f);
  152. break;
  153. }
  154. }
  155. }
  156. }