MaximilianPs

Solar System Class

Jul 18th, 2024
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.45 KB | None | 0 0
  1. /* THis shit is designed to work with Space Combat Kit and with Space Graphics Toolkit.
  2. THis class sets rotates the planet by the current day/hour and the given Year.
  3. This also implement orbital moon.
  4. This shit won't let you reach any planet because the messy floating origin issue.
  5. This class will move any type of moon while the planets still on the same position.
  6. If anyone can fix this mess please let me know....
  7. Wishful thinking... it's like talking to the void....Cosmic. */
  8.  
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using UnityEngine;
  12. using VSX.FloatingOriginSystem;
  13. using SpaceGraphicsToolkit;
  14. using CW.Common;
  15.  
  16. namespace BrokenWings.SpaceSystem
  17. {
  18.     #region ---- SUB CLASSES -----------------------------------------
  19.  
  20.     [System.Serializable]
  21.     public class CelestialObjectData
  22.     {
  23.         public string quadrantName;
  24.         [Space]
  25.         [Header("Orbital Settings")]
  26.         public GameObject planet;
  27.         [Tooltip("Orbit period in Earth years")]
  28.         public float orbitPeriod;
  29.         public float revolutionSpeed;
  30.         public Moon[] moons;
  31.         [Space]
  32.         public List<SpaceSpawnPoint> spawnPoints = new List<SpaceSpawnPoint>();
  33.         [Space]
  34.         [Tooltip("The scene that must be loaded")]
  35.         public UnityEngine.Object sceneName;
  36.     }
  37.  
  38.     [System.Serializable]
  39.     public class Moon
  40.     {
  41.         public string name;
  42.         public string description;
  43.         public GameObject prefab;
  44.         [Space]
  45.         [Tooltip("in Meters")]
  46.         public float distance;
  47.         [Tooltip("In Hours")]
  48.         public float orbitPeriod;
  49.         public float revolutionSpeed;
  50.     }
  51.  
  52.     #endregion
  53.  
  54.     public class CelestialSystemManager : MonoBehaviour
  55.     {
  56.         public enum SpawnPointType
  57.         {
  58.             Player,
  59.             Enemy,
  60.             Generic
  61.         }
  62.  
  63.         [SerializeField] private int year = 2197;
  64.         [SerializeField] private List<CelestialObjectData> celestialBodies;
  65.        
  66.         [SerializeField] private float solarSystemRadius = 2000000f; // Raggio massimo del sistema solare in unità Unity
  67.         [SerializeField] private float maxDistance = 200000f; // Distanza massima desiderata in unità di Unity
  68.         [SerializeField] private float minDistance = 5000; // Distanza minima tra i corpi celesti
  69.         [SerializeField] private UnityEngine.Object emptySpaceScene;
  70.         [Space]
  71.         [SerializeField] private SgtFloatingCamera sgtCamera;
  72.         [SerializeField] private FloatingOriginManager sckManager;
  73.         [Space]
  74.         [SerializeField] private bool debugSystem = false;
  75.  
  76.         private System.DateTime inGameTime;
  77.         /// <summary>
  78.         /// The ingame current time
  79.         /// </summary>
  80.         public System.DateTime Time { get { return inGameTime; } }
  81.  
  82.         private void Awake()
  83.         {
  84.             InitializeCelestialSystem();
  85.             if (debugSystem) LogAllCelestialBodyPositions("After Initialization");
  86.         }
  87.  
  88.         private void InitializeCelestialSystem()
  89.         {
  90.             InitializeCelestialBody();
  91.         }
  92.  
  93.         private void InitializeCelestialBody()
  94.         {
  95.             System.DateTime currentTime = System.DateTime.Now;
  96.             inGameTime = new System.DateTime(year, currentTime.Month, currentTime.Day, currentTime.Hour, currentTime.Minute, currentTime.Second);
  97.  
  98.             // Posiziona il Sole al centro
  99.             PositionCelestialBody(celestialBodies[0].planet, Vector3.zero);
  100.  
  101.             for (int i = 1; i < celestialBodies.Count; i++)
  102.             {
  103.                 float distance = maxDistance * i;
  104.                 Vector3 position = CalculateCelestialBodyPosition(celestialBodies[i], inGameTime);
  105.  
  106.                 PositionCelestialBody(celestialBodies[i].planet, position);
  107.                 SetupRotation(celestialBodies[i].planet, celestialBodies[i].revolutionSpeed);
  108.  
  109.                 foreach (var moon in celestialBodies[i].moons)
  110.                 {
  111.                     SetupMoonOrbit(moon, celestialBodies[i].planet, moon.distance, moon.orbitPeriod);
  112.                 }
  113.             }
  114.         }
  115.  
  116.         /// <summary>
  117.         /// Given a Vector3 will move the given GameObject by using SgtPosition
  118.         /// </summary>
  119.         /// <param name="celestialBody">GameObject to move</param>
  120.         /// <param name="position">Vector3 coordinates</param>
  121.         private void PositionCelestialBody(GameObject celestialBody, Vector3 position)
  122.         {
  123.             SgtFloatingObject floatingObject = celestialBody.GetComponent<SgtFloatingObject>();
  124.             if (floatingObject == null) floatingObject = celestialBody.AddComponent<SgtFloatingObject>();
  125.  
  126.             floatingObject.Position = new SgtPosition(position);
  127.         }
  128.  
  129.         /// <summary>
  130.         /// Adds the component CwRotate and sets the rotation speed in hours.
  131.         /// </summary>
  132.         private void SetupRotation(GameObject celestialBody, float rotationPeriodHours)
  133.         {
  134.             if (rotationPeriodHours == 0) return;
  135.  
  136.             CwRotate rotate = celestialBody.GetComponent<CwRotate>();
  137.             if (rotate == null)
  138.                 rotate = celestialBody.AddComponent<CwRotate>();
  139.  
  140.             float angularVelocity = 360f / (rotationPeriodHours * 3600f);
  141.             rotate.AngularVelocity = new Vector3(0, angularVelocity, 0);
  142.             rotate.RelativeTo = Space.Self;
  143.         }
  144.  
  145.         /// <summary>
  146.         /// Sets a celestial body to orbit the specified coordinates.
  147.         /// </summary>
  148.         private void SetupMoonOrbit(Moon moon, GameObject planet, float orbitRadius, float orbitPeriodHours)
  149.         {
  150.             PositionCelestialBody(moon.prefab, planet.transform.position);
  151.  
  152.             SgtSimpleOrbit orbit = moon.prefab.GetComponent<SgtSimpleOrbit>();
  153.             if (orbit == null)orbit = moon.prefab.AddComponent<SgtSimpleOrbit>();
  154.  
  155.             // Planet non ha necessità di un controllo per SgtFloatingObject dato che è stato fatto in PositionCelestialBody
  156.             SgtFloatingObject floatingObject = planet.GetComponent<SgtFloatingObject>();
  157.            
  158.             if(debugSystem) Debug.Log($"{planet.name} position: {floatingObject.Position}");
  159.  
  160.             orbitRadius += GetPlanetRadius(planet);
  161.             orbit.Radius = orbitRadius;
  162.             orbit.Angle = CalculateMoonAngle(moon, inGameTime);
  163.             orbit.DegreesPerSecond = 360f / (orbitPeriodHours * 3600f);
  164.             orbit.Offset = planet.transform.InverseTransformPoint(moon.prefab.transform.position);
  165.         }
  166.  
  167.         private Vector3 CalculateCelestialBodyPosition(CelestialObjectData celestialBody, System.DateTime time)
  168.         {
  169.             float distanceFromSun = maxDistance * celestialBodies.IndexOf(celestialBody);
  170.             float orbitalPeriod = celestialBody.orbitPeriod * 365.25f; // Converti anni in giorni
  171.             float angularSpeed = 360f / orbitalPeriod;
  172.  
  173.             System.TimeSpan timeDifference = time - new System.DateTime(year, 1, 1);
  174.             float totalDays = (float)timeDifference.TotalDays;
  175.  
  176.             float angle = (angularSpeed * totalDays) % 360f;
  177.             float radians = angle * Mathf.Deg2Rad;
  178.  
  179.             float x = distanceFromSun * Mathf.Cos(radians);
  180.             float z = distanceFromSun * Mathf.Sin(radians);
  181.  
  182.             return new Vector3(x, 0, z);
  183.         }
  184.  
  185.         private float CalculateMoonAngle(Moon moon, System.DateTime time)
  186.         {
  187.             float orbitalPeriod = moon.orbitPeriod / 24f; // Converti ore in giorni
  188.             float angularSpeed = 360f / orbitalPeriod;
  189.  
  190.             System.TimeSpan timeDifference = time - new System.DateTime(year, 1, 1);
  191.             float totalDays = (float)timeDifference.TotalDays;
  192.  
  193.             float angle = (angularSpeed * totalDays) % 360f;
  194.             return angle;
  195.         }
  196.  
  197.         private float GetPlanetRadius(GameObject planet)
  198.         {
  199.             Renderer renderer = planet.GetComponent<Renderer>();
  200.             if (renderer != null)
  201.             {
  202.                 return renderer.bounds.extents.magnitude;
  203.             }
  204.  
  205.             return 5000f; // Valore di default se non si trova un renderer
  206.         }
  207.  
  208.         #region --- PUBLIC METHOD ------------------------------------------------------
  209.  
  210.             // Metodi pubblici per l'accesso ai dati dei corpi celesti
  211.             public GameObject FindCelestialBodyByName(string name)
  212.         {
  213.             foreach (var item in celestialBodies)
  214.             {
  215.                 if (item.quadrantName == name) return item.planet;
  216.                 foreach (var moon in item.moons)
  217.                 {
  218.                     if (moon.name == name) return moon.prefab;
  219.                 }
  220.             }
  221.             return null;
  222.         }
  223.  
  224.         public CelestialObjectData GetCelestialObjectDataByName(string name)
  225.         {
  226.             return celestialBodies.FirstOrDefault(obj => obj.quadrantName == name);
  227.         }
  228.  
  229.        
  230.         public List<CelestialObjectData> GetCelestialBodies()
  231.         {
  232.             return celestialBodies;
  233.         }
  234.  
  235.         public Transform GetSpawnPointTransform(string celestialBodyName, string spawnPointName)
  236.         {
  237.             CelestialObjectData celestialBody = celestialBodies.FirstOrDefault(obj => obj.quadrantName == celestialBodyName);
  238.  
  239.             if (celestialBody != null)
  240.             {
  241.                 return celestialBody.spawnPoints.FirstOrDefault(sp => sp.GetComponent<SpaceSpawnPoint>().spawnPointName == spawnPointName)?.transform;
  242.             }
  243.  
  244.             Debug.LogWarning($"CelestialBody {celestialBodyName} or SpawnPoint {spawnPointName} not found");
  245.             return null;
  246.         }
  247.  
  248.         public Vector3 GetGlobalSpawnCoordinates(string celestialBodyName, string spawnPointName)
  249.         {
  250.             CelestialObjectData celestialBody = GetCelestialObjectDataByName(celestialBodyName);
  251.             if (celestialBody != null)
  252.             {
  253.                 // Cerca lo spawn point nel pianeta
  254.                 SpaceSpawnPoint spawnPoint = celestialBody.spawnPoints.Find(sp => sp.spawnPointName == spawnPointName);
  255.                 if (spawnPoint != null)
  256.                 {
  257.                     return spawnPoint.transform.position;
  258.                 }
  259.  
  260.                 // Se non trovato nel pianeta, cerca nelle lune
  261.                 foreach (Moon moon in celestialBody.moons)
  262.                 {
  263.                     spawnPoint = moon.prefab.GetComponentInChildren<SpaceSpawnPoint>(true);
  264.                     if (spawnPoint != null && spawnPoint.spawnPointName == spawnPointName)
  265.                     {
  266.                         return spawnPoint.transform.position;
  267.                     }
  268.                 }
  269.             }
  270.  
  271.             Debug.LogWarning($"Could not find spawn point {spawnPointName} for celestial body {celestialBodyName}");
  272.             return Vector3.zero;
  273.         }
  274.  
  275.         public string GetCellByName(string planetName)
  276.         {
  277.             for (int i = 0; celestialBodies.Count > 0; i++)
  278.             {
  279.                 if (celestialBodies[i].quadrantName == planetName)
  280.                     return celestialBodies[i].sceneName.name;
  281.             }
  282.  
  283.             return emptySpaceScene.name;
  284.         }
  285.  
  286.         public float GetBodySizeByName(string name)
  287.         {
  288.             GameObject target = FindCelestialBodyByName(name);
  289.             if (target == null)
  290.             {
  291.                 Debug.LogWarning($"Celestial body '{name}' not found.");
  292.                 return 0f;
  293.             }
  294.  
  295.             MeshFilter meshFilter = target.GetComponent<MeshFilter>();
  296.             Vector3 finalSize = Vector3.zero;
  297.  
  298.             if (meshFilter != null && meshFilter.sharedMesh != null)
  299.             {
  300.                 Vector3 meshSize = meshFilter.sharedMesh.bounds.size;
  301.                 finalSize = Vector3.Scale(meshSize, target.transform.lossyScale);
  302.                 return Mathf.Max(finalSize.x, finalSize.y, finalSize.z);
  303.             }
  304.  
  305.             Collider collider = target.GetComponent<Collider>();
  306.             if (collider != null)
  307.             {
  308.                 if (collider is BoxCollider boxCollider)
  309.                 {
  310.                     finalSize = Vector3.Scale(boxCollider.size, target.transform.lossyScale);
  311.                     return Mathf.Max(finalSize.x, finalSize.y, finalSize.z);
  312.                 }
  313.                 if (collider is SphereCollider sphereCollider)
  314.                 {
  315.                     finalSize = Vector3.one * (sphereCollider.radius * 2 * target.transform.lossyScale.x);
  316.                     return Mathf.Max(finalSize.x, finalSize.y, finalSize.z);
  317.                 }
  318.                 if (collider is CapsuleCollider capsuleCollider)
  319.                 {
  320.                     finalSize = new Vector3(
  321.                         capsuleCollider.radius * 2,
  322.                         capsuleCollider.height,
  323.                         capsuleCollider.radius * 2
  324.                     ) * target.transform.lossyScale.x;
  325.                     return Mathf.Max(finalSize.x, finalSize.y, finalSize.z);
  326.                 }
  327.             }
  328.  
  329.             Debug.LogWarning($"Unable to determine size for '{name}'. No suitable component found.");
  330.             return 0f;
  331.         }
  332.  
  333.         #endregion
  334.  
  335.         #region --- GIZMO & DEBUG ------------------------------------------------------
  336.  
  337.         private void LogAllCelestialBodyPositions(string context)
  338.         {
  339.             Debug.Log($"--- Logging Celestial Body Positions: {context} ---");
  340.             foreach (var celestialBody in celestialBodies)
  341.             {
  342.                 Vector3 position = celestialBody.planet.transform.position;
  343.                 Debug.Log($"{celestialBody.quadrantName} position: {position}");
  344.  
  345.                 foreach (var moon in celestialBody.moons)
  346.                 {
  347.                     Vector3 moonPosition = moon.prefab.transform.position;
  348.                     Debug.Log($"  Moon {moon.name} position: {moonPosition}");
  349.                 }
  350.             }
  351.         }
  352.        
  353.         private void LogAllCelestialBodyPositions()
  354.         {
  355.             foreach (var celestialBody in celestialBodies)
  356.             {
  357.                 Vector3 position = celestialBody.planet.transform.position;
  358.                 Debug.Log($"{celestialBody.quadrantName} position: {position}");
  359.  
  360.                 foreach (var moon in celestialBody.moons)
  361.                 {
  362.                     Vector3 moonPosition = moon.prefab.transform.position;
  363.                     Debug.Log($"  Moon {moon.name} position: {moonPosition}");
  364.                 }
  365.             }
  366.         }
  367.  
  368.         #endregion
  369.     }
  370. }
  371.  
Advertisement
Add Comment
Please, Sign In to add comment