Help with solar system script please? Parenting issues.

Hi

I am creating a procedural solar system that spawns from script when you click on a star.

Now I want two different solar systems to spawn…one micro Solar System and one macro Solar System…both solar Systems are exactly the same but just at different scales. the micro Solar System is parented under the Micro game object and the macro solar system is parented under the Macro Solar System

You can see an example of this in the screenshot below:

The script that achieves this is written like so and it works fine but I just have one little hiccup with the moons that I am hoping someone here will be able to help me solve.

void Start() {
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            nameGenerator = GetComponent<Lexic.NameGenerator>();
            nameGenerator.namesSourceClass = "Lexic.FantasyFemaleNames2";
            nameGenerator.Initialise();

            //Generate Planets
            GameObject microParent = new GameObject("Micro");
            GameObject macroParent = new GameObject("Macro");

            int planets = Random.Range(0, numberOfPlanets);
            int moons = Random.Range(0, numberOfMoons);
            int moonsTotal = 0;
            for (int i=0; i<planets; i++) {
                GameObject planet = GenerateBody(
                
                     ////this is where the micro Solar System is parented too
                    microParent,
                    ////this is where the macro Solar System is parented too
                    macroParent
                    "Planet " + nameGenerator.GetNextRandomName(),
                    planetColor,
                    planetSettings.coloursStartRange,
                    planetSettings.coloursEndRange,
                    planetEccentricityRange,
                    planetDistanceRange,
                    planetSizeRange,
                    planetSettings.heightScale,
                    planetSettings.startValueDistance,
                    planetSettings.detailDistances,
                    planetSettings.calculateMsds,
                    planetSettings.detailMsds,
                    planetSettings.colliders,
                    PlanetType.Terra
                );

            
                //Generate Moons
            
                for (int j=0; j<moons; j++) {
                        GenerateBody(
                     ////this is where the micro Moon is parented too
                        microPlanet,
                     ////this is where I am trying to get the macro Moon parented too
                        macroPlanet,
                        "Moon " + nameGenerator.GetNextRandomName(),
                        moonColor,
                        moonSettings.coloursStartRange,
                        moonSettings.coloursEndRange,
                        Vector2.zero, //moons have a circular orbit
                        moonDistanceRange,
                        moonSizeRange,
                        planetSettings.heightScale,
                        planetSettings.startValueDistance,
                        planetSettings.detailDistances,
                        planetSettings.calculateMsds,
                        planetSettings.detailMsds,
                        planetSettings.colliders,
                        PlanetType.Lunar
                    );
                }
                moonsTotal += moons;
            
            }
            //Generate Comets
            int comets = Random.Range(0, numberOfComets);
            for (int k=0; k<comets; k++) {
                GenerateBody(

                    microParent,
                    macroParent,
                    "Planet " + nameGenerator.GetNextRandomName(),
                    cometColor,
                    cometSettings.coloursStartRange,
                    cometSettings.coloursEndRange,
                    cometEccentricityRange,
                    cometDistanceRange,
                    cometSizeRange,
                    cometSettings.heightScale,
                    cometSettings.startValueDistance,
                    cometSettings.detailDistances,
                    cometSettings.calculateMsds,
                    cometSettings.detailMsds,
                    cometSettings.colliders,
                    PlanetType.Comet

                );
            }


            macroParent.transform.parent = gameObject.transform;
            macroParent.transform.localPosition = Vector3.zero;
            microParent.transform.parent = gameObject.transform;
            microParent.transform.localPosition = Vector3.zero;

            watch.Stop();
            Debug.Log(
                string.Format(
                    "Generated {0} planets, {1} moons, and {2} comets in {3}ms",
                    planets, moonsTotal, comets, watch.ElapsedMilliseconds
                )
            );
        }

As you can see here in this screenshot the moons are not quite parenting properly for example Orbit Moon Betharath should be a child of Orbit Planet Porath, both moons should be children of the planet but instead Moon Betharath is a child of the other moon - Orbit Mooon Arigakari…

How do I get both moons to be children of Orbit Planet Porath?

This is part of the script where the planets generate their bodies.

GameObject GenerateBody(GameObject microParent, GameObject macroParent, string name, Color color, Color32[] colourStartRange, Color32[] colourEndRange, Vector2 eccentricityRange, Vector2 distanceRange, Vector2 sizeRange, float heightScale, float startValue, float[] detailDistances, bool calculateMsds, float[] detailMsds, bool[] generateColliders, PlanetType planetType)
        {
      
     
            GameObject orbitObj = new GameObject("Orbit " + name);
           ////this is where I am parenting
            orbitObj.transform.parent = microParent.transform;
            orbitObj.transform.localPosition = Vector3.zero;
            microPlanet = orbitObj;

            //add an orbit component, and fill it out
            CelestialOrbit orbit = orbitObj.AddComponent<CelestialOrbit>();
            CelestialOrbitPath orbitPath = orbitObj.AddComponent<CelestialOrbitPath>();
            line = orbitObj.GetComponent<LineRenderer>();
            line.material = new Material(Shader.Find("Particles/Standard Unlit"));
      
            line.SetWidth(0.005f, 0.005f);
            orbit.periapsis = Random.Range(distanceRange.x, distanceRange.y);
            orbit.eccentricity = Random.Range(eccentricityRange.x, eccentricityRange.y);
            orbit.inclination = Random.Range(inclinationRange.x, inclinationRange.y);
            orbit.longitude = Random.Range(longitudeRange.x, longitudeRange.y);
            orbit.argument = Random.Range(argumentRange.x, argumentRange.y);
            orbit.meanAnomaly = Random.Range(-180f, 180f);
            orbit.ComputeStaticProperties(); //need to do this so that semi major axis is available
            orbit.period = 2*Math.PI*Math.Sqrt(orbit.semiMajorAxis*orbit.semiMajorAxis*orbit.semiMajorAxis/gravitationParameter);

       

            //create the model for the body
            GameObject planetObj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        
            planetObj.name = name + " Micro";
            planetObj.GetComponent<Renderer>().material.color = color;
            line.startColor = color;
            line.endColor = color;
        
            planetObj.transform.parent = orbitObj.transform;
            planetObj.transform.localScale = Random.Range(sizeRange.x, sizeRange.y) * Vector3.one;
            planetObj.transform.localPosition = Vector3.zero;
            /////PlanetaryTerrain
            ///
        
           GameObject orbitPlanetaryTerrainObj = new GameObject("Orbit " + name);
            macroPlanet = orbitPlanetaryTerrainObj;
            ////this is where I am parenting
            orbitPlanetaryTerrainObj.transform.parent = macroParent.transform;
            orbitPlanetaryTerrainObj.transform.localPosition = Vector3.zero;
            CelestialOrbit orbitPlanetaryTerrain = orbitPlanetaryTerrainObj.AddComponent<CelestialOrbit>();

            orbitPlanetaryTerrain.periapsis = Random.Range(distanceRange.x * 100000, distanceRange.y * 100000);
            orbitPlanetaryTerrain.eccentricity = Random.Range(eccentricityRange.x, eccentricityRange.y);
            orbitPlanetaryTerrain.inclination = Random.Range(inclinationRange.x, inclinationRange.y);
            orbitPlanetaryTerrain.longitude = Random.Range(longitudeRange.x, longitudeRange.y);
            orbitPlanetaryTerrain.argument = Random.Range(argumentRange.x, argumentRange.y);
            orbitPlanetaryTerrain.meanAnomaly = Random.Range(-180f, 180f);
            orbitPlanetaryTerrain.ComputeStaticProperties(); //need to do this so that semi major axis is available
            orbitPlanetaryTerrain.period = 2 * Math.PI * Math.Sqrt(orbitPlanetaryTerrain.semiMajorAxis * orbitPlanetaryTerrain.semiMajorAxis * orbitPlanetaryTerrain.semiMajorAxis / gravitationParameter);

            GameObject planetaryTerrainObj = new GameObject(name);
            Planet planet = planetaryTerrainObj.AddComponent<Planet>();
            planetaryTerrainObj.SetActive(false);
            planetaryTerrainObj.name = name;

            planet.detailDistances = detailDistances;



            float[] detailD = planet.detailDistances;

            for (int i = 0; i < detailD.Length; i++)
            {
                if (i == 0)
                    detailD[i] = startValue;
                else
                    detailD[i] = (detailD[i - 1] / 2f);

            }
            planet.calculateMsds = calculateMsds;
            planet.detailMsds = detailMsds;

            planet.generateColliders = generateColliders;

            planetaryTerrainObj.transform.parent = orbitPlanetaryTerrainObj.transform;
            planetaryTerrainObj.transform.localPosition = Vector3.zero;

            // planet.shader = Shader.Find("PlanetaryTerrain/PlanetFadeShaderBump");
            //  planet.planetMaterial = new Material(planet.shader);
            planet.GetComponent<Planet>().radius = Random.Range(sizeRange.x * 1000000, sizeRange.y * 1000000);
            planet.GetComponent<Planet>().planetName = name;

            planet.heightScale = heightScale;
            planet.planetType = planetType;

            return orbitObj;
        }

    
    }

If someone could help me out that would be amazing thanks :slight_smile:

In line 9 of last script you do

microPlanet = orbitObj;

I think this is it. The place where parent planet gets replaced with orbit.

I need that because that outlines the parent for the moons. microPlanet is an empty gameObject so is macroPlanet…the microPlanet is assigned on line 9 and macroPlanet is assigned on line 44 in that last script from two private variables…

private GameObject microPlanet;
private GameObject macroPlanet;

As you can see:

 macroPlanet = orbitPlanetaryTerrainObj;
for (int i=0; i<planets; i++) {
                GameObject planet = GenerateBody(
         
                     ////this is where the micro Solar System is parented too
                    microParent,
                    ////this is where the macro Solar System is parented too
                    macroParent
                    "Planet " + nameGenerator.GetNextRandomName(),
                    planetColor,
                    planetSettings.coloursStartRange,
                    planetSettings.coloursEndRange,
                    planetEccentricityRange,
                    planetDistanceRange,
                    planetSizeRange,
                    planetSettings.heightScale,
                    planetSettings.startValueDistance,
                    planetSettings.detailDistances,
                    planetSettings.calculateMsds,
                    planetSettings.detailMsds,
                    planetSettings.colliders,
                    PlanetType.Terra
                );
     
                //Generate Moons
     
                for (int j=0; j<moons; j++) {
                        GenerateBody(
                     ////this is where the micro Moon is parented too
                        microPlanet,
                     ////this is where I am trying to get the macro Moon parented too
                        macroPlanet,
                        "Moon " + nameGenerator.GetNextRandomName(),
                        moonColor,
                        moonSettings.coloursStartRange,
                        moonSettings.coloursEndRange,
                        Vector2.zero, //moons have a circular orbit
                        moonDistanceRange,
                        moonSizeRange,
                        planetSettings.heightScale,
                        planetSettings.startValueDistance,
                        planetSettings.detailDistances,
                        planetSettings.calculateMsds,
                        planetSettings.detailMsds,
                        planetSettings.colliders,
                        PlanetType.Lunar
                    );
                }

Anyone?

Don’t change the parent object / orbit if its a moon.
(Create a field / flag for the planet and check against it upon generation)

Or pass the same parent for all moons.

Alternatively, do not store those parents in the class.
Store them on stack only (so that generate methods do not mess around with variables).