123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- using UnityEngine;
- namespace VolumetricLines
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- [RequireComponent(typeof(MeshFilter))]
- [RequireComponent(typeof(MeshRenderer))]
- [ExecuteInEditMode]
- public class VolumetricLineBehavior : MonoBehaviour
- {
-
- static readonly Vector3 Average = new Vector3(1f/3f, 1f/3f, 1f/3f);
- #region private variables
-
-
-
- [SerializeField]
- public Material m_templateMaterial;
-
-
-
-
- [SerializeField]
- private bool m_doNotOverwriteTemplateMaterialProperties;
-
-
-
- [SerializeField]
- private Vector3 m_startPos;
-
-
-
-
- [SerializeField]
- private Vector3 m_endPos = new Vector3(0f, 0f, 100f);
-
-
-
- [SerializeField]
- private Color m_lineColor;
-
-
-
- [SerializeField]
- private float m_lineWidth;
-
-
-
- [SerializeField]
- [Range(0.0f, 1.0f)]
- private float m_lightSaberFactor;
-
-
-
- private Material m_material;
-
-
-
-
- private MeshFilter m_meshFilter;
- #endregion
- #region properties
-
-
-
-
-
- public Material TemplateMaterial
- {
- get { return m_templateMaterial; }
- set { m_templateMaterial = value; }
- }
-
-
-
-
-
-
-
- public bool DoNotOverwriteTemplateMaterialProperties
- {
- get { return m_doNotOverwriteTemplateMaterialProperties; }
- set { m_doNotOverwriteTemplateMaterialProperties = value; }
- }
-
-
-
-
- public Color LineColor
- {
- get { return m_lineColor; }
- set
- {
- CreateMaterial();
- if (null != m_material)
- {
- m_lineColor = value;
- m_material.color = m_lineColor;
- }
- }
- }
-
-
-
- public float LineWidth
- {
- get { return m_lineWidth; }
- set
- {
- CreateMaterial();
- if (null != m_material)
- {
- m_lineWidth = value;
- m_material.SetFloat("_LineWidth", m_lineWidth);
- }
- UpdateBounds();
- }
- }
-
-
-
- public float LightSaberFactor
- {
- get { return m_lightSaberFactor; }
- set
- {
- CreateMaterial();
- if (null != m_material)
- {
- m_lightSaberFactor = value;
- m_material.SetFloat("_LightSaberFactor", m_lightSaberFactor);
- }
- }
- }
-
-
-
- public Vector3 StartPos
- {
- get { return m_startPos; }
- set
- {
- m_startPos = value;
- SetStartAndEndPoints(m_startPos, m_endPos);
- }
- }
-
-
-
- public Vector3 EndPos
- {
- get { return m_endPos; }
- set
- {
- m_endPos = value;
- SetStartAndEndPoints(m_startPos, m_endPos);
- }
- }
- #endregion
-
- #region methods
-
-
-
- private void CreateMaterial()
- {
- if (null == m_material || null == GetComponent<MeshRenderer>().sharedMaterial)
- {
- if (null != m_templateMaterial)
- {
- m_material = Material.Instantiate(m_templateMaterial);
- GetComponent<MeshRenderer>().sharedMaterial = m_material;
- SetAllMaterialProperties();
- }
- else
- {
- m_material = GetComponent<MeshRenderer>().sharedMaterial;
- }
- }
- }
-
-
-
- private void DestroyMaterial()
- {
- if (null != m_material)
- {
- DestroyImmediate(m_material);
- m_material = null;
- }
- }
-
-
-
- private float CalculateLineScale()
- {
- return Vector3.Dot(transform.lossyScale, Average);
- }
-
-
-
- public void UpdateLineScale()
- {
- if (null != m_material)
- {
- m_material.SetFloat("_LineScale", CalculateLineScale());
- }
- }
-
-
-
- private void SetAllMaterialProperties()
- {
- SetStartAndEndPoints(m_startPos, m_endPos);
- if (null != m_material)
- {
- if (!m_doNotOverwriteTemplateMaterialProperties)
- {
- m_material.color = m_lineColor;
- m_material.SetFloat("_LineWidth", m_lineWidth);
- m_material.SetFloat("_LightSaberFactor", m_lightSaberFactor);
- }
- UpdateLineScale();
- }
- }
-
-
-
-
- private Bounds CalculateBounds()
- {
- var maxWidth = Mathf.Max(transform.lossyScale.x, transform.lossyScale.y, transform.lossyScale.z);
- var scaledLineWidth = maxWidth * LineWidth * 0.5f;
- var min = new Vector3(
- Mathf.Min(m_startPos.x, m_endPos.x) - scaledLineWidth,
- Mathf.Min(m_startPos.y, m_endPos.y) - scaledLineWidth,
- Mathf.Min(m_startPos.z, m_endPos.z) - scaledLineWidth
- );
- var max = new Vector3(
- Mathf.Max(m_startPos.x, m_endPos.x) + scaledLineWidth,
- Mathf.Max(m_startPos.y, m_endPos.y) + scaledLineWidth,
- Mathf.Max(m_startPos.z, m_endPos.z) + scaledLineWidth
- );
-
- return new Bounds
- {
- min = min,
- max = max
- };
- }
-
-
-
-
- public void UpdateBounds()
- {
- if (null != m_meshFilter)
- {
- var mesh = m_meshFilter.sharedMesh;
- Debug.Assert(null != mesh);
- if (null != mesh)
- {
- mesh.bounds = CalculateBounds();
- }
- }
- }
-
-
-
- public void SetStartAndEndPoints(Vector3 startPoint, Vector3 endPoint)
- {
- m_startPos = startPoint;
- m_endPos = endPoint;
- Vector3[] vertexPositions = {
- m_startPos,
- m_startPos,
- m_startPos,
- m_startPos,
- m_endPos,
- m_endPos,
- m_endPos,
- m_endPos,
- };
-
- Vector3[] other = {
- m_endPos,
- m_endPos,
- m_endPos,
- m_endPos,
- m_startPos,
- m_startPos,
- m_startPos,
- m_startPos,
- };
- if (null != m_meshFilter)
- {
- var mesh = m_meshFilter.sharedMesh;
- Debug.Assert(null != mesh);
- if (null != mesh)
- {
- mesh.vertices = vertexPositions;
- mesh.normals = other;
- UpdateBounds();
- }
- }
- }
- #endregion
- #region event functions
- void Start ()
- {
- Mesh mesh = new Mesh();
- m_meshFilter = GetComponent<MeshFilter>();
- m_meshFilter.mesh = mesh;
- SetStartAndEndPoints(m_startPos, m_endPos);
- mesh.uv = VolumetricLineVertexData.TexCoords;
- mesh.uv2 = VolumetricLineVertexData.VertexOffsets;
- mesh.SetIndices(VolumetricLineVertexData.Indices, MeshTopology.Triangles, 0);
- CreateMaterial();
-
- }
- void OnDestroy()
- {
- if (null != m_meshFilter)
- {
- if (Application.isPlaying)
- {
- Mesh.Destroy(m_meshFilter.sharedMesh);
- }
- else
- {
- Mesh.DestroyImmediate(m_meshFilter.sharedMesh);
- }
- m_meshFilter.sharedMesh = null;
- }
- DestroyMaterial();
- }
-
- void Update()
- {
- if (transform.hasChanged)
- {
- UpdateLineScale();
- UpdateBounds();
- }
- }
- void OnValidate()
- {
-
-
- if(string.IsNullOrEmpty(gameObject.scene.name) || string.IsNullOrEmpty(gameObject.scene.path)) {
- return;
- }
- CreateMaterial();
- SetAllMaterialProperties();
- UpdateBounds();
- }
-
- void OnDrawGizmos()
- {
- Gizmos.color = Color.green;
- Gizmos.DrawLine(gameObject.transform.TransformPoint(m_startPos), gameObject.transform.TransformPoint(m_endPos));
- }
- #endregion
- }
- }
|