LethalCompany/Lethal Company/ExportedProject/Assets/Scripts/Assembly-CSharp/DigitalRuby/ThunderAndLightning/LightningMeshSurfaceScript.cs
2023-12-22 18:30:10 -05:00

170 lines
5.2 KiB
C#

using System.Collections.Generic;
using UnityEngine;
namespace DigitalRuby.ThunderAndLightning
{
public class LightningMeshSurfaceScript : LightningBoltPrefabScriptBase
{
[Header("Lightning Mesh Properties")]
[Tooltip("The mesh filter. You must assign a mesh filter in order to create lightning on the mesh.")]
public MeshFilter MeshFilter;
[Tooltip("The mesh collider. This is used to get random points on the mesh.")]
public Collider MeshCollider;
[SingleLine("Random range that the point will offset from the mesh, using the normal of the chosen point to offset")]
public RangeOfFloats MeshOffsetRange = new RangeOfFloats
{
Minimum = 0.5f,
Maximum = 1f
};
[Header("Lightning Path Properties")]
[SingleLine("Range for points in the lightning path")]
public RangeOfIntegers PathLengthCount = new RangeOfIntegers
{
Minimum = 3,
Maximum = 6
};
[SingleLine("Range for minimum distance between points in the lightning path")]
public RangeOfFloats MinimumPathDistanceRange = new RangeOfFloats
{
Minimum = 0.5f,
Maximum = 1f
};
[Tooltip("The maximum distance between mesh points. When walking the mesh, if a point is greater than this, the path direction is reversed. This tries to avoid paths crossing between mesh points that are not actually physically touching.")]
public float MaximumPathDistance = 2f;
private float maximumPathDistanceSquared;
[Tooltip("Whether to use spline interpolation between the path points. Paths must be at least 4 points long to be splined.")]
public bool Spline;
[Tooltip("For spline. the distance hint for each spline segment. Set to <= 0 to use the generations to determine how many spline segments to use. If > 0, it will be divided by Generations before being applied. This value is a guideline and is approximate, and not uniform on the spline.")]
public float DistancePerSegmentHint;
private readonly List<Vector3> sourcePoints = new List<Vector3>();
private Mesh previousMesh;
private MeshHelper meshHelper;
private void CheckMesh()
{
if (MeshFilter == null || MeshFilter.sharedMesh == null)
{
meshHelper = null;
}
else if (MeshFilter.sharedMesh != previousMesh)
{
previousMesh = MeshFilter.sharedMesh;
meshHelper = new MeshHelper(previousMesh);
}
}
protected override LightningBoltParameters OnCreateParameters()
{
LightningBoltParameters lightningBoltParameters = base.OnCreateParameters();
lightningBoltParameters.Generator = LightningGeneratorPath.PathGeneratorInstance;
return lightningBoltParameters;
}
protected virtual void PopulateSourcePoints(List<Vector3> points)
{
if (meshHelper != null)
{
CreateRandomLightningPath(sourcePoints);
}
}
public void CreateRandomLightningPath(List<Vector3> points)
{
if (meshHelper == null)
{
return;
}
RaycastHit hit = default(RaycastHit);
maximumPathDistanceSquared = MaximumPathDistance * MaximumPathDistance;
meshHelper.GenerateRandomPoint(ref hit, out var triangleIndex);
hit.distance = Random.Range(MeshOffsetRange.Minimum, MeshOffsetRange.Maximum);
Vector3 vector = hit.point + hit.normal * hit.distance;
float num = Random.Range(MinimumPathDistanceRange.Minimum, MinimumPathDistanceRange.Maximum);
num *= num;
sourcePoints.Add(MeshFilter.transform.TransformPoint(vector));
int num2 = ((Random.Range(0, 1) == 1) ? 3 : (-3));
int num3 = Random.Range(PathLengthCount.Minimum, PathLengthCount.Maximum);
while (num3 != 0)
{
triangleIndex += num2;
if (triangleIndex >= 0 && triangleIndex < meshHelper.Triangles.Length)
{
meshHelper.GetRaycastFromTriangleIndex(triangleIndex, ref hit);
hit.distance = Random.Range(MeshOffsetRange.Minimum, MeshOffsetRange.Maximum);
Vector3 vector2 = hit.point + hit.normal * hit.distance;
float sqrMagnitude = (vector2 - vector).sqrMagnitude;
if (sqrMagnitude > maximumPathDistanceSquared)
{
break;
}
if (sqrMagnitude >= num)
{
vector = vector2;
sourcePoints.Add(MeshFilter.transform.TransformPoint(vector2));
num3--;
num = Random.Range(MinimumPathDistanceRange.Minimum, MinimumPathDistanceRange.Maximum);
num *= num;
}
}
else
{
num2 = -num2;
triangleIndex += num2;
num3--;
}
}
}
protected override void Start()
{
base.Start();
}
protected override void Update()
{
if (Time.timeScale > 0f)
{
CheckMesh();
}
base.Update();
}
public override void CreateLightningBolt(LightningBoltParameters parameters)
{
if (meshHelper == null)
{
return;
}
int generations = (parameters.Generations = Mathf.Clamp(Generations, 1, 5));
Generations = generations;
sourcePoints.Clear();
PopulateSourcePoints(sourcePoints);
if (sourcePoints.Count > 1)
{
parameters.Points.Clear();
if (Spline && sourcePoints.Count > 3)
{
LightningSplineScript.PopulateSpline(parameters.Points, sourcePoints, Generations, DistancePerSegmentHint, Camera);
parameters.SmoothingFactor = (parameters.Points.Count - 1) / sourcePoints.Count;
}
else
{
parameters.Points.AddRange(sourcePoints);
parameters.SmoothingFactor = 1;
}
base.CreateLightningBolt(parameters);
}
}
}
}