Space-Smash-Out/Assets/Scripts/NimbleZoneDetection.cs

166 lines
5.7 KiB
C#

using System;
using System.Linq;
using UnityEngine;
using static AffectingForcesManager;
public class NimbleZoneDetection : MonoBehaviour
{
public AffectingForcesManager forcesManager;
public GameObject renderedZoneObject;
public enum Gravities
{
DownGravity, NoGravity, InwardsGravity, OutwardsGravity
}
[SerializeField]
private static float gravityFactor = 30f;
[SerializeField]
private Gravities outsideGravityFunction = Gravities.NoGravity;
[SerializeField]
private Zone zone = Zone.NimbleZone;
// Ripple properties
[SerializeField]
private float rippleFrequency = 3f;
[SerializeField]
private float rippleDensity = 30f;
[SerializeField]
private float rippleAmplitude = 0.2f;
[SerializeField]
private float rippleBlend = 1f;
[SerializeField]
private float rippleRadius = 2f;
[SerializeField]
private float rippleDuration = 2f;
private int maxRippleAmount = 5;
private int playerCount = 2;
private int spawnedCount = 0;
private MeshRenderer meshRenderer;
private Material material;
void Awake()
{
meshRenderer = renderedZoneObject.GetComponent<MeshRenderer>();
material = meshRenderer.material;
ResetShaderProperties();
}
private Func<Vector3, Vector3>[] gravityFunctions =
{ DownGravity, NoGravity, InwardsGravity, OutwardsGravity };
private static Func<Vector3, Vector3> NoGravity =
new Func<Vector3, Vector3>(position => new Vector3());
private static Func<Vector3, Vector3> DownGravity =
new Func<Vector3, Vector3>(position => Vector3.down * gravityFactor);
private static Func<Vector3, Vector3> InwardsGravity =
new Func<Vector3, Vector3>
(position => new Vector3(position.x, position.y, 0).normalized * -gravityFactor);
private static Func<Vector3, Vector3> OutwardsGravity = new Func<Vector3, Vector3>
(position => new Vector3(position.x, position.y, 0).normalized * gravityFactor);
public Func<Vector3, Vector3> GetGravityFunction(Gravities gravity)
{
return gravityFunctions[(int)gravity];
}
private void OnTriggerEnter(Collider collider)
{
int instanceID = collider.gameObject.GetInstanceID();
if (spawnedCount < playerCount)
++spawnedCount;
else SpawnRipple(collider, false);
forcesManager.SetGravityForInstance(instanceID, NoGravity);
forcesManager.SetZoneForInstance(instanceID, zone);
}
private void OnTriggerExit(Collider collider)
{
int instanceID = collider.gameObject.GetInstanceID();
SpawnRipple(collider, true);
forcesManager.SetGravityForInstance(instanceID, GetGravityFunction(outsideGravityFunction));
forcesManager.SetZoneForInstance(instanceID, Zone.OutsideZone);
}
private void Update()
{
material.SetFloat("_ShaderTime", Time.timeSinceLevelLoad);
}
private void SpawnRipple(Collider collider, bool isOutwardsRipple)
{
Rigidbody body = collider.attachedRigidbody;
GameObject gameObject = collider.gameObject;
float velocity = body.velocity.magnitude;
Vector3 position = (gameObject.transform.position - transform.position).normalized;
Vector4[] rippleOrigins = material.GetVectorArray("_RippleOrigins");
float currentTime = Time.timeSinceLevelLoad;
var whyGodWhy = material.GetVector("_TIME");
Console.WriteLine(whyGodWhy);
float[] startedTimes = material.GetFloatArray("_RippleStartTimes");
float[] startedRippleDurations = material.GetFloatArray("_RippleDurations");
float[] rippleAmplitudes = material.GetFloatArray("_RippleAmplitudes");
float[] rippleFrequencies = material.GetFloatArray("_RippleFrequencies");
float[] rippleDensities = material.GetFloatArray("_RippleDensities");
float[] rippleBlends = material.GetFloatArray("_RippleBlends");
float[] rippleRadii = material.GetFloatArray("_RippleRadii");
for (int i = 0; i < startedTimes.Length; ++i)
{
if (startedTimes[i] + startedRippleDurations[i] < currentTime)
{
rippleOrigins[i] = new Vector4(position.x, position.y, position.z, 0);
material.SetVectorArray("_RippleOrigins", rippleOrigins);
startedTimes[i] = currentTime;
material.SetFloatArray("_RippleStartTimes", startedTimes);
rippleAmplitudes[i] = isOutwardsRipple ? rippleAmplitude : -rippleAmplitude;
rippleFrequencies[i] = rippleFrequency;
rippleDensities[i] = rippleDensity;
rippleBlends[i] = rippleBlend;
startedRippleDurations[i] = rippleDuration;
rippleRadii[i] = rippleRadius;
material.SetFloatArray("_RippleAmplitudes", rippleAmplitudes);
material.SetFloatArray("_RippleFrequencies", rippleFrequencies);
material.SetFloatArray("_RippleDensities", rippleDensities);
material.SetFloatArray("_RippleAmplitudes", rippleAmplitudes);
material.SetFloatArray("_RippleBlends", rippleBlends);
material.SetFloatArray("_RippleDurations", startedRippleDurations);
material.SetFloatArray("_RippleRadii", rippleRadii);
break;
}
}
}
private void ResetShaderProperties()
{
Vector4[] rippleOrigins = new Vector4[maxRippleAmount];
float[] startedTimes = new float[maxRippleAmount];
float[] rippleAmplitudes = new float[maxRippleAmount];
float[] rippleFrequencies = new float[maxRippleAmount];
float[] rippleDensities = new float[maxRippleAmount];
float[] rippleDurations = new float[maxRippleAmount];
float[] rippleRadii = new float[maxRippleAmount];
float[] rippleBlends = new float[maxRippleAmount];
// Initialize Ripple Shader Properties
material.SetVectorArray("_RippleOrigins", rippleOrigins);
material.SetFloatArray("_RippleStartTimes", startedTimes);
material.SetFloatArray("_RippleAmplitudes", rippleAmplitudes);
material.SetFloatArray("_RippleFrequencies", rippleFrequencies);
material.SetFloatArray("_RippleDensities", rippleDensities);
material.SetFloatArray("_RippleBlends", rippleBlends);
material.SetFloatArray("_RippleDurations", rippleDurations);
material.SetFloatArray("_RippleRadii", rippleRadii);
}
}