Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* THis shit is designed to work with Space Combat Kit and with Space Graphics Toolkit.
- THis class sets rotates the planet by the current day/hour and the given Year.
- This also implement orbital moon.
- This shit won't let you reach any planet because the messy floating origin issue.
- This class will move any type of moon while the planets still on the same position.
- If anyone can fix this mess please let me know....
- Wishful thinking... it's like talking to the void....Cosmic. */
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using VSX.FloatingOriginSystem;
- using SpaceGraphicsToolkit;
- using CW.Common;
- namespace BrokenWings.SpaceSystem
- {
- #region ---- SUB CLASSES -----------------------------------------
- [System.Serializable]
- public class CelestialObjectData
- {
- public string quadrantName;
- [Space]
- [Header("Orbital Settings")]
- public GameObject planet;
- [Tooltip("Orbit period in Earth years")]
- public float orbitPeriod;
- public float revolutionSpeed;
- public Moon[] moons;
- [Space]
- public List<SpaceSpawnPoint> spawnPoints = new List<SpaceSpawnPoint>();
- [Space]
- [Tooltip("The scene that must be loaded")]
- public UnityEngine.Object sceneName;
- }
- [System.Serializable]
- public class Moon
- {
- public string name;
- public string description;
- public GameObject prefab;
- [Space]
- [Tooltip("in Meters")]
- public float distance;
- [Tooltip("In Hours")]
- public float orbitPeriod;
- public float revolutionSpeed;
- }
- #endregion
- public class CelestialSystemManager : MonoBehaviour
- {
- public enum SpawnPointType
- {
- Player,
- Enemy,
- Generic
- }
- [SerializeField] private int year = 2197;
- [SerializeField] private List<CelestialObjectData> celestialBodies;
- [SerializeField] private float solarSystemRadius = 2000000f; // Raggio massimo del sistema solare in unità Unity
- [SerializeField] private float maxDistance = 200000f; // Distanza massima desiderata in unità di Unity
- [SerializeField] private float minDistance = 5000; // Distanza minima tra i corpi celesti
- [SerializeField] private UnityEngine.Object emptySpaceScene;
- [Space]
- [SerializeField] private SgtFloatingCamera sgtCamera;
- [SerializeField] private FloatingOriginManager sckManager;
- [Space]
- [SerializeField] private bool debugSystem = false;
- private System.DateTime inGameTime;
- /// <summary>
- /// The ingame current time
- /// </summary>
- public System.DateTime Time { get { return inGameTime; } }
- private void Awake()
- {
- InitializeCelestialSystem();
- if (debugSystem) LogAllCelestialBodyPositions("After Initialization");
- }
- private void InitializeCelestialSystem()
- {
- InitializeCelestialBody();
- }
- private void InitializeCelestialBody()
- {
- System.DateTime currentTime = System.DateTime.Now;
- inGameTime = new System.DateTime(year, currentTime.Month, currentTime.Day, currentTime.Hour, currentTime.Minute, currentTime.Second);
- // Posiziona il Sole al centro
- PositionCelestialBody(celestialBodies[0].planet, Vector3.zero);
- for (int i = 1; i < celestialBodies.Count; i++)
- {
- float distance = maxDistance * i;
- Vector3 position = CalculateCelestialBodyPosition(celestialBodies[i], inGameTime);
- PositionCelestialBody(celestialBodies[i].planet, position);
- SetupRotation(celestialBodies[i].planet, celestialBodies[i].revolutionSpeed);
- foreach (var moon in celestialBodies[i].moons)
- {
- SetupMoonOrbit(moon, celestialBodies[i].planet, moon.distance, moon.orbitPeriod);
- }
- }
- }
- /// <summary>
- /// Given a Vector3 will move the given GameObject by using SgtPosition
- /// </summary>
- /// <param name="celestialBody">GameObject to move</param>
- /// <param name="position">Vector3 coordinates</param>
- private void PositionCelestialBody(GameObject celestialBody, Vector3 position)
- {
- SgtFloatingObject floatingObject = celestialBody.GetComponent<SgtFloatingObject>();
- if (floatingObject == null) floatingObject = celestialBody.AddComponent<SgtFloatingObject>();
- floatingObject.Position = new SgtPosition(position);
- }
- /// <summary>
- /// Adds the component CwRotate and sets the rotation speed in hours.
- /// </summary>
- private void SetupRotation(GameObject celestialBody, float rotationPeriodHours)
- {
- if (rotationPeriodHours == 0) return;
- CwRotate rotate = celestialBody.GetComponent<CwRotate>();
- if (rotate == null)
- rotate = celestialBody.AddComponent<CwRotate>();
- float angularVelocity = 360f / (rotationPeriodHours * 3600f);
- rotate.AngularVelocity = new Vector3(0, angularVelocity, 0);
- rotate.RelativeTo = Space.Self;
- }
- /// <summary>
- /// Sets a celestial body to orbit the specified coordinates.
- /// </summary>
- private void SetupMoonOrbit(Moon moon, GameObject planet, float orbitRadius, float orbitPeriodHours)
- {
- PositionCelestialBody(moon.prefab, planet.transform.position);
- SgtSimpleOrbit orbit = moon.prefab.GetComponent<SgtSimpleOrbit>();
- if (orbit == null)orbit = moon.prefab.AddComponent<SgtSimpleOrbit>();
- // Planet non ha necessità di un controllo per SgtFloatingObject dato che è stato fatto in PositionCelestialBody
- SgtFloatingObject floatingObject = planet.GetComponent<SgtFloatingObject>();
- if(debugSystem) Debug.Log($"{planet.name} position: {floatingObject.Position}");
- orbitRadius += GetPlanetRadius(planet);
- orbit.Radius = orbitRadius;
- orbit.Angle = CalculateMoonAngle(moon, inGameTime);
- orbit.DegreesPerSecond = 360f / (orbitPeriodHours * 3600f);
- orbit.Offset = planet.transform.InverseTransformPoint(moon.prefab.transform.position);
- }
- private Vector3 CalculateCelestialBodyPosition(CelestialObjectData celestialBody, System.DateTime time)
- {
- float distanceFromSun = maxDistance * celestialBodies.IndexOf(celestialBody);
- float orbitalPeriod = celestialBody.orbitPeriod * 365.25f; // Converti anni in giorni
- float angularSpeed = 360f / orbitalPeriod;
- System.TimeSpan timeDifference = time - new System.DateTime(year, 1, 1);
- float totalDays = (float)timeDifference.TotalDays;
- float angle = (angularSpeed * totalDays) % 360f;
- float radians = angle * Mathf.Deg2Rad;
- float x = distanceFromSun * Mathf.Cos(radians);
- float z = distanceFromSun * Mathf.Sin(radians);
- return new Vector3(x, 0, z);
- }
- private float CalculateMoonAngle(Moon moon, System.DateTime time)
- {
- float orbitalPeriod = moon.orbitPeriod / 24f; // Converti ore in giorni
- float angularSpeed = 360f / orbitalPeriod;
- System.TimeSpan timeDifference = time - new System.DateTime(year, 1, 1);
- float totalDays = (float)timeDifference.TotalDays;
- float angle = (angularSpeed * totalDays) % 360f;
- return angle;
- }
- private float GetPlanetRadius(GameObject planet)
- {
- Renderer renderer = planet.GetComponent<Renderer>();
- if (renderer != null)
- {
- return renderer.bounds.extents.magnitude;
- }
- return 5000f; // Valore di default se non si trova un renderer
- }
- #region --- PUBLIC METHOD ------------------------------------------------------
- // Metodi pubblici per l'accesso ai dati dei corpi celesti
- public GameObject FindCelestialBodyByName(string name)
- {
- foreach (var item in celestialBodies)
- {
- if (item.quadrantName == name) return item.planet;
- foreach (var moon in item.moons)
- {
- if (moon.name == name) return moon.prefab;
- }
- }
- return null;
- }
- public CelestialObjectData GetCelestialObjectDataByName(string name)
- {
- return celestialBodies.FirstOrDefault(obj => obj.quadrantName == name);
- }
- public List<CelestialObjectData> GetCelestialBodies()
- {
- return celestialBodies;
- }
- public Transform GetSpawnPointTransform(string celestialBodyName, string spawnPointName)
- {
- CelestialObjectData celestialBody = celestialBodies.FirstOrDefault(obj => obj.quadrantName == celestialBodyName);
- if (celestialBody != null)
- {
- return celestialBody.spawnPoints.FirstOrDefault(sp => sp.GetComponent<SpaceSpawnPoint>().spawnPointName == spawnPointName)?.transform;
- }
- Debug.LogWarning($"CelestialBody {celestialBodyName} or SpawnPoint {spawnPointName} not found");
- return null;
- }
- public Vector3 GetGlobalSpawnCoordinates(string celestialBodyName, string spawnPointName)
- {
- CelestialObjectData celestialBody = GetCelestialObjectDataByName(celestialBodyName);
- if (celestialBody != null)
- {
- // Cerca lo spawn point nel pianeta
- SpaceSpawnPoint spawnPoint = celestialBody.spawnPoints.Find(sp => sp.spawnPointName == spawnPointName);
- if (spawnPoint != null)
- {
- return spawnPoint.transform.position;
- }
- // Se non trovato nel pianeta, cerca nelle lune
- foreach (Moon moon in celestialBody.moons)
- {
- spawnPoint = moon.prefab.GetComponentInChildren<SpaceSpawnPoint>(true);
- if (spawnPoint != null && spawnPoint.spawnPointName == spawnPointName)
- {
- return spawnPoint.transform.position;
- }
- }
- }
- Debug.LogWarning($"Could not find spawn point {spawnPointName} for celestial body {celestialBodyName}");
- return Vector3.zero;
- }
- public string GetCellByName(string planetName)
- {
- for (int i = 0; celestialBodies.Count > 0; i++)
- {
- if (celestialBodies[i].quadrantName == planetName)
- return celestialBodies[i].sceneName.name;
- }
- return emptySpaceScene.name;
- }
- public float GetBodySizeByName(string name)
- {
- GameObject target = FindCelestialBodyByName(name);
- if (target == null)
- {
- Debug.LogWarning($"Celestial body '{name}' not found.");
- return 0f;
- }
- MeshFilter meshFilter = target.GetComponent<MeshFilter>();
- Vector3 finalSize = Vector3.zero;
- if (meshFilter != null && meshFilter.sharedMesh != null)
- {
- Vector3 meshSize = meshFilter.sharedMesh.bounds.size;
- finalSize = Vector3.Scale(meshSize, target.transform.lossyScale);
- return Mathf.Max(finalSize.x, finalSize.y, finalSize.z);
- }
- Collider collider = target.GetComponent<Collider>();
- if (collider != null)
- {
- if (collider is BoxCollider boxCollider)
- {
- finalSize = Vector3.Scale(boxCollider.size, target.transform.lossyScale);
- return Mathf.Max(finalSize.x, finalSize.y, finalSize.z);
- }
- if (collider is SphereCollider sphereCollider)
- {
- finalSize = Vector3.one * (sphereCollider.radius * 2 * target.transform.lossyScale.x);
- return Mathf.Max(finalSize.x, finalSize.y, finalSize.z);
- }
- if (collider is CapsuleCollider capsuleCollider)
- {
- finalSize = new Vector3(
- capsuleCollider.radius * 2,
- capsuleCollider.height,
- capsuleCollider.radius * 2
- ) * target.transform.lossyScale.x;
- return Mathf.Max(finalSize.x, finalSize.y, finalSize.z);
- }
- }
- Debug.LogWarning($"Unable to determine size for '{name}'. No suitable component found.");
- return 0f;
- }
- #endregion
- #region --- GIZMO & DEBUG ------------------------------------------------------
- private void LogAllCelestialBodyPositions(string context)
- {
- Debug.Log($"--- Logging Celestial Body Positions: {context} ---");
- foreach (var celestialBody in celestialBodies)
- {
- Vector3 position = celestialBody.planet.transform.position;
- Debug.Log($"{celestialBody.quadrantName} position: {position}");
- foreach (var moon in celestialBody.moons)
- {
- Vector3 moonPosition = moon.prefab.transform.position;
- Debug.Log($" Moon {moon.name} position: {moonPosition}");
- }
- }
- }
- private void LogAllCelestialBodyPositions()
- {
- foreach (var celestialBody in celestialBodies)
- {
- Vector3 position = celestialBody.planet.transform.position;
- Debug.Log($"{celestialBody.quadrantName} position: {position}");
- foreach (var moon in celestialBody.moons)
- {
- Vector3 moonPosition = moon.prefab.transform.position;
- Debug.Log($" Moon {moon.name} position: {moonPosition}");
- }
- }
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment