VolumetricMultiLineBehavior.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. using UnityEngine;
  2. using System.Collections;
  3. namespace VolumetricLines
  4. {
  5. /// <summary>
  6. /// Render a line strip consisting of multiple VolumetricLineBehavior pieces stitched together
  7. ///
  8. /// Based on the Volumetric lines algorithm by Sebastien Hillaire
  9. /// http://sebastien.hillaire.free.fr/index.php?option=com_content&view=article&id=57&Itemid=74
  10. ///
  11. /// Thread in the Unity3D Forum:
  12. /// http://forum.unity3d.com/threads/181618-Volumetric-lines
  13. ///
  14. /// Unity3D port by Johannes Unterguggenberger
  15. /// johannes.unterguggenberger@gmail.com
  16. ///
  17. /// Thanks to Michael Probst for support during development.
  18. ///
  19. /// Thanks for bugfixes and improvements to Unity Forum User "Mistale"
  20. /// http://forum.unity3d.com/members/102350-Mistale
  21. ///
  22. /// /// Shader code optimization and cleanup by Lex Darlog (aka DRL)
  23. /// http://forum.unity3d.com/members/lex-drl.67487/
  24. ///
  25. /// </summary>
  26. public class VolumetricMultiLineBehavior : MonoBehaviour
  27. {
  28. #region private variables
  29. /// <summary>
  30. /// Template material to be used for all line parts of this multiline
  31. /// </summary>
  32. [SerializeField]
  33. public Material m_templateMaterial;
  34. /// <summary>
  35. /// Set to false in order to change the material's properties as specified in this script.
  36. /// Set to true in order to *initially* leave the material's properties as they are in the template material.
  37. /// </summary>
  38. [SerializeField]
  39. private bool m_doNotOverwriteTemplateMaterialProperties;
  40. /// <summary>
  41. /// Line Color for all line parts of this multiline
  42. /// </summary>
  43. [SerializeField]
  44. private Color m_lineColor;
  45. /// <summary>
  46. /// The width of all line parts of this multiline
  47. /// </summary>
  48. [SerializeField]
  49. private float m_lineWidth;
  50. /// <summary>
  51. /// Light saber factor for all line parts of this multiline
  52. /// </summary>
  53. [SerializeField]
  54. [Range(0.0f, 1.0f)]
  55. private float m_lightSaberFactor;
  56. /// <summary>
  57. /// The vertices where 2 adjacent multi lines touch each other.
  58. /// The end of line 1 is the start of line 2, etc.
  59. /// </summary>
  60. [SerializeField]
  61. private Vector3[] m_lineVertices;
  62. /// <summary>
  63. /// Contains all volumetric lines
  64. /// </summary>
  65. private VolumetricLineBehavior[] m_volumetricLines;
  66. #endregion
  67. #region properties
  68. /// <summary>
  69. /// Gets or sets the tmplate material.
  70. /// Setting this will only have an impact once.
  71. /// Subsequent changes will be ignored.
  72. /// </summary>
  73. public Material TemplateMaterial
  74. {
  75. get { return m_templateMaterial; }
  76. set { m_templateMaterial = value; }
  77. }
  78. /// <summary>
  79. /// Gets or sets whether or not the template material properties
  80. /// should be used (false) or if the properties of this MonoBehavior
  81. /// instance should be used (true, default).
  82. /// Setting this will only have an impact once, and then only if it
  83. /// is set before TemplateMaterial has been assigned.
  84. /// </summary>
  85. public bool DoNotOverwriteTemplateMaterialProperties
  86. {
  87. get { return m_doNotOverwriteTemplateMaterialProperties; }
  88. set { m_doNotOverwriteTemplateMaterialProperties = value; }
  89. }
  90. /// <summary>
  91. /// Get or set the line color for each line part of this multiline
  92. /// </summary>
  93. public Color LineColor
  94. {
  95. get
  96. {
  97. return m_lineColor;
  98. }
  99. set
  100. {
  101. m_lineColor = value;
  102. if (null == m_volumetricLines)
  103. {
  104. return;
  105. }
  106. for (int i = 0; i < m_volumetricLines.Length; ++i)
  107. {
  108. if (null != m_volumetricLines[i] && m_volumetricLines[i])
  109. {
  110. m_volumetricLines[i].LineColor = value;
  111. }
  112. }
  113. }
  114. }
  115. /// <summary>
  116. /// Get or set the line width of this volumetric line's material
  117. /// </summary>
  118. public float LineWidth
  119. {
  120. get
  121. {
  122. return m_lineWidth;
  123. }
  124. set
  125. {
  126. m_lineWidth = value;
  127. if (null == m_volumetricLines)
  128. {
  129. return;
  130. }
  131. for (int i = 0; i < m_volumetricLines.Length; ++i)
  132. {
  133. if (null != m_volumetricLines[i] && m_volumetricLines[i])
  134. {
  135. m_volumetricLines[i].LineWidth = value;
  136. }
  137. }
  138. }
  139. }
  140. /// <summary>
  141. /// Get or set the light saber factor of this volumetric line's material
  142. /// </summary>
  143. public float LightSaberFactor
  144. {
  145. get
  146. {
  147. return m_lightSaberFactor;
  148. }
  149. set
  150. {
  151. m_lightSaberFactor = value;
  152. if (null == m_volumetricLines)
  153. {
  154. return;
  155. }
  156. for (int i = 0; i < m_volumetricLines.Length; ++i)
  157. {
  158. if (null != m_volumetricLines[i] && m_volumetricLines[i])
  159. {
  160. m_volumetricLines[i].LightSaberFactor = value;
  161. }
  162. }
  163. }
  164. }
  165. #endregion
  166. #region methods
  167. /// <summary>
  168. /// Instantiate all line parts of this multiline and set their properties
  169. /// </summary>
  170. public void CreateAllVolumetricLines()
  171. {
  172. if (null != m_volumetricLines)
  173. {
  174. return;
  175. }
  176. m_volumetricLines = new VolumetricLineBehavior[m_lineVertices.Length - 1];
  177. for (int i = 0; i < m_lineVertices.Length - 1; ++i)
  178. {
  179. int n = i;
  180. var go = new GameObject("multiline" + n);
  181. go.transform.SetParent(gameObject.transform);
  182. go.transform.localPosition = Vector3.zero;
  183. go.transform.localRotation = Quaternion.identity;
  184. var volLine = go.AddComponent<VolumetricLineBehavior>();
  185. volLine.TemplateMaterial = TemplateMaterial;
  186. volLine.DoNotOverwriteTemplateMaterialProperties = DoNotOverwriteTemplateMaterialProperties;
  187. volLine.LineWidth = LineWidth;
  188. volLine.LineColor = LineColor;
  189. volLine.LightSaberFactor = LightSaberFactor;
  190. volLine.StartPos = m_lineVertices[i];
  191. volLine.EndPos = m_lineVertices[i + 1];
  192. m_volumetricLines[i] = volLine;
  193. }
  194. }
  195. /// <summary>
  196. /// Destroys all line parts of this multiline
  197. /// </summary>
  198. public void DestroyAllVolumetricLines()
  199. {
  200. if (null == m_volumetricLines)
  201. {
  202. return;
  203. }
  204. for (int i = 0; i < m_volumetricLines.Length; ++i)
  205. {
  206. if (null == m_volumetricLines[i] || !m_volumetricLines[i])
  207. {
  208. continue;
  209. }
  210. var o = m_volumetricLines[i].gameObject;
  211. if (o)
  212. {
  213. GameObject.Destroy(o);
  214. }
  215. }
  216. m_volumetricLines = null;
  217. }
  218. /// <summary>
  219. /// Update the vertices of this multi line.
  220. /// </summary>
  221. /// <param name="newSetOfVertices">New set of vertices.</param>
  222. public void UpdateLineVertices(Vector3[] newSetOfVertices)
  223. {
  224. DestroyAllVolumetricLines();
  225. m_lineVertices = newSetOfVertices;
  226. CreateAllVolumetricLines();
  227. }
  228. /// <summary>
  229. /// Sets all material properties (color, width, light saber factor)
  230. /// </summary>
  231. private void SetAllMaterialProperties()
  232. {
  233. LineColor = LineColor;
  234. LineWidth = LineWidth;
  235. LightSaberFactor = LightSaberFactor;
  236. }
  237. #endregion
  238. #region event functions
  239. void Start ()
  240. {
  241. CreateAllVolumetricLines();
  242. }
  243. void OnDestroy()
  244. {
  245. DestroyAllVolumetricLines();
  246. }
  247. void OnValidate()
  248. {
  249. SetAllMaterialProperties();
  250. }
  251. void OnDrawGizmos()
  252. {
  253. Gizmos.color = Color.green;
  254. if (null == m_lineVertices)
  255. {
  256. return;
  257. }
  258. for (int i=0; i < m_lineVertices.Length - 1; ++i)
  259. {
  260. Gizmos.DrawLine(gameObject.transform.TransformPoint(m_lineVertices[i]), gameObject.transform.TransformPoint(m_lineVertices[i+1]));
  261. }
  262. }
  263. #endregion
  264. }
  265. }