diff options
author | chai <chaifix@163.com> | 2022-04-28 13:58:20 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2022-04-28 13:58:20 +0800 |
commit | 88a6b32e792910e11451da18eb5fb8c103235842 (patch) | |
tree | e64c5feaf46b7d06ae096e3719515c0cafc74dc5 /SurvivalTest/Assets/ACS-17/LightCone - Volumetric Spotlight/LightCone.cs | |
parent | 072f02678d2c5d0d79f49e923b111c4a28da3f69 (diff) |
+misc
Diffstat (limited to 'SurvivalTest/Assets/ACS-17/LightCone - Volumetric Spotlight/LightCone.cs')
-rw-r--r-- | SurvivalTest/Assets/ACS-17/LightCone - Volumetric Spotlight/LightCone.cs | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/SurvivalTest/Assets/ACS-17/LightCone - Volumetric Spotlight/LightCone.cs b/SurvivalTest/Assets/ACS-17/LightCone - Volumetric Spotlight/LightCone.cs new file mode 100644 index 0000000..edfc47d --- /dev/null +++ b/SurvivalTest/Assets/ACS-17/LightCone - Volumetric Spotlight/LightCone.cs @@ -0,0 +1,215 @@ +#define LightCone_OnDrawGizmos_Collide + +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +[RequireComponent( typeof(Light) )] +public class LightCone : MonoBehaviour { + public int wedges = 36; + public float dist = 20; + public float width = 2; + public float height = 2; + [SerializeField] + private Color _color = new Color(1, 1, 1, 0.25f); + public LayerMask collidesWith; + public int gizmoWedges = 4; + + [Header("Spotlight Settings")] + public bool spotlightEnabled = true; + public float spotAnglePercent = 100; + public float rangePercent = 100; + + + + MeshFilter mF; + Mesh m; + Vector3[] verts; + int[] tris; + Material mat; + RaycastHit[] hits; + + private Light lt; + private float dist0, width0, sAP0, rP0; + + public Color color + { + get + { + return _color; + } + + set + { + _color = value; + UpdateLight(); + } + } + + // Use this for initialization + void Start () { + mF = GetComponent<MeshFilter>(); + m = mF.mesh; + + m.Clear(); + + MakeVerts(); + + tris = new int[wedges*3]; + + int triN=0; + int vertN=1; + for (int i=0; i<wedges; i++) { + tris[triN] = 0; + triN++; + if (vertN < verts.Length-1) { + tris[triN] = vertN+1; + } else { + tris[triN] = 1; + } + triN++; + tris[triN] = vertN; + vertN++; + triN++; + } + m.triangles = tris; + + mat = GetComponent<Renderer>().material; + + UpdateLight(); + } + + void MakeVerts() { + verts = new Vector3[wedges+1]; + verts[0] = Vector3.zero; + + Vector3 v, r; + hits = new RaycastHit[wedges]; + for (int i=0; i<wedges; i++) { + v = Vector3.zero; + v.z = dist; + v.x = Mathf.Cos(i * Mathf.PI * 2 / wedges) * width; + v.y = Mathf.Sin(i * Mathf.PI * 2 / wedges) * height; + r = transform.rotation * v.normalized; + if ( Physics.Raycast(transform.position, r, out hits[i], v.magnitude, collidesWith) ) { + v = v.normalized * hits[i].distance; + } + verts[i+1] = v; + } + m.vertices = verts; + } + + // Update is called once per frame + void Update () { + MakeVerts(); + if (color != mat.color) { + mat.color = color; + } + } + + // This draws the outline when not playing (and Selected) + void OnDrawGizmosSelected() { + if (Application.isPlaying) return; + Vector3[] pts = new Vector3[gizmoWedges]; + Vector3 v, vDir; + + Color litColor = color; + litColor.a = 1; +#if LightCone_OnDrawGizmos_Collide + Color grayColor = Color.Lerp(Color.clear, color, 0.5f); + grayColor.a = 0.5f; +#else + Gizmos.color = litColor; +#endif + + for (int i=0; i<gizmoWedges; i++) { + v = Vector3.zero; + v.z = dist; + v.x = Mathf.Cos(i * Mathf.PI * 2 / gizmoWedges) * width; + v.y = Mathf.Sin(i * Mathf.PI * 2 / gizmoWedges) * height; + vDir = transform.rotation * v; + pts[i] = vDir; + pts[i] += transform.position; + +#if LightCone_OnDrawGizmos_Collide +#else + Gizmos.DrawLine(transform.position, pts[i]); + if (i>0) { + Gizmos.DrawLine(pts[i-1], pts[i]); + if (i == gizmoWedges-1) { + Gizmos.DrawLine(pts[i], pts[0]); + } + } +#endif + } + +#if LightCone_OnDrawGizmos_Collide + Vector3[] ptsColl = new Vector3[gizmoWedges]; + RaycastHit hitInfo; + for (int i = 0; i < pts.Length; i++) { + ptsColl[i] = pts[i]; + vDir = ptsColl[i] - transform.position; + if (Physics.Raycast(transform.position, vDir, out hitInfo, vDir.magnitude, collidesWith)) + { + // The line collided with something, so make it shorter + ptsColl[i] = hitInfo.point; + } + + // Draw the area past the collision + Gizmos.color = grayColor; + Gizmos.DrawLine(ptsColl[i], pts[i]); + if (i > 0) + { + Gizmos.DrawLine(pts[i - 1], pts[i]); + if (i == gizmoWedges - 1) + { + Gizmos.DrawLine(pts[i], pts[0]); + } + } + // Draw the collision + Gizmos.color = litColor; + Gizmos.DrawLine(transform.position, ptsColl[i]); + if (i > 0) + { + Gizmos.DrawLine(ptsColl[i - 1], ptsColl[i]); + if (i == gizmoWedges - 1) + { + Gizmos.DrawLine(ptsColl[i], ptsColl[0]); + } + } + } +#endif + + } + + private void OnDrawGizmos() + { + if (Application.isPlaying) return; + UpdateLight(); + } + + void UpdateLight() { + if (lt == null) { + lt = GetComponent<Light>(); + lt.type = LightType.Spot; + } + + if (dist0 != dist || width0 != width || sAP0 != spotAnglePercent || rangePercent != rP0) { + lt.spotAngle = Mathf.Atan2(width, dist)*360/Mathf.PI * (spotAnglePercent / 100f); + lt.range = dist * rangePercent / 100f; + dist0 = dist; + width0 = width; + sAP0 = spotAnglePercent; + rP0 = rangePercent; + } + + lt.color = color; + + lt.enabled = spotlightEnabled; + } + + + public RaycastHit[] GetRaycastHits() { + return hits; + } +} |