174 lines
5.5 KiB
C#
174 lines
5.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
[ExecuteInEditMode]
|
|
public class PrecipitationManager : MonoBehaviour
|
|
{
|
|
[Serializable]
|
|
public class EnvironmentParticlesSettings
|
|
{
|
|
[Range(0f, 1f)]
|
|
public float amount = 1f;
|
|
|
|
public Color color = Color.white;
|
|
|
|
[Tooltip("Alpha = variation amount")]
|
|
public Color colorVariation = Color.white;
|
|
|
|
public float fallSpeed;
|
|
|
|
public Vector2 cameraRange;
|
|
|
|
public Vector2 flutterFrequency;
|
|
|
|
public Vector2 flutterSpeed;
|
|
|
|
public Vector2 flutterMagnitude;
|
|
|
|
public Vector2 sizeRange;
|
|
|
|
public EnvironmentParticlesSettings(Color color, Color colorVariation, float fallSpeed, Vector2 cameraRange, Vector2 flutterFrequency, Vector2 flutterSpeed, Vector2 flutterMagnitude, Vector2 sizeRange)
|
|
{
|
|
this.color = color;
|
|
this.colorVariation = colorVariation;
|
|
this.fallSpeed = fallSpeed;
|
|
this.cameraRange = cameraRange;
|
|
this.flutterFrequency = flutterFrequency;
|
|
this.flutterSpeed = flutterSpeed;
|
|
this.flutterMagnitude = flutterMagnitude;
|
|
this.sizeRange = sizeRange;
|
|
}
|
|
}
|
|
|
|
public Texture2D mainTexture;
|
|
|
|
public Texture2D noiseTexture;
|
|
|
|
[Range(0f, 1f)]
|
|
public float windStrength;
|
|
|
|
[Range(-180f, 180f)]
|
|
public float windYRotation;
|
|
|
|
[Range(2f, 256f)]
|
|
public int meshSubdivisions = 200;
|
|
|
|
public EnvironmentParticlesSettings rain = new EnvironmentParticlesSettings(Color.white, Color.white, 3f, new Vector2(0f, 15f), new Vector2(0.988f, 1.234f), new Vector2(0.01f, 0.01f), new Vector2(0.35f, 0.25f), new Vector2(0.5f, 1f));
|
|
|
|
public EnvironmentParticlesSettings snow = new EnvironmentParticlesSettings(Color.white, Color.white, 0.25f, new Vector2(0f, 10f), new Vector2(0.988f, 1.234f), new Vector2(1f, 0.5f), new Vector2(0.35f, 0.25f), new Vector2(0.05f, 0.025f));
|
|
|
|
private GridHandler gridHandler;
|
|
|
|
private Matrix4x4[] renderMatrices = new Matrix4x4[27];
|
|
|
|
private Mesh meshToDraw;
|
|
|
|
private Material rainMaterial;
|
|
|
|
private Material snowMaterial;
|
|
|
|
private static Material CreateMaterialIfNull(string shaderName, ref Material reference)
|
|
{
|
|
if (reference == null)
|
|
{
|
|
reference = new Material(Shader.Find(shaderName));
|
|
reference.hideFlags = HideFlags.HideAndDontSave;
|
|
reference.renderQueue = 3000;
|
|
reference.enableInstancing = true;
|
|
}
|
|
return reference;
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
gridHandler = GetComponent<GridHandler>();
|
|
gridHandler.onPlayerGridChange += OnPlayerGridChange;
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
gridHandler.onPlayerGridChange -= OnPlayerGridChange;
|
|
}
|
|
|
|
private void OnPlayerGridChange(Vector3Int playerGrid)
|
|
{
|
|
int num = 0;
|
|
for (int i = -1; i <= 1; i++)
|
|
{
|
|
for (int j = -1; j <= 1; j++)
|
|
{
|
|
for (int k = -1; k <= 1; k++)
|
|
{
|
|
Vector3Int vector3Int = new Vector3Int(i, j, k);
|
|
renderMatrices[num++].SetTRS(gridHandler.GetGridCenter(playerGrid + vector3Int), Quaternion.identity, Vector3.one);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (meshToDraw == null)
|
|
{
|
|
RebuildPrecipitationMesh();
|
|
}
|
|
float num = Mathf.Lerp(0f, 45f, windStrength);
|
|
Matrix4x4 windRotationMatrix = Matrix4x4.TRS(q: Quaternion.Euler(new Vector3(0f - num, windYRotation, 0f)), pos: Vector3.zero, s: Vector3.one);
|
|
float maxTravelDistance = gridHandler.gridSize / Mathf.Cos(num * (MathF.PI / 180f));
|
|
RenderEnvironmentParticles(rain, CreateMaterialIfNull("Hidden/Environment/Rain", ref rainMaterial), maxTravelDistance, windRotationMatrix);
|
|
RenderEnvironmentParticles(snow, CreateMaterialIfNull("Hidden/Environment/Snow", ref snowMaterial), maxTravelDistance, windRotationMatrix);
|
|
}
|
|
|
|
private void RenderEnvironmentParticles(EnvironmentParticlesSettings settings, Material material, float maxTravelDistance, Matrix4x4 windRotationMatrix)
|
|
{
|
|
if (!(settings.amount <= 0f))
|
|
{
|
|
material.SetTexture("_MainTex", mainTexture);
|
|
material.SetTexture("_NoiseTex", noiseTexture);
|
|
material.SetFloat("_GridSize", gridHandler.gridSize);
|
|
material.SetFloat("_Amount", settings.amount);
|
|
material.SetColor("_Color", settings.color);
|
|
material.SetColor("_ColorVariation", settings.colorVariation);
|
|
material.SetFloat("_FallSpeed", settings.fallSpeed);
|
|
material.SetVector("_FlutterFrequency", settings.flutterFrequency);
|
|
material.SetVector("_FlutterSpeed", settings.flutterSpeed);
|
|
material.SetVector("_FlutterMagnitude", settings.flutterMagnitude);
|
|
material.SetVector("_CameraRange", settings.cameraRange);
|
|
material.SetVector("_SizeRange", settings.sizeRange);
|
|
material.SetFloat("_MaxTravelDistance", maxTravelDistance);
|
|
material.SetMatrix("_WindRotationMatrix", windRotationMatrix);
|
|
Graphics.DrawMeshInstanced(meshToDraw, 0, material, renderMatrices, renderMatrices.Length, null, ShadowCastingMode.Off, receiveShadows: true, 0, null, LightProbeUsage.Off);
|
|
}
|
|
}
|
|
|
|
public void RebuildPrecipitationMesh()
|
|
{
|
|
Mesh mesh = new Mesh();
|
|
List<int> list = new List<int>();
|
|
List<Vector3> list2 = new List<Vector3>();
|
|
List<Vector3> list3 = new List<Vector3>();
|
|
float num = 100f / (float)meshSubdivisions;
|
|
int num2 = 0;
|
|
for (float num3 = 0f; num3 <= 100f; num3 += num)
|
|
{
|
|
for (float num4 = 0f; num4 <= 100f; num4 += num)
|
|
{
|
|
float num5 = num3 / 100f;
|
|
float num6 = num4 / 100f;
|
|
list2.Add(new Vector3(num5 - 0.5f, 0f, num6 - 0.5f));
|
|
float z = Mathf.Max(num3 / num % 4f / 4f, num4 / num % 4f / 4f);
|
|
list3.Add(new Vector3(num5, num6, z));
|
|
list.Add(num2++);
|
|
}
|
|
}
|
|
mesh.SetVertices(list2);
|
|
mesh.SetUVs(0, list3);
|
|
mesh.SetIndices(list.ToArray(), MeshTopology.Points, 0);
|
|
mesh.bounds = new Bounds(Vector3.zero, new Vector3(500f, 500f, 500f));
|
|
mesh.hideFlags = HideFlags.HideAndDontSave;
|
|
meshToDraw = mesh;
|
|
}
|
|
}
|