Files
ScienceLab.TypesOfMotion/Assets/Scripts/MoonOrbitUranus.cs
2026-02-18 00:08:49 +02:00

231 lines
6.9 KiB
C#

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);
}
}