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

151 lines
4.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Managers;
using Unity.Mathematics;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;
using static AffectingForcesManager;
[ExecuteInEditMode]
public class GravityChanger : MonoBehaviour
{
private static ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static Transform _nimbleZoneTransform;
public AffectingForcesManager forcesManager;
public GameObject renderedZoneObject;
[SerializeField]
private List<GravityColorEntry> GravityColors = new();
private Dictionary<Gravity, Color> _gravityColors =
new Dictionary<Gravity, Color>
{
{Gravity.DownGravity, Color.green },
{Gravity.UpGravity, Color.magenta },
{Gravity.NoGravity, Color.red },
{Gravity.InwardsGravity, Color.blue },
{Gravity.OutwardsGravity, Color.yellow },
};
[SerializeField]
private static float _gravityFactor = 30f;
[SerializeField]
private Gravity _gravity = Gravity.NoGravity;
private int maxRippleAmount = 5;
private MeshRenderer meshRenderer;
private Material material;
void Awake()
{
foreach (GravityColorEntry entry in GravityColors)
{
_gravityColors[entry.gravity] = entry.color;
}
meshRenderer = renderedZoneObject.GetComponent<MeshRenderer>();
_nimbleZoneTransform = gameObject.transform;
ApplyZoneColor(meshRenderer);
#if UNITY_EDITOR
if (!Application.isPlaying) return;
#endif
material = meshRenderer.material;
}
/// <summary>
/// Array of the available gravities.
/// </summary>
private Func<Transform, Transform, Vector3>[] gravityFunctions =
{ DownGravity, UpGravity, NoGravity, InwardsGravity, OutwardsGravity };
/// <summary>
/// Function which returns a gravity zero vector.
/// </summary>
private static readonly Func<Transform, Transform, Vector3> NoGravity =
new((gravitySource, target) => new Vector3());
/// <summary>
/// Function which returns a gravity vector downwards, depending
/// on the parent transforms rotation.
/// The parenting transform for a ship is the arena it's in.
/// </summary>
private static readonly Func<Transform, Transform, Vector3> DownGravity =
new((gravitySource, target) =>
gravitySource.rotation * Vector3.down * _gravityFactor);
/// <summary>
/// Function which returns a gravity vector upwards, depending
/// on the parent transforms rotation.
/// The parenting transform for a ship is the arena it's in.
/// </summary>
private static readonly Func<Transform, Transform, Vector3> UpGravity =
new((gravitySource, target) =>
gravitySource.rotation * Vector3.up * _gravityFactor);
/// <summary>
/// Function which returns a gravity vector towards the center of the parenting transform.
/// The parenting transform for a ship is the arena it's in.
/// </summary>
private static readonly Func<Transform, Transform, Vector3> InwardsGravity =
new((gravitySource, target) =>
(target.position - gravitySource.position).normalized * -_gravityFactor);
/// <summary>
/// Function which returns a gravity vector outwards from the center of the parenting transform.
/// The parenting transform for a ship is the arena it's in.
/// </summary>
private static readonly Func<Transform, Transform, Vector3> OutwardsGravity =
new((gravitySource, target) =>
(target.position - gravitySource.position).normalized * _gravityFactor);
public Func<Transform, Transform, Vector3> GetGravityFunction(Gravity gravity)
{
return gravityFunctions[(int)gravity];
}
private void OnTriggerEnter(Collider collider)
{
int instanceID = collider.gameObject.GetInstanceID();
if (collider.tag == "Ship")
{
forcesManager.SetGravityForInstance(instanceID, GetGravityFunction(_gravity), transform);
}
}
private void Update()
{
#if UNITY_EDITOR
if (!Application.isPlaying) return;
#endif
material.SetFloat("_ShaderTime", Time.timeSinceLevelLoad);
}
private void ApplyZoneColor(MeshRenderer renderer)
{
Color color = _gravityColors[_gravity];
MaterialPropertyBlock materialPropertyBlock = new();
materialPropertyBlock.SetColor("_BaseColor", color);
renderer.SetPropertyBlock(materialPropertyBlock);
}
}
public enum Gravity
{
DownGravity, UpGravity, NoGravity, InwardsGravity, OutwardsGravity
}
[Serializable]
public class GravityColorEntry
{
public Gravity gravity;
public Color color;
}