Files
UltimateFishing2020/Assets/Scripts/Assembly-CSharp/PrecipitationManager.cs
2026-03-04 10:03:45 +08:00

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;
}
}