110 lines
2.8 KiB
C#
110 lines
2.8 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
public class RainExposure : MonoBehaviour
|
|
{
|
|
[Serializable]
|
|
public class Settings
|
|
{
|
|
public float RipplesSpeed = 2f;
|
|
public float WetSpeed = .5f;
|
|
public float RaycastDistance = 50f;
|
|
}
|
|
|
|
[Serializable]
|
|
public class References
|
|
{
|
|
public Shader Shader;
|
|
public Renderer[] Renderers;
|
|
}
|
|
|
|
[Serializable]
|
|
public class State
|
|
{
|
|
[Range(0f, 1f)] public float Ripples;
|
|
[Range(0f, 1f)] public float Wet;
|
|
}
|
|
|
|
[SerializeField] private Settings _settings;
|
|
[SerializeField] private References _references;
|
|
[SerializeField] private State _state;
|
|
|
|
private bool covered;
|
|
private float coverDistance;
|
|
|
|
private static readonly int RipplesId = Shader.PropertyToID("_Ripples");
|
|
private static readonly int WetId = Shader.PropertyToID("_Wet");
|
|
|
|
private readonly RaycastHit[] _hits = new RaycastHit[32];
|
|
|
|
void OnDrawGizmosSelected()
|
|
{
|
|
Color col = Color.white;
|
|
if (Application.isPlaying)
|
|
col = covered ? Color.green : Color.red;
|
|
|
|
Gizmos.color = col;
|
|
Gizmos.DrawLine(transform.position, transform.position + Vector3.up * (covered ? coverDistance : _settings.RaycastDistance));
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
float t = Time.deltaTime;
|
|
|
|
covered = IsCovered();
|
|
float target = covered ? 0f : 1f;
|
|
|
|
_state.Ripples = Mathf.MoveTowards(_state.Ripples, target, _settings.RipplesSpeed * t);
|
|
_state.Wet = Mathf.MoveTowards(_state.Wet, target, _settings.WetSpeed * t);
|
|
|
|
SetMaterials();
|
|
}
|
|
|
|
private bool IsCovered()
|
|
{
|
|
int hitCount = Physics.RaycastNonAlloc(transform.position, Vector3.up, _hits, _settings.RaycastDistance);
|
|
|
|
for (int i = 0; i < hitCount; i++)
|
|
{
|
|
Collider col = _hits[i].collider;
|
|
|
|
if (!col)
|
|
continue;
|
|
|
|
if (col.transform == transform || col.transform.IsChildOf(transform))
|
|
continue;
|
|
|
|
coverDistance = _hits[i].distance;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void SetMaterials()
|
|
{
|
|
if (!_references.Shader || _references.Renderers == null)
|
|
return;
|
|
|
|
for (int i = 0; i < _references.Renderers.Length; i++)
|
|
{
|
|
Renderer rend = _references.Renderers[i];
|
|
|
|
if (rend == null)
|
|
continue;
|
|
|
|
Material[] mats = rend.materials;
|
|
|
|
for (int j = 0; j < mats.Length; j++)
|
|
{
|
|
Material mat = mats[j];
|
|
|
|
if (mat == null || mat.shader != _references.Shader)
|
|
continue;
|
|
|
|
mat.SetFloat(RipplesId, _state.Ripples);
|
|
mat.SetFloat(WetId, _state.Wet);
|
|
}
|
|
}
|
|
}
|
|
} |