using System.Collections; using System.Collections.Generic; using UnityEngine; public class MoonOrbitSaturn : MonoBehaviour { public Transform saturn; public SaturnMoonType moonType = SaturnMoonType.Mimas; public bool autoCalculateOrbit = true; public float manualOrbitRadius = 10f; public float orbitInclination = 0f; public float startAngleDegrees = 0f; public float timeScale = 10f; public float orbitScaleMultiplier = 4f; public bool showDebugInfo = false; private const float SATURN_RADIUS_KM = 58232f; private const float MIMAS_DISTANCE_KM = 185539f; private const float MIMAS_PERIOD_HOURS = 22.6f; private const float ENCELADUS_DISTANCE_KM = 237948f; private const float ENCELADUS_PERIOD_HOURS = 32.9f; private const float TETHYS_DISTANCE_KM = 294619f; private const float TETHYS_PERIOD_HOURS = 45.3f; private const float DIONE_DISTANCE_KM = 377396f; private const float DIONE_PERIOD_HOURS = 65.7f; private const float RHEA_DISTANCE_KM = 527108f; private const float RHEA_PERIOD_HOURS = 108.4f; private const float TITAN_DISTANCE_KM = 1221870f; private const float TITAN_PERIOD_HOURS = 382.7f; private const float IAPETUS_DISTANCE_KM = 3560820f; private const float IAPETUS_PERIOD_HOURS = 1903.7f; private float orbitRadius; private float angularSpeed; private float currentAngle; public enum SaturnMoonType { Mimas, Enceladus, Tethys, Dione, Rhea, Titan, Iapetus } void Start() { if (saturn == null) { saturn = GameObject.Find("Saturn")?.transform; if (saturn == null) { enabled = false; return; } } CalculateOrbit(); SetInitialPosition(); } void CalculateOrbit() { float saturnRadius = saturn.localScale.x / 2f; if (autoCalculateOrbit) { switch (moonType) { case SaturnMoonType.Mimas: orbitRadius = saturnRadius * (MIMAS_DISTANCE_KM / SATURN_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (MIMAS_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 1.57f; break; case SaturnMoonType.Enceladus: orbitRadius = saturnRadius * (ENCELADUS_DISTANCE_KM / SATURN_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (ENCELADUS_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 0.02f; break; case SaturnMoonType.Tethys: orbitRadius = saturnRadius * (TETHYS_DISTANCE_KM / SATURN_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (TETHYS_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 1.09f; break; case SaturnMoonType.Dione: orbitRadius = saturnRadius * (DIONE_DISTANCE_KM / SATURN_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (DIONE_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 0.02f; break; case SaturnMoonType.Rhea: orbitRadius = saturnRadius * (RHEA_DISTANCE_KM / SATURN_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (RHEA_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 0.35f; break; case SaturnMoonType.Titan: orbitRadius = saturnRadius * (TITAN_DISTANCE_KM / SATURN_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (TITAN_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 0.33f; break; case SaturnMoonType.Iapetus: orbitRadius = saturnRadius * (IAPETUS_DISTANCE_KM / SATURN_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (IAPETUS_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 15.47f; break; } orbitRadius *= orbitScaleMultiplier; } else { orbitRadius = manualOrbitRadius; float period = GetPeriod() * 3600f; angularSpeed = (2f * Mathf.PI / period) * timeScale; } } float GetPeriod() { switch (moonType) { case SaturnMoonType.Mimas: return MIMAS_PERIOD_HOURS; case SaturnMoonType.Enceladus: return ENCELADUS_PERIOD_HOURS; case SaturnMoonType.Tethys: return TETHYS_PERIOD_HOURS; case SaturnMoonType.Dione: return DIONE_PERIOD_HOURS; case SaturnMoonType.Rhea: return RHEA_PERIOD_HOURS; case SaturnMoonType.Titan: return TITAN_PERIOD_HOURS; case SaturnMoonType.Iapetus: return IAPETUS_PERIOD_HOURS; default: return MIMAS_PERIOD_HOURS; } } void SetInitialPosition() { currentAngle = startAngleDegrees * Mathf.Deg2Rad; UpdatePosition(); } void Update() { currentAngle += angularSpeed * Time.deltaTime; UpdatePosition(); } void UpdatePosition() { float x = Mathf.Cos(currentAngle) * orbitRadius; float z = Mathf.Sin(currentAngle) * orbitRadius; float inclinationRad = orbitInclination * Mathf.Deg2Rad; float y = z * Mathf.Sin(inclinationRad); z = z * Mathf.Cos(inclinationRad); transform.position = saturn.position + new Vector3(x, y, z); } void OnDrawGizmos() { if (saturn == null) return; Gizmos.color = Color.white; int segments = 64; Vector3 prevPos = GetOrbitPoint(0f); for (int i = 1; i <= segments; i++) { Vector3 newPos = GetOrbitPoint(i * 2f * Mathf.PI / segments); Gizmos.DrawLine(prevPos, newPos); prevPos = newPos; } } Vector3 GetOrbitPoint(float angle) { float x = Mathf.Cos(angle) * orbitRadius; float z = Mathf.Sin(angle) * orbitRadius; float inclinationRad = orbitInclination * Mathf.Deg2Rad; float y = z * Mathf.Sin(inclinationRad); z = z * Mathf.Cos(inclinationRad); return saturn.position + new Vector3(x, y, z); } }