217 lines
6.3 KiB
C#
217 lines
6.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class MoonOrbitJupiter : MonoBehaviour
|
|
{
|
|
public Transform jupiter;
|
|
|
|
public JupiterMoonType moonType = JupiterMoonType.Io;
|
|
public bool autoCalculateOrbit = true;
|
|
public float manualOrbitRadius = 10f;
|
|
|
|
public float orbitInclination = 0.04f;
|
|
public float startAngleDegrees = 0f;
|
|
|
|
public float timeScale = 10f;
|
|
|
|
public bool showDebugInfo = false;
|
|
|
|
private const float JUPITER_RADIUS_KM = 69911f;
|
|
|
|
private const float IO_RADIUS_KM = 1821f;
|
|
private const float IO_DISTANCE_KM = 421700f;
|
|
private const float IO_PERIOD_HOURS = 42.5f;
|
|
|
|
private const float EUROPA_RADIUS_KM = 1560f;
|
|
private const float EUROPA_DISTANCE_KM = 671100f;
|
|
private const float EUROPA_PERIOD_HOURS = 85.2f;
|
|
|
|
private const float GANYMEDE_RADIUS_KM = 2634f;
|
|
private const float GANYMEDE_DISTANCE_KM = 1070400f;
|
|
private const float GANYMEDE_PERIOD_HOURS = 171.7f;
|
|
|
|
private const float CALLISTO_RADIUS_KM = 2410f;
|
|
private const float CALLISTO_DISTANCE_KM = 1882700f;
|
|
private const float CALLISTO_PERIOD_HOURS = 400.5f;
|
|
|
|
private float orbitRadius;
|
|
private float angularSpeed;
|
|
private float currentAngle = 0f;
|
|
private float orbitCount = 0f;
|
|
private float debugTimer = 0f;
|
|
|
|
public enum JupiterMoonType
|
|
{
|
|
Io,
|
|
Europa,
|
|
Ganymede,
|
|
Callisto
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
if (jupiter == null)
|
|
{
|
|
jupiter = GameObject.Find("Jupiter")?.transform;
|
|
if (jupiter == null)
|
|
{
|
|
enabled = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
CalculateOrbit();
|
|
SetInitialPosition();
|
|
|
|
}
|
|
|
|
void CalculateOrbit()
|
|
{
|
|
float jupiterRadius = jupiter.localScale.x / 2f;
|
|
|
|
if (autoCalculateOrbit)
|
|
{
|
|
switch (moonType)
|
|
{
|
|
case JupiterMoonType.Io:
|
|
orbitRadius = jupiterRadius * (IO_DISTANCE_KM / JUPITER_RADIUS_KM);
|
|
angularSpeed = (2f * Mathf.PI / (IO_PERIOD_HOURS * 3600f)) * timeScale;
|
|
orbitInclination = 0.04f;
|
|
break;
|
|
|
|
case JupiterMoonType.Europa:
|
|
orbitRadius = jupiterRadius * (EUROPA_DISTANCE_KM / JUPITER_RADIUS_KM);
|
|
angularSpeed = (2f * Mathf.PI / (EUROPA_PERIOD_HOURS * 3600f)) * timeScale;
|
|
orbitInclination = 0.47f;
|
|
break;
|
|
|
|
case JupiterMoonType.Ganymede:
|
|
orbitRadius = jupiterRadius * (GANYMEDE_DISTANCE_KM / JUPITER_RADIUS_KM);
|
|
angularSpeed = (2f * Mathf.PI / (GANYMEDE_PERIOD_HOURS * 3600f)) * timeScale;
|
|
orbitInclination = 0.20f;
|
|
break;
|
|
|
|
case JupiterMoonType.Callisto:
|
|
orbitRadius = jupiterRadius * (CALLISTO_DISTANCE_KM / JUPITER_RADIUS_KM);
|
|
angularSpeed = (2f * Mathf.PI / (CALLISTO_PERIOD_HOURS * 3600f)) * timeScale;
|
|
orbitInclination = 0.51f;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
orbitRadius = manualOrbitRadius;
|
|
float period = GetPeriod() * 3600f;
|
|
angularSpeed = (2f * Mathf.PI / period) * timeScale;
|
|
}
|
|
}
|
|
|
|
float GetPeriod()
|
|
{
|
|
switch (moonType)
|
|
{
|
|
case JupiterMoonType.Io: return IO_PERIOD_HOURS;
|
|
case JupiterMoonType.Europa: return EUROPA_PERIOD_HOURS;
|
|
case JupiterMoonType.Ganymede: return GANYMEDE_PERIOD_HOURS;
|
|
case JupiterMoonType.Callisto: return CALLISTO_PERIOD_HOURS;
|
|
default: return IO_PERIOD_HOURS;
|
|
}
|
|
}
|
|
|
|
void SetInitialPosition()
|
|
{
|
|
currentAngle = startAngleDegrees * Mathf.Deg2Rad;
|
|
UpdatePosition();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (jupiter == 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 = jupiter.position + new Vector3(x, y, z);
|
|
}
|
|
|
|
void OnDrawGizmos()
|
|
{
|
|
if (jupiter == null) return;
|
|
|
|
Color gizmoColor = Color.white;
|
|
switch (moonType)
|
|
{
|
|
case JupiterMoonType.Io:
|
|
gizmoColor = new Color(1f, 0.9f, 0.3f, 0.5f);
|
|
break;
|
|
case JupiterMoonType.Europa:
|
|
gizmoColor = new Color(0.8f, 0.9f, 1f, 0.5f);
|
|
break;
|
|
case JupiterMoonType.Ganymede:
|
|
gizmoColor = new Color(0.7f, 0.6f, 0.5f, 0.5f);
|
|
break;
|
|
case JupiterMoonType.Callisto:
|
|
gizmoColor = new Color(0.5f, 0.5f, 0.5f, 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 jupiter.position + new Vector3(x, y, z);
|
|
}
|
|
}
|