private KeplerOrbitMover SpawnBody(JPLElementsData data, string attractorName) { KeplerOrbitMover attractor = FindBodyInstance(attractorName); KeplerOrbitMover body = Instantiate(BodyTemplate, parent: attractor == null ? null : attractor.transform); if (!string.IsNullOrEmpty(data.BodyName)) { body.name = data.BodyName.Trim(); } Transform bodyTransform = body.transform; if (attractor != null) { body.AttractorSettings.AttractorMass = data.AttractorMass; } double unitsPerAU = UnitsPerAU; if (IsAllowedRangeScaleMltPerBody) { // By default MLT value is 1, // but for moons it may be larger than 1 for better visualization. unitsPerAU *= data.RangeMlt; } // G constant is used as free parameter to fixate orbits periods values while SemiMajor axis parameter is adjusted for the scene. double compensatedGConst = GConstant / Math.Pow(AU / unitsPerAU, 3d); body.AttractorSettings.GravityConstant = (float)compensatedGConst; body.AttractorSettings.AttractorObject = attractor == null ? null : attractor.transform; body.OrbitData = new KeplerOrbitData( eccentricity: data.EC, semiMajorAxis: data.A * unitsPerAU, meanAnomalyDeg: data.MA, inclinationDeg: data.IN, argOfPerifocusDeg: data.W, ascendingNodeDeg: data.OM, attractorMass: body.AttractorSettings.AttractorMass, gConst: compensatedGConst); if (attractor != null && data.A > 0) { body.ForceUpdateViewFromInternalState(); } else { body.enabled = false; } var mat = data.Type == 1 ? MainAttractorMaterial : null; SetBodyColorAndDiameter(bodyTransform, data.Color, mat, (float)data.Diameter, ScalePerDiameter); body.gameObject.SetActive(true); return(body); }
private void SpawnAll(JPLElementsData[] inputData) { // Spawn all bodies in multiple passes to resolve parent-child connections. // All spawned bodies are instantiated from signle template, which has no visual components attached, // because this example is designed only for simplest orbits loading process demonstration. if (inputData == null || inputData.Length == 0) { return; } List <JPLElementsData> spawnOrder = new List <JPLElementsData>(inputData); List <KeplerOrbitMover> spawnedInstances = new List <KeplerOrbitMover>(); if (GameObject.FindObjectsOfType <Transform>().Length > 5) { Debug.Log("Warning! too many object on scene. Don't forget to remove old spawned object before spawning new pass"); } bool isAnySpawned = true; while (spawnOrder.Count > 0 && isAnySpawned) { isAnySpawned = false; for (int i = 0; i < spawnOrder.Count; i++) { var attractorName = spawnOrder[0].AttractorName != null ? spawnOrder[0].AttractorName.Trim() : ""; bool isAttractorSpawned = string.IsNullOrEmpty(attractorName) ?true :spawnedInstances.Any(s => s.name == attractorName); if (isAttractorSpawned) { KeplerOrbitMover attractor = string.IsNullOrEmpty(attractorName) ? null : spawnedInstances.First(s => s.name == attractorName); KeplerOrbitMover body = Instantiate(BodyTemplate, parent: attractor == null ? null : attractor.transform); if (!string.IsNullOrEmpty(spawnOrder[0].BodyName)) { body.name = spawnOrder[0].BodyName.Trim(); } if (attractor != null) { body.AttractorSettings.AttractorMass = spawnOrder[0].AttractorMass; } body.AttractorSettings.GravityConstant = (float)GConstant; body.AttractorSettings.AttractorObject = attractor == null ? null : attractor.transform; body.OrbitData = new KeplerOrbitData( eccentricity: spawnOrder[i].EC, semiMajorAxis: spawnOrder[i].A * UnitsPerAU, meanAnomalyDeg: spawnOrder[i].MA, inclinationDeg: spawnOrder[i].IN, argOfPerifocusDeg: spawnOrder[i].W, ascendingNodeDeg: spawnOrder[i].OM, attractorMass: body.AttractorSettings.AttractorMass, gConst: GConstant); if (attractor != null) { body.ForceUpdateViewFromInternalState(); } else { body.enabled = false; } body.gameObject.SetActive(true); spawnOrder.RemoveAt(0); i--; spawnedInstances.Add(body); isAnySpawned = true; } else { // If attractor not spawned yet, then wait for next spawn cycle pass. } } } if (!isAnySpawned && spawnOrder.Count > 0) { Debug.LogError("Couldn't spawn " + spawnOrder.Count + " because assigned attractor was not found"); } }