using System.Collections.Generic; using UnityEngine; public class OrbitalPosition : MonoBehaviour { public float DistanceFromCentre = 0; public float RadiusDistance = 0; public Vector3 TranslateToVec3() => new ( x: DistanceFromCentre * Mathf.Cos(RadiusDistance), y: DistanceFromCentre * Mathf.Sin(RadiusDistance) ); } public class GlobalOrbitalPositionManager : MonoBehaviour { static GlobalOrbitalPositionManager s_Instance = null; List m_ObjectInstances = new(); [SerializeField, Range(0f, Mathf.PI * 2)] float m_RadiusSpeed = 2f; [SerializeField, Range(0f, 2f)] float m_DistanceSpeed = 2f; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] private static void OnApplicationStart() { GameObject manager = new("GLOBAL ORBITAL MANAGER"); DontDestroyOnLoad(manager); s_Instance = manager.AddComponent(); } public void Update() { foreach (OrbitalPosition orbitalPosition in m_ObjectInstances) { orbitalPosition.DistanceFromCentre = Mathf.Clamp(orbitalPosition.DistanceFromCentre - (m_DistanceSpeed * Time.deltaTime * m_DistanceSpeed), 0f, float.PositiveInfinity); orbitalPosition.RadiusDistance = (orbitalPosition.RadiusDistance + (m_RadiusSpeed * Time.deltaTime * m_RadiusSpeed)) % (Mathf.PI * 2); orbitalPosition.gameObject.transform.position = orbitalPosition.TranslateToVec3(); } } public static void RegisterOrbitalPositionInstance(OrbitalPosition newInstance) => s_Instance.m_ObjectInstances.Add(newInstance); public static void UnregisterOrbitalPositionInstance(OrbitalPosition removedInstance) => s_Instance.m_ObjectInstances.Remove(removedInstance); } [RequireComponent(typeof(OrbitalPosition))] public abstract class OrbitalPositionBehaviour : MonoBehaviour { protected OrbitalPosition m_OrbitalPosition = null; private void Start() { m_OrbitalPosition = GetComponent(); GlobalOrbitalPositionManager.RegisterOrbitalPositionInstance(m_OrbitalPosition); OnStart(); } private void OnDestroy() => GlobalOrbitalPositionManager.UnregisterOrbitalPositionInstance(m_OrbitalPosition); public abstract void OnStart(); }