133 lines
3.7 KiB
C#
133 lines
3.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
|
|
namespace TrueClouds
|
|
{
|
|
[ExecuteInEditMode]
|
|
class CloudPointLight : MonoBehaviour
|
|
{
|
|
public float Start = 0;
|
|
public float Range = 10;
|
|
public Color Color = Color.white;
|
|
public float ShadowIntensity = 0.2f;
|
|
|
|
private static Shader SHADER = null;
|
|
|
|
private static int START_ID = -1;
|
|
private static int RANGE_ID = -1;
|
|
private static int COLOR_ID = -1;
|
|
private static int SHADOW_INTENSITY_ID = -1;
|
|
|
|
private Material _material;
|
|
private Transform _transform;
|
|
private GameObject _light;
|
|
private Transform _lightTransform;
|
|
|
|
private void OnValidate()
|
|
{
|
|
ValidateHasGoodLayer();
|
|
ValidateDistances();
|
|
}
|
|
|
|
private void ValidateHasGoodLayer()
|
|
{
|
|
CloudCamera[] cameras = GetComponents<CloudCamera>();
|
|
if (cameras.Length == 0)
|
|
{
|
|
return;
|
|
}
|
|
if (cameras.All(camera => (camera.LightMask & gameObject.layer) == 0))
|
|
{
|
|
Debug.LogWarning("This light has a layer that is not rendered by any of the Cloud Cameras", gameObject);
|
|
}
|
|
}
|
|
|
|
private void ValidateDistances()
|
|
{
|
|
Start = Mathf.Max(0, Start);
|
|
Range = Mathf.Max(Range, Start);
|
|
}
|
|
|
|
private void Awake()
|
|
{
|
|
if (SHADER == null)
|
|
{
|
|
InitShaderAndIDs();
|
|
}
|
|
|
|
_transform = transform;
|
|
|
|
_light = GameObject.CreatePrimitive(PrimitiveType.Sphere);
|
|
_light.layer = gameObject.layer;
|
|
_light.hideFlags = HideFlags.HideAndDontSave;
|
|
_material = new Material(SHADER);
|
|
_light.GetComponent<Renderer>().sharedMaterial = _material;
|
|
_lightTransform = _light.transform;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
_light.SetActive(false);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
_light.SetActive(true);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (Application.isEditor && !Application.isPlaying)
|
|
{
|
|
DestroyImmediate(_light);
|
|
}
|
|
else
|
|
{
|
|
Destroy(_light);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (SHADER == null)
|
|
{
|
|
InitShaderAndIDs();
|
|
}
|
|
|
|
_material.SetFloat(START_ID, Start);
|
|
_material.SetFloat(RANGE_ID, Range);
|
|
_material.SetColor(COLOR_ID, Color);
|
|
_material.SetFloat(SHADOW_INTENSITY_ID, ShadowIntensity);
|
|
|
|
float scale = Range * 2 * 1.1f; // scale up a bit to account for the fact that we don't have a perfect sphere
|
|
_lightTransform.localScale = new Vector3(scale, scale, scale);
|
|
_lightTransform.position = _transform.position;
|
|
}
|
|
|
|
private void InitShaderAndIDs()
|
|
{
|
|
SHADER = Shader.Find("Hidden/Clouds/PointLight");
|
|
|
|
START_ID = Shader.PropertyToID("_Start");
|
|
RANGE_ID = Shader.PropertyToID("_MaxDistance");
|
|
COLOR_ID = Shader.PropertyToID("_TintColor");
|
|
SHADOW_INTENSITY_ID = Shader.PropertyToID("_ShadowIntensity");
|
|
}
|
|
|
|
private void OnDrawGizmosSelected()
|
|
{
|
|
Color gizmo = Color.yellow;
|
|
gizmo.a = 0.7f;
|
|
Gizmos.color = gizmo;
|
|
Gizmos.DrawSphere(transform.position, Start);
|
|
|
|
gizmo.a = 0.3f;
|
|
Gizmos.color = gizmo;
|
|
Gizmos.DrawSphere(transform.position, Range);
|
|
}
|
|
}
|
|
}
|