using System.Collections; using System.Collections.Generic; using UnityEngine; public class MoonOrbitUranus : MonoBehaviour { public Transform uranus; public UranusMoonType moonType = UranusMoonType.Miranda; public bool autoCalculateOrbit = true; public float manualOrbitRadius = 10f; public float orbitInclination = 4.34f; public float startAngleDegrees = 0f; public float timeScale = 10f; public bool showDebugInfo = false; private const float URANUS_RADIUS_KM = 25362f; private const float MIRANDA_RADIUS_KM = 236f; private const float MIRANDA_DISTANCE_KM = 129900f; private const float MIRANDA_PERIOD_HOURS = 33.9f; private const float ARIEL_RADIUS_KM = 579f; private const float ARIEL_DISTANCE_KM = 190900f; private const float ARIEL_PERIOD_HOURS = 60.5f; private const float UMBRIEL_RADIUS_KM = 585f; private const float UMBRIEL_DISTANCE_KM = 266000f; private const float UMBRIEL_PERIOD_HOURS = 99.5f; private const float TITANIA_RADIUS_KM = 789f; private const float TITANIA_DISTANCE_KM = 436300f; private const float TITANIA_PERIOD_HOURS = 209.0f; private const float OBERON_RADIUS_KM = 761f; private const float OBERON_DISTANCE_KM = 583500f; private const float OBERON_PERIOD_HOURS = 323.1f; private float orbitRadius; private float angularSpeed; private float currentAngle = 0f; private float orbitCount = 0f; private float debugTimer = 0f; public enum UranusMoonType { Miranda, Ariel, Umbriel, Titania, Oberon } void Start() { if (uranus == null) { uranus = GameObject.Find("Uranus")?.transform; if (uranus == null) { enabled = false; return; } } CalculateOrbit(); SetInitialPosition(); } void CalculateOrbit() { float uranusRadius = uranus.localScale.x / 2f; if (autoCalculateOrbit) { switch (moonType) { case UranusMoonType.Miranda: orbitRadius = uranusRadius * (MIRANDA_DISTANCE_KM / URANUS_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (MIRANDA_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 4.34f; break; case UranusMoonType.Ariel: orbitRadius = uranusRadius * (ARIEL_DISTANCE_KM / URANUS_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (ARIEL_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 0.04f; break; case UranusMoonType.Umbriel: orbitRadius = uranusRadius * (UMBRIEL_DISTANCE_KM / URANUS_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (UMBRIEL_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 0.13f; break; case UranusMoonType.Titania: orbitRadius = uranusRadius * (TITANIA_DISTANCE_KM / URANUS_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (TITANIA_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 0.08f; break; case UranusMoonType.Oberon: orbitRadius = uranusRadius * (OBERON_DISTANCE_KM / URANUS_RADIUS_KM); angularSpeed = (2f * Mathf.PI / (OBERON_PERIOD_HOURS * 3600f)) * timeScale; orbitInclination = 0.07f; break; } } else { orbitRadius = manualOrbitRadius; float period = GetPeriod() * 3600f; angularSpeed = (2f * Mathf.PI / period) * timeScale; } } float GetPeriod() { switch (moonType) { case UranusMoonType.Miranda: return MIRANDA_PERIOD_HOURS; case UranusMoonType.Ariel: return ARIEL_PERIOD_HOURS; case UranusMoonType.Umbriel: return UMBRIEL_PERIOD_HOURS; case UranusMoonType.Titania: return TITANIA_PERIOD_HOURS; case UranusMoonType.Oberon: return OBERON_PERIOD_HOURS; default: return MIRANDA_PERIOD_HOURS; } } void SetInitialPosition() { currentAngle = startAngleDegrees * Mathf.Deg2Rad; UpdatePosition(); } void Update() { if (uranus == null) return; currentAngle += angularSpeed * Time.deltaTime; if (currentAngle >= 2f * Mathf.PI) { currentAngle -= 2f * Mathf.PI; orbitCount++; if (showDebugInfo) { Debug.Log(moonType + " orbit " + orbitCount); } } UpdatePosition(); if (showDebugInfo) { debugTimer += Time.deltaTime; if (debugTimer >= 10f) { debugTimer = 0f; float progress = (currentAngle / (2f * Mathf.PI)) * 100f; Debug.Log(moonType + ": R=" + orbitRadius.ToString("F2") + " P=" + progress.ToString("F1") + "%"); } } } 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 = uranus.position + new Vector3(x, y, z); } void OnDrawGizmos() { if (uranus == null) return; Color gizmoColor = Color.white; switch (moonType) { case UranusMoonType.Miranda: gizmoColor = new Color(0.9f, 0.85f, 0.8f, 0.5f); break; case UranusMoonType.Ariel: gizmoColor = new Color(0.95f, 0.95f, 0.9f, 0.5f); break; case UranusMoonType.Umbriel: gizmoColor = new Color(0.4f, 0.4f, 0.4f, 0.5f); break; case UranusMoonType.Titania: gizmoColor = new Color(0.8f, 0.75f, 0.7f, 0.5f); break; case UranusMoonType.Oberon: gizmoColor = new Color(0.7f, 0.7f, 0.65f, 0.5f); break; } Gizmos.color = gizmoColor; int segments = 64; Vector3 prevPos = GetOrbitPoint(0); 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 uranus.position + new Vector3(x, y, z); } }