[Refactor] Reworked how OrbitalBehaviour behaves under the hood
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
public class EnemyController : OrbitalPositionBehaviour
|
public class EnemyController : OrbitalBehaviour
|
||||||
{
|
{
|
||||||
private static readonly List<EnemyController> Instances = new();
|
private static readonly List<EnemyController> Instances = new();
|
||||||
|
|
||||||
@@ -16,23 +16,31 @@ public class EnemyController : OrbitalPositionBehaviour
|
|||||||
Instances.Clear();
|
Instances.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStart()
|
private void Start()
|
||||||
{
|
{
|
||||||
Instances.Add(this);
|
Instances.Add(this);
|
||||||
|
|
||||||
transform.position = new Vector3(0, 0, -200f);
|
RegisterObject(new OrbitalInitializer
|
||||||
|
{
|
||||||
|
DistanceAlongCircumference = Random.Range(0f, Mathf.PI * 2f),
|
||||||
|
ObjectRadius = 0.1f,
|
||||||
|
SpinSpeed = 0.7f
|
||||||
|
});
|
||||||
|
|
||||||
m_OrbitalPosition.m_DistanceAlongRadius = Random.Range(0f, Mathf.PI * 2f);
|
transform.position = new Vector3(0, 0, -200f);
|
||||||
m_OrbitalPosition.m_ObjectRadius = 0.1f;
|
|
||||||
m_OrbitalPosition.m_SpinSpeed = 0.7f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnReachCentre()
|
protected override void OnReachCentre()
|
||||||
{
|
{
|
||||||
if (GlobalOrbitalPositionManager.s_IsSimulationRunning)
|
if (BehaviourManager.IsSimulationRunning)
|
||||||
PlayerController.s_PlayerScore++;
|
PlayerController.s_PlayerScore++;
|
||||||
|
|
||||||
Instances.Remove(this);
|
|
||||||
Destroy(gameObject);
|
Destroy(gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
BehaviourManager.UnregisterOrbitalInstance(this);
|
||||||
|
Instances.Remove(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
244
Assets/Scripts/GlobalOrbitalManager.cs
Normal file
244
Assets/Scripts/GlobalOrbitalManager.cs
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public partial class OrbitalBehaviour
|
||||||
|
{
|
||||||
|
public class BehaviourManager : MonoBehaviour
|
||||||
|
{
|
||||||
|
private static BehaviourManager Instance;
|
||||||
|
|
||||||
|
private Vector3[] m_PrecalculatedPositions;
|
||||||
|
|
||||||
|
private bool m_CurrentRingAllowsSpawning;
|
||||||
|
private bool m_IsSimulationRunning;
|
||||||
|
private bool m_AllowPlayerInput;
|
||||||
|
|
||||||
|
public static bool IsSimulationRunning => Instance.m_IsSimulationRunning;
|
||||||
|
public static bool AllowPlayerInput => Instance.m_AllowPlayerInput;
|
||||||
|
|
||||||
|
private float m_LocalDeltaTimeScale = 1f;
|
||||||
|
private float m_TimeOfLastRingSpawn;
|
||||||
|
|
||||||
|
private int m_LastGeneratedRing;
|
||||||
|
|
||||||
|
private readonly Dictionary<int, float> m_Distances = new();
|
||||||
|
private readonly List<OrbitalBehaviour> m_ObjectInstances = new();
|
||||||
|
private readonly List<Ring> m_Rings = new();
|
||||||
|
|
||||||
|
private OrbitalBehaviour m_PlayerInstance;
|
||||||
|
|
||||||
|
private GameObject m_RingParent;
|
||||||
|
|
||||||
|
private const int CirclePoints = 100;
|
||||||
|
|
||||||
|
public static IEnumerator StartPlayerSpeedupModifier()
|
||||||
|
{
|
||||||
|
Instance.m_LocalDeltaTimeScale *= 1.5f;
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(10f);
|
||||||
|
|
||||||
|
Instance.m_LocalDeltaTimeScale /= 1.5f;
|
||||||
|
Instance.m_LocalDeltaTimeScale *= 2f;
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(5f);
|
||||||
|
|
||||||
|
Instance.m_LocalDeltaTimeScale /= 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||||
|
private static void OnApplicationStart()
|
||||||
|
{
|
||||||
|
GameObject manager = new("OrbitalManager");
|
||||||
|
DontDestroyOnLoad(manager);
|
||||||
|
Instance = manager.AddComponent<BehaviourManager>();
|
||||||
|
|
||||||
|
Instance.PrecalculatePositions();
|
||||||
|
Instance.StartCoroutine(RestartSimulation());
|
||||||
|
|
||||||
|
Instance.m_RingParent = new GameObject("RingHolder");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PrecalculatePositions()
|
||||||
|
{
|
||||||
|
m_PrecalculatedPositions = new Vector3[CirclePoints];
|
||||||
|
for (int idx = 0; idx < m_PrecalculatedPositions.Length; idx++)
|
||||||
|
{
|
||||||
|
m_PrecalculatedPositions[idx] = new Vector3
|
||||||
|
(
|
||||||
|
x: Mathf.Cos(Mathf.Deg2Rad * (359f / CirclePoints * idx)),
|
||||||
|
y: Mathf.Sin(Mathf.Deg2Rad * (359f / CirclePoints * idx)),
|
||||||
|
z: 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerator RestartSimulation()
|
||||||
|
{
|
||||||
|
Instance.m_IsSimulationRunning = false;
|
||||||
|
Instance.m_AllowPlayerInput = false;
|
||||||
|
|
||||||
|
Instance.m_LocalDeltaTimeScale = 7f;
|
||||||
|
|
||||||
|
for (int idx = 0; idx < 100; idx++) // 100 = 5 seconds of fixed updates
|
||||||
|
{
|
||||||
|
if (Instance.m_PlayerInstance != null)
|
||||||
|
{
|
||||||
|
Instance.m_PlayerInstance.m_AttachedRing = Instance.m_LastGeneratedRing;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return new WaitForFixedUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerController.AttachPlayer();
|
||||||
|
|
||||||
|
foreach (OrbitalBehaviour behaviour in Instance.m_ObjectInstances)
|
||||||
|
{
|
||||||
|
behaviour.OnSimulationRestart();
|
||||||
|
}
|
||||||
|
|
||||||
|
yield return new WaitForSeconds(1.3f);
|
||||||
|
|
||||||
|
Instance.m_IsSimulationRunning = true;
|
||||||
|
Instance.m_AllowPlayerInput = true;
|
||||||
|
|
||||||
|
Instance.m_LocalDeltaTimeScale = 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SpawnNewRing()
|
||||||
|
{
|
||||||
|
GameObject newRing = Instantiate(Settings.Instance.RingPrefab, m_RingParent.transform);
|
||||||
|
newRing.transform.localScale = new Vector3(12f, 12f, 1f);
|
||||||
|
|
||||||
|
Ring ring = newRing.AddComponent<Ring>();
|
||||||
|
ring.m_ID = m_LastGeneratedRing + 1;
|
||||||
|
m_Rings.Add(ring);
|
||||||
|
|
||||||
|
LineRenderer lineRenderer = newRing.GetComponentInChildren<LineRenderer>();
|
||||||
|
lineRenderer.loop = true;
|
||||||
|
lineRenderer.positionCount = CirclePoints;
|
||||||
|
lineRenderer.startWidth = 0.1f;
|
||||||
|
lineRenderer.endWidth = 0.1f;
|
||||||
|
lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
|
||||||
|
|
||||||
|
m_LastGeneratedRing = ring.m_ID;
|
||||||
|
m_TimeOfLastRingSpawn = Time.time;
|
||||||
|
|
||||||
|
m_CurrentRingAllowsSpawning = Random.Range(0, 25) != 0;
|
||||||
|
if (!m_CurrentRingAllowsSpawning && m_AllowPlayerInput)
|
||||||
|
{
|
||||||
|
Instantiate(Settings.Instance.ModifierPrefab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (Time.time - m_TimeOfLastRingSpawn > Settings.Instance.GapDistance / m_LocalDeltaTimeScale)
|
||||||
|
{
|
||||||
|
SpawnNewRing();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Ring> toRemove = new();
|
||||||
|
m_Distances.Clear();
|
||||||
|
|
||||||
|
foreach (Ring ring in m_Rings)
|
||||||
|
{
|
||||||
|
float diff = (m_LocalDeltaTimeScale * Time.deltaTime) * Settings.Instance.DistanceSpeed;
|
||||||
|
ring.transform.localScale -= new Vector3(diff, diff, 0f);
|
||||||
|
|
||||||
|
LineRenderer lineRenderer = ring.GetComponentInChildren<LineRenderer>();
|
||||||
|
for (int vert = 0; vert < CirclePoints; vert++)
|
||||||
|
{
|
||||||
|
lineRenderer.SetPosition(vert, new Vector3
|
||||||
|
(
|
||||||
|
x: m_PrecalculatedPositions[vert].x * ring.transform.localScale.x,
|
||||||
|
y: m_PrecalculatedPositions[vert].y * ring.transform.localScale.y,
|
||||||
|
z: 10
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
float lerp = (ring.transform.localScale.x - 0.5f) / 4f;
|
||||||
|
Color c = Color.Lerp(Color.black, Color.white, Mathf.Clamp01(lerp));
|
||||||
|
if (ring.transform.localScale.x < 0.5f)
|
||||||
|
{
|
||||||
|
if (m_IsSimulationRunning)
|
||||||
|
PlayerController.s_PlayerScore++;
|
||||||
|
|
||||||
|
toRemove.Add(ring);
|
||||||
|
}
|
||||||
|
|
||||||
|
lineRenderer.startColor = c;
|
||||||
|
lineRenderer.endColor = c;
|
||||||
|
|
||||||
|
m_Distances[ring.m_ID] = ring.transform.localScale.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Ring ring in toRemove)
|
||||||
|
{
|
||||||
|
m_Rings.Remove(ring);
|
||||||
|
Destroy(ring.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (OrbitalBehaviour orbitalPosition in m_ObjectInstances)
|
||||||
|
{
|
||||||
|
if (!orbitalPosition.IsAttachedToRings)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!m_Distances.TryGetValue(orbitalPosition.m_AttachedRing, out float distance))
|
||||||
|
{
|
||||||
|
orbitalPosition.m_AttachedRing = m_LastGeneratedRing;
|
||||||
|
orbitalPosition.OnReachCentre();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
orbitalPosition.m_DistanceFromCentre = distance;
|
||||||
|
|
||||||
|
float deltaTime = Time.deltaTime * m_LocalDeltaTimeScale;
|
||||||
|
float movement = deltaTime * Settings.Instance.RadiusSpeed * orbitalPosition.m_SpinSpeed;
|
||||||
|
orbitalPosition.m_DistanceAlongCircumference += movement;
|
||||||
|
orbitalPosition.m_DistanceAlongCircumference %= Mathf.PI * 2;
|
||||||
|
orbitalPosition.transform.position = orbitalPosition.TranslateToVector3();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FixedUpdate()
|
||||||
|
{
|
||||||
|
foreach (OrbitalBehaviour orbital in m_ObjectInstances)
|
||||||
|
{
|
||||||
|
if (orbital == m_PlayerInstance)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Vector2 a = orbital.TranslateToVector3();
|
||||||
|
Vector2 b = m_PlayerInstance.TranslateToVector3();
|
||||||
|
float distance = (a - b).magnitude;
|
||||||
|
float radii = orbital.m_ObjectRadius + m_PlayerInstance.m_ObjectRadius;
|
||||||
|
if (distance > radii)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_PlayerInstance.OnOrbitalCollision(orbital);
|
||||||
|
orbital.OnOrbitalCollision(m_PlayerInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Random.Range(0, 20) == 0 && m_AllowPlayerInput && m_CurrentRingAllowsSpawning)
|
||||||
|
{
|
||||||
|
Instantiate(Settings.Instance.EnemyPrefab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UnregisterOrbitalInstance(OrbitalBehaviour instance)
|
||||||
|
{
|
||||||
|
Instance.m_ObjectInstances.Remove(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RegisterOrbitalInstance(OrbitalBehaviour instance)
|
||||||
|
{
|
||||||
|
instance.m_AttachedRing = Instance.m_LastGeneratedRing; // Connects it to last generated ring
|
||||||
|
Instance.m_ObjectInstances.Add(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetPlayer(OrbitalBehaviour player)
|
||||||
|
{
|
||||||
|
Instance.m_PlayerInstance = player;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Scripts/GlobalOrbitalManager.cs.meta
Normal file
11
Assets/Scripts/GlobalOrbitalManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 49460c83aa57cc6478a9366b88bc63e7
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -1,270 +1,52 @@
|
|||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
[System.Serializable] public class OrbitalPosition
|
public partial class OrbitalBehaviour : MonoBehaviour
|
||||||
{
|
{
|
||||||
public int m_AttachedRing;
|
[Header("Orbital Information")]
|
||||||
public float m_DistanceFromCentre;
|
[SerializeField] private int m_AttachedRing;
|
||||||
public float m_DistanceAlongRadius;
|
[SerializeField] private float m_DistanceAlongCircumference;
|
||||||
public float m_ObjectRadius = 0.1f;
|
[SerializeField] private float m_ObjectRadius = 0.1f;
|
||||||
public bool m_IsAttachedToRings = true;
|
[SerializeField] private float m_SpinSpeed = 0.1f;
|
||||||
|
|
||||||
public OrbitalPositionBehaviour m_Behaviour;
|
[SerializeField] private float m_DistanceFromCentre;
|
||||||
public readonly Transform m_Owner;
|
|
||||||
|
|
||||||
public float m_SpinSpeed = 1f;
|
[field: SerializeField] protected bool IsAttachedToRings { get; set; } = true;
|
||||||
|
|
||||||
public OrbitalPosition(GameObject owner)
|
protected void RegisterObject(OrbitalInitializer init)
|
||||||
{
|
{
|
||||||
m_AttachedRing = GlobalOrbitalPositionManager.LastRingID;
|
BehaviourManager.RegisterOrbitalInstance(this);
|
||||||
m_Owner = owner.transform;
|
|
||||||
|
m_DistanceAlongCircumference = init.DistanceAlongCircumference;
|
||||||
|
m_ObjectRadius = init.ObjectRadius;
|
||||||
|
m_SpinSpeed = init.SpinSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 TranslateToVec3() => new
|
private Vector3 TranslateToVector3() => new
|
||||||
(
|
(
|
||||||
x: m_DistanceFromCentre * Mathf.Cos(m_DistanceAlongRadius),
|
x: m_DistanceFromCentre * Mathf.Cos(m_DistanceAlongCircumference),
|
||||||
y: m_DistanceFromCentre * Mathf.Sin(m_DistanceAlongRadius)
|
y: m_DistanceFromCentre * Mathf.Sin(m_DistanceAlongCircumference),
|
||||||
|
z: 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
protected virtual void OnOrbitalCollision(OrbitalBehaviour other) { }
|
||||||
|
|
||||||
|
protected virtual void OnSimulationRestart() { }
|
||||||
|
protected virtual void OnReachCentre() { }
|
||||||
|
|
||||||
|
protected void AdvanceRing()
|
||||||
|
{
|
||||||
|
m_AttachedRing++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OrbitalInitializer
|
||||||
|
{
|
||||||
|
public float DistanceAlongCircumference { get; set; }
|
||||||
|
public float ObjectRadius { get; set; }
|
||||||
|
public float SpinSpeed { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Ring : MonoBehaviour
|
public class Ring : MonoBehaviour
|
||||||
{
|
{
|
||||||
public int m_ID;
|
public int m_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GlobalOrbitalPositionManager : MonoBehaviour
|
|
||||||
{
|
|
||||||
private static GlobalOrbitalPositionManager s_Instance;
|
|
||||||
public static GlobalOrbitalPositionManager Instance => s_Instance;
|
|
||||||
|
|
||||||
private readonly List<OrbitalPosition> m_ObjectInstances = new();
|
|
||||||
private readonly List<Ring> m_Rings = new();
|
|
||||||
private readonly Dictionary<int, float> m_Distances = new();
|
|
||||||
|
|
||||||
public static bool s_IsSimulationRunning = true;
|
|
||||||
|
|
||||||
private OrbitalPosition m_PlayerOrbitalPosition;
|
|
||||||
public static void SetPlayer(OrbitalPosition player) => s_Instance.m_PlayerOrbitalPosition = player;
|
|
||||||
|
|
||||||
public static bool AllowPlayerInput { get; private set; } = true;
|
|
||||||
|
|
||||||
private float m_TimeOfLastRingSpawn = float.NegativeInfinity;
|
|
||||||
|
|
||||||
private int m_LastGeneratedRing;
|
|
||||||
public static int LastRingID => s_Instance.m_LastGeneratedRing;
|
|
||||||
|
|
||||||
private const int CirclePoints = 100;
|
|
||||||
|
|
||||||
private float m_LocalDeltaTimeScale = 1f;
|
|
||||||
private float LocalDeltaTime => Time.deltaTime * m_LocalDeltaTimeScale;
|
|
||||||
|
|
||||||
private bool m_CurrentRingAllowsSpawning;
|
|
||||||
|
|
||||||
private Vector3[] m_PrecalculatedPositions;
|
|
||||||
|
|
||||||
public IEnumerator StartPlayerSpeedupModifier()
|
|
||||||
{
|
|
||||||
m_LocalDeltaTimeScale *= 1.5f;
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(10f);
|
|
||||||
|
|
||||||
m_LocalDeltaTimeScale /= 1.5f;
|
|
||||||
m_LocalDeltaTimeScale *= 2f;
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(5f);
|
|
||||||
|
|
||||||
m_LocalDeltaTimeScale /= 2f;
|
|
||||||
}
|
|
||||||
|
|
||||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void OnApplicationStart()
|
|
||||||
{
|
|
||||||
GameObject manager = new("GLOBAL ORBITAL MANAGER");
|
|
||||||
DontDestroyOnLoad(manager);
|
|
||||||
|
|
||||||
s_Instance = manager.AddComponent<GlobalOrbitalPositionManager>();
|
|
||||||
s_Instance.m_PrecalculatedPositions = new Vector3[CirclePoints];
|
|
||||||
|
|
||||||
for (int i = 0; i < s_Instance.m_PrecalculatedPositions.Length; i++)
|
|
||||||
{
|
|
||||||
s_Instance.m_PrecalculatedPositions[i] = new Vector3
|
|
||||||
(
|
|
||||||
x: Mathf.Cos(Mathf.Deg2Rad * (359f / CirclePoints * i)),
|
|
||||||
y: Mathf.Sin(Mathf.Deg2Rad * (359f / CirclePoints * i)),
|
|
||||||
z: 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
RestartSimulation();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerator RestartSimulationInternal()
|
|
||||||
{
|
|
||||||
s_IsSimulationRunning = false;
|
|
||||||
|
|
||||||
s_Instance.m_LocalDeltaTimeScale = 7f;
|
|
||||||
AllowPlayerInput = false;
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
yield return new WaitForFixedUpdate();
|
|
||||||
|
|
||||||
if (PlayerController.IsPlayerAttached)
|
|
||||||
s_Instance.m_PlayerOrbitalPosition.m_AttachedRing = s_Instance.m_LastGeneratedRing;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerController.AttachPlayer();
|
|
||||||
foreach (OrbitalPosition behaviour in s_Instance.m_ObjectInstances)
|
|
||||||
{
|
|
||||||
behaviour.m_Behaviour.OnSimulationRestart();
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new WaitForSeconds(1.3f);
|
|
||||||
AllowPlayerInput = true;
|
|
||||||
s_Instance.m_LocalDeltaTimeScale = 1f;
|
|
||||||
|
|
||||||
s_IsSimulationRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RestartSimulation() => s_Instance.StartCoroutine(RestartSimulationInternal());
|
|
||||||
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
if (Time.time - m_TimeOfLastRingSpawn > (Settings.Instance.GapDistance / m_LocalDeltaTimeScale))
|
|
||||||
{
|
|
||||||
GameObject newRing = Instantiate(Settings.Instance.RingPrefab);
|
|
||||||
newRing.transform.localScale = new Vector3(12f, 12f, 1);
|
|
||||||
|
|
||||||
Ring ring = newRing.AddComponent<Ring>();
|
|
||||||
ring.m_ID = m_LastGeneratedRing + 1;
|
|
||||||
m_Rings.Add(ring);
|
|
||||||
|
|
||||||
LineRenderer lineRenderer = newRing.GetComponentInChildren<LineRenderer>();
|
|
||||||
lineRenderer.loop = true;
|
|
||||||
lineRenderer.positionCount = CirclePoints;
|
|
||||||
lineRenderer.startWidth = 0.1f;
|
|
||||||
lineRenderer.endWidth = 0.1f;
|
|
||||||
lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
|
|
||||||
|
|
||||||
m_LastGeneratedRing = ring.m_ID;
|
|
||||||
m_TimeOfLastRingSpawn = Time.time;
|
|
||||||
|
|
||||||
m_CurrentRingAllowsSpawning = Random.Range(0, 25) != 0;
|
|
||||||
if (!m_CurrentRingAllowsSpawning && AllowPlayerInput)
|
|
||||||
Instantiate(Settings.Instance.ModifierPrefab);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Ring> toRemove = new();
|
|
||||||
m_Distances.Clear();
|
|
||||||
|
|
||||||
foreach (Ring ring in m_Rings)
|
|
||||||
{
|
|
||||||
float diff = LocalDeltaTime * Settings.Instance.DistanceSpeed;
|
|
||||||
ring.transform.localScale -= new Vector3(diff, diff, 0f);
|
|
||||||
|
|
||||||
LineRenderer lineRenderer = ring.GetComponentInChildren<LineRenderer>();
|
|
||||||
for (int vert = 0; vert < CirclePoints; vert++)
|
|
||||||
{
|
|
||||||
lineRenderer.SetPosition(vert, new Vector3
|
|
||||||
(
|
|
||||||
x: m_PrecalculatedPositions[vert].x * ring.transform.localScale.x,
|
|
||||||
y: m_PrecalculatedPositions[vert].y * ring.transform.localScale.y,
|
|
||||||
z: 10
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
float lerp = (ring.transform.localScale.x - 0.5f) / 4f;
|
|
||||||
Color c = Color.Lerp(Color.black, Color.white, Mathf.Clamp01(lerp));
|
|
||||||
if (ring.transform.localScale.x < 0.5f)
|
|
||||||
{
|
|
||||||
if (s_IsSimulationRunning)
|
|
||||||
PlayerController.s_PlayerScore++;
|
|
||||||
|
|
||||||
toRemove.Add(ring);
|
|
||||||
}
|
|
||||||
|
|
||||||
lineRenderer.startColor = c;
|
|
||||||
lineRenderer.endColor = c;
|
|
||||||
|
|
||||||
m_Distances[ring.m_ID] = ring.transform.localScale.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Ring ring in toRemove)
|
|
||||||
{
|
|
||||||
m_Rings.Remove(ring);
|
|
||||||
Destroy(ring.gameObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (OrbitalPosition orbitalPosition in m_ObjectInstances)
|
|
||||||
{
|
|
||||||
if (!orbitalPosition.m_IsAttachedToRings)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!m_Distances.ContainsKey(orbitalPosition.m_AttachedRing))
|
|
||||||
{
|
|
||||||
orbitalPosition.m_AttachedRing = m_LastGeneratedRing;
|
|
||||||
orbitalPosition.m_Behaviour.OnReachCentre();
|
|
||||||
}
|
|
||||||
|
|
||||||
float distance = m_Distances[orbitalPosition.m_AttachedRing];
|
|
||||||
orbitalPosition.m_DistanceFromCentre = distance;
|
|
||||||
orbitalPosition.m_DistanceAlongRadius = (orbitalPosition.m_DistanceAlongRadius + LocalDeltaTime * Settings.Instance.RadiusSpeed * orbitalPosition.m_SpinSpeed) % (Mathf.PI * 2);
|
|
||||||
|
|
||||||
orbitalPosition.m_Owner.position = orbitalPosition.TranslateToVec3();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FixedUpdate()
|
|
||||||
{
|
|
||||||
foreach (OrbitalPosition orbital in m_ObjectInstances)
|
|
||||||
{
|
|
||||||
if (orbital == m_PlayerOrbitalPosition)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Vector2 a = orbital.TranslateToVec3();
|
|
||||||
Vector2 b = m_PlayerOrbitalPosition.TranslateToVec3();
|
|
||||||
float distance = (a - b).magnitude;
|
|
||||||
float radii = orbital.m_ObjectRadius + m_PlayerOrbitalPosition.m_ObjectRadius;
|
|
||||||
if (distance < radii)
|
|
||||||
{
|
|
||||||
orbital.m_Behaviour.OnCollision(m_PlayerOrbitalPosition.m_Behaviour);
|
|
||||||
m_PlayerOrbitalPosition.m_Behaviour.OnCollision(orbital.m_Behaviour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Random.Range(0, 20) == 0 && AllowPlayerInput && m_CurrentRingAllowsSpawning)
|
|
||||||
Instantiate(Settings.Instance.EnemyPrefab);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RegisterOrbitalPositionInstance(OrbitalPosition newInstance) =>
|
|
||||||
s_Instance.m_ObjectInstances.Add(newInstance);
|
|
||||||
|
|
||||||
public static void UnregisterOrbitalPositionInstance(OrbitalPosition removedInstance) =>
|
|
||||||
s_Instance.m_ObjectInstances.Remove(removedInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class OrbitalPositionBehaviour : MonoBehaviour
|
|
||||||
{
|
|
||||||
[SerializeField] protected OrbitalPosition m_OrbitalPosition;
|
|
||||||
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
m_OrbitalPosition = new OrbitalPosition(gameObject)
|
|
||||||
{
|
|
||||||
m_Behaviour = this
|
|
||||||
};
|
|
||||||
|
|
||||||
GlobalOrbitalPositionManager.RegisterOrbitalPositionInstance(m_OrbitalPosition);
|
|
||||||
OnStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy() =>
|
|
||||||
GlobalOrbitalPositionManager.UnregisterOrbitalPositionInstance(m_OrbitalPosition);
|
|
||||||
|
|
||||||
protected virtual void OnStart() { }
|
|
||||||
|
|
||||||
public virtual void OnReachCentre() { }
|
|
||||||
|
|
||||||
public virtual void OnCollision(OrbitalPositionBehaviour other) { }
|
|
||||||
|
|
||||||
public virtual void OnSimulationRestart() { }
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using UnityEngine;
|
|||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityEngine.Rendering.PostProcessing;
|
using UnityEngine.Rendering.PostProcessing;
|
||||||
|
|
||||||
public class PlayerController : OrbitalPositionBehaviour
|
public class PlayerController : OrbitalBehaviour
|
||||||
{
|
{
|
||||||
[Header("References")]
|
[Header("References")]
|
||||||
[SerializeField] private MeshRenderer m_Renderer;
|
[SerializeField] private MeshRenderer m_Renderer;
|
||||||
@@ -14,7 +14,6 @@ public class PlayerController : OrbitalPositionBehaviour
|
|||||||
[SerializeField] private PostProcessVolume m_PostProcessVolume;
|
[SerializeField] private PostProcessVolume m_PostProcessVolume;
|
||||||
|
|
||||||
private static PlayerController Instance;
|
private static PlayerController Instance;
|
||||||
public static bool IsPlayerAttached => Instance.m_OrbitalPosition.m_IsAttachedToRings;
|
|
||||||
|
|
||||||
private static int s_HighScore = 20;
|
private static int s_HighScore = 20;
|
||||||
public static int s_PlayerScore;
|
public static int s_PlayerScore;
|
||||||
@@ -26,16 +25,19 @@ public class PlayerController : OrbitalPositionBehaviour
|
|||||||
private bool m_HasInvincibility;
|
private bool m_HasInvincibility;
|
||||||
private bool m_KillingItself;
|
private bool m_KillingItself;
|
||||||
|
|
||||||
protected override void OnStart()
|
private void Start()
|
||||||
{
|
{
|
||||||
Instance = this;
|
|
||||||
s_HighScore = Mathf.Max(s_HighScore, PlayerPrefs.GetInt("HighScore", 0));
|
s_HighScore = Mathf.Max(s_HighScore, PlayerPrefs.GetInt("HighScore", 0));
|
||||||
Debug.Log($"Loaded high score of [{s_HighScore}]");
|
Instance = this;
|
||||||
|
|
||||||
GlobalOrbitalPositionManager.SetPlayer(m_OrbitalPosition);
|
BehaviourManager.SetPlayer(this);
|
||||||
|
RegisterObject(new OrbitalInitializer
|
||||||
|
{
|
||||||
|
ObjectRadius = 0.1f,
|
||||||
|
SpinSpeed = 0.2f
|
||||||
|
});
|
||||||
|
|
||||||
m_OrbitalPosition.m_ObjectRadius = 0.1f;
|
IsAttachedToRings = true;
|
||||||
m_OrbitalPosition.m_SpinSpeed = 0.2f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@@ -45,9 +47,9 @@ public class PlayerController : OrbitalPositionBehaviour
|
|||||||
m_ScoreText.color = s_PlayerScore > s_HighScore ? Color.yellow : Color.white;
|
m_ScoreText.color = s_PlayerScore > s_HighScore ? Color.yellow : Color.white;
|
||||||
m_Renderer.material = m_HasFreeHitActive ? m_FreeHitMaterial : m_DefaultMaterial;
|
m_Renderer.material = m_HasFreeHitActive ? m_FreeHitMaterial : m_DefaultMaterial;
|
||||||
|
|
||||||
if (GlobalInput.IsScreenClicked && GlobalOrbitalPositionManager.AllowPlayerInput)
|
if (GlobalInput.IsScreenClicked && BehaviourManager.AllowPlayerInput)
|
||||||
{
|
{
|
||||||
m_OrbitalPosition.m_AttachedRing += 1;
|
AdvanceRing();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_KillingItself)
|
if (!m_KillingItself)
|
||||||
@@ -57,31 +59,26 @@ public class PlayerController : OrbitalPositionBehaviour
|
|||||||
m_DeathLerp += Time.deltaTime;
|
m_DeathLerp += Time.deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AttachPlayer()
|
|
||||||
{
|
|
||||||
Instance.m_OrbitalPosition.m_IsAttachedToRings = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator OnGrowPlayerModifier()
|
private IEnumerator OnGrowPlayerModifier()
|
||||||
{
|
{
|
||||||
transform.localScale *= 1.5f;
|
transform.localScale *= 1.5f;
|
||||||
m_OrbitalPosition.m_ObjectRadius *= 1.5f;
|
//m_OrbitalPosition.m_ObjectRadius *= 1.5f;
|
||||||
|
|
||||||
yield return new WaitForSecondsRealtime(15f);
|
yield return new WaitForSecondsRealtime(15f);
|
||||||
|
|
||||||
transform.localScale /= 1.5f;
|
transform.localScale /= 1.5f;
|
||||||
m_OrbitalPosition.m_ObjectRadius /= 1.5f;
|
//m_OrbitalPosition.m_ObjectRadius /= 1.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerator OnShrinkPlayerModifier()
|
private IEnumerator OnShrinkPlayerModifier()
|
||||||
{
|
{
|
||||||
transform.localScale *= 0.6f;
|
transform.localScale *= 0.6f;
|
||||||
m_OrbitalPosition.m_ObjectRadius *= 0.6f;
|
//m_OrbitalPosition.m_ObjectRadius *= 0.6f;
|
||||||
|
|
||||||
yield return new WaitForSecondsRealtime(15f);
|
yield return new WaitForSecondsRealtime(15f);
|
||||||
|
|
||||||
transform.localScale /= 0.6f;
|
transform.localScale /= 0.6f;
|
||||||
m_OrbitalPosition.m_ObjectRadius /= 0.6f;
|
//m_OrbitalPosition.m_ObjectRadius /= 0.6f;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerator TriggerInvincibility()
|
private IEnumerator TriggerInvincibility()
|
||||||
@@ -94,9 +91,9 @@ public class PlayerController : OrbitalPositionBehaviour
|
|||||||
m_HasInvincibility = false;
|
m_HasInvincibility = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnCollision(OrbitalPositionBehaviour other)
|
protected override void OnOrbitalCollision(OrbitalBehaviour other)
|
||||||
{
|
{
|
||||||
if (!m_OrbitalPosition.m_IsAttachedToRings)
|
if (!IsAttachedToRings)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (other.CompareTag("Enemy"))
|
if (other.CompareTag("Enemy"))
|
||||||
@@ -112,7 +109,8 @@ public class PlayerController : OrbitalPositionBehaviour
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalOrbitalPositionManager.RestartSimulation();
|
StartCoroutine(BehaviourManager.RestartSimulation());
|
||||||
|
|
||||||
m_SuicidePoint = transform.position;
|
m_SuicidePoint = transform.position;
|
||||||
m_KillingItself = true;
|
m_KillingItself = true;
|
||||||
m_DeathLerp = 0f;
|
m_DeathLerp = 0f;
|
||||||
@@ -139,7 +137,7 @@ public class PlayerController : OrbitalPositionBehaviour
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PlayerModifier.Modifiers.SpeedUp:
|
case PlayerModifier.Modifiers.SpeedUp:
|
||||||
StartCoroutine(GlobalOrbitalPositionManager.Instance.StartPlayerSpeedupModifier());
|
StartCoroutine(BehaviourManager.StartPlayerSpeedupModifier());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PlayerModifier.Modifiers.ClearAllEnemies:
|
case PlayerModifier.Modifiers.ClearAllEnemies:
|
||||||
@@ -158,7 +156,7 @@ public class PlayerController : OrbitalPositionBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnSimulationRestart()
|
protected override void OnSimulationRestart()
|
||||||
{
|
{
|
||||||
m_KillingItself = false;
|
m_KillingItself = false;
|
||||||
m_Renderer.enabled = true;
|
m_Renderer.enabled = true;
|
||||||
@@ -172,8 +170,13 @@ public class PlayerController : OrbitalPositionBehaviour
|
|||||||
s_PlayerScore = 0;
|
s_PlayerScore = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnReachCentre()
|
protected override void OnReachCentre()
|
||||||
{
|
{
|
||||||
GlobalOrbitalPositionManager.RestartSimulation();
|
StartCoroutine(BehaviourManager.RestartSimulation());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AttachPlayer()
|
||||||
|
{
|
||||||
|
Instance.IsAttachedToRings = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Random = UnityEngine.Random;
|
using URandom = UnityEngine.Random;
|
||||||
|
|
||||||
public class PlayerModifier : OrbitalPositionBehaviour
|
public class PlayerModifier : OrbitalBehaviour
|
||||||
{
|
{
|
||||||
public enum Modifiers
|
public enum Modifiers
|
||||||
{
|
{
|
||||||
@@ -24,17 +24,24 @@ public class PlayerModifier : OrbitalPositionBehaviour
|
|||||||
return (Modifiers)possibilities.GetValue(s_RandomGenerator.Next(possibilities.Length));
|
return (Modifiers)possibilities.GetValue(s_RandomGenerator.Next(possibilities.Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnStart()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
RegisterObject(new OrbitalInitializer
|
||||||
|
{
|
||||||
|
DistanceAlongCircumference = URandom.Range(0f, Mathf.PI * 2f),
|
||||||
|
ObjectRadius = 0.3f,
|
||||||
|
SpinSpeed = 1.6f
|
||||||
|
});
|
||||||
|
|
||||||
transform.position = new Vector3(0, 0, -100f);
|
transform.position = new Vector3(0, 0, -100f);
|
||||||
|
|
||||||
m_OrbitalPosition.m_DistanceAlongRadius = Random.Range(0f, Mathf.PI * 2f);
|
|
||||||
m_OrbitalPosition.m_ObjectRadius = 0.3f;
|
|
||||||
m_OrbitalPosition.m_SpinSpeed = 1.6f;
|
|
||||||
|
|
||||||
Modifier = GetRandomModifier();
|
Modifier = GetRandomModifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnCollision(OrbitalPositionBehaviour other) => Destroy(gameObject);
|
protected override void OnOrbitalCollision(OrbitalBehaviour other) => Destroy(gameObject);
|
||||||
public override void OnReachCentre() => Destroy(gameObject);
|
protected override void OnReachCentre() => Destroy(gameObject);
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
BehaviourManager.UnregisterOrbitalInstance(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user