using UnityEngine; using System.Collections.Generic; using System; // Required for Math.Pow // EarthInternalStructure.cs // This script creates a nested spherical model of the Earth's internal layers. // It attaches EarthLayerProperties to each layer to store empirical data. // Attach this script to your "Earth" GameObject in the scene. public class EarthInternalStructure : MonoBehaviour { [Header("References")] [Tooltip("Reference to the NBodySimulator to get the distance scaling factor.")] public NBodySimulator nBodySimulator; [Tooltip("Material for the Inner Core.")] public Material innerCoreMaterial; [Tooltip("Material for the Outer Core.")] public Material outerCoreMaterial; [Tooltip("Material for the Lower Mantle.")] public Material lowerMantleMaterial; [Tooltip("Material for the Asthenosphere.")] public Material asthenosphereMaterial; [Tooltip("Material for the Lithosphere.")] public Material lithosphereMaterial; [Tooltip("Material for the Crust.")] public Material crustMaterial; [Tooltip("Material for the Water (Oceans).")] public Material waterMaterial; [Tooltip("Material for the Ice Caps.")] public Material iceMaterial; // A list to hold the data for each layer, ordered from innermost to outermost. private List _earthLayersData = new List(); // Private struct to define layer data before creating GameObjects private struct EarthLayerData { public string name; public double outerRadius_m; // Outer radius of this layer from Earth's center in meters public float massPercentage; // Mass percentage relative to total Earth mass (0-1) public double averageDensity_kg_m3; public double averagePressure_GPa; public double averageTemperature_C; public double viscosity_cP; public Material material; // Reference to the Unity Material for this layer } void Awake() { if (nBodySimulator == null) { nBodySimulator = FindObjectOfType(); if (nBodySimulator == null) { Debug.LogError("NBodySimulator not found in scene. Please assign it or ensure it exists."); enabled = false; return; } } // Define the layers using the static calculation classes for empirical data // Ensure materials are assigned in the Unity Editor Inspector for this script _earthLayersData.Add(new EarthLayerData { name = "Inner Core", outerRadius_m = EarthConstantsAndCalculations.INNER_CORE_OUTER_RADIUS_M, massPercentage = (float)EarthConstantsAndCalculations.INNER_CORE_MASS_PERCENTAGE, averageDensity_kg_m3 = EarthConstantsAndCalculations.INNER_CORE_AVERAGE_DENSITY_KG_M3, averagePressure_GPa = EarthConstantsAndCalculations.INNER_CORE_AVERAGE_PRESSURE_GPA, averageTemperature_C = EarthConstantsAndCalculations.INNER_CORE_AVERAGE_TEMPERATURE_C, viscosity_cP = EarthConstantsAndCalculations.INNER_CORE_VISCOSITY_CP, material = innerCoreMaterial }); _earthLayersData.Add(new EarthLayerData { name = "Outer Core", outerRadius_m = EarthConstantsAndCalculations.OUTER_CORE_OUTER_RADIUS_M, massPercentage = (float)EarthConstantsAndCalculations.OUTER_CORE_MASS_PERCENTAGE, averageDensity_kg_m3 = EarthConstantsAndCalculations.OUTER_CORE_AVERAGE_DENSITY_KG_M3, averagePressure_GPa = EarthConstantsAndCalculations.OUTER_CORE_AVERAGE_PRESSURE_GPA, averageTemperature_C = EarthConstantsAndCalculations.OUTER_CORE_AVERAGE_TEMPERATURE_C, viscosity_cP = EarthConstantsAndCalculations.OUTER_CORE_VISCOSITY_CP, material = outerCoreMaterial }); // Mantle layers - using empirical boundaries from EarthConstantsAndCalculations // Mass percentages and other properties are empirical averages. _earthLayersData.Add(new EarthLayerData { name = "Lower Mantle", outerRadius_m = EarthConstantsAndCalculations.LOWER_MANTLE_OUTER_RADIUS_M, massPercentage = (float)EarthConstantsAndCalculations.LOWER_MANTLE_MASS_PERCENTAGE, averageDensity_kg_m3 = EarthConstantsAndCalculations.LOWER_MANTLE_AVERAGE_DENSITY_KG_M3, averagePressure_GPa = EarthConstantsAndCalculations.LOWER_MANTLE_AVERAGE_PRESSURE_GPA, averageTemperature_C = EarthConstantsAndCalculations.LOWER_MANTLE_AVERAGE_TEMPERATURE_C, viscosity_cP = EarthConstantsAndCalculations.LOWER_MANTLE_VISCOSITY_CP, material = lowerMantleMaterial }); _earthLayersData.Add(new EarthLayerData { name = "Asthenosphere", outerRadius_m = EarthConstantsAndCalculations.ASTHENOSPHERE_OUTER_RADIUS_M, massPercentage = (float)EarthConstantsAndCalculations.ASTHENOSPHERE_MASS_PERCENTAGE, averageDensity_kg_m3 = EarthConstantsAndCalculations.ASTHENOSPHERE_AVERAGE_DENSITY_KG_M3, averagePressure_GPa = EarthConstantsAndCalculations.ASTHENOSPHERE_AVERAGE_PRESSURE_GPA, averageTemperature_C = EarthConstantsAndCalculations.ASTHENOSPHERE_AVERAGE_TEMPERATURE_C, viscosity_cP = EarthConstantsAndCalculations.ASTHENOSPHERE_VISCOSITY_CP, material = asthenosphereMaterial }); _earthLayersData.Add(new EarthLayerData { name = "Lithosphere", outerRadius_m = EarthConstantsAndCalculations.LITHOSPHERE_OUTER_RADIUS_M, massPercentage = (float)EarthConstantsAndCalculations.LITHOSPHERE_MASS_PERCENTAGE, averageDensity_kg_m3 = EarthConstantsAndCalculations.LITHOSPHERE_AVERAGE_DENSITY_KG_M3, averagePressure_GPa = EarthConstantsAndCalculations.LITHOSPHERE_AVERAGE_PRESSURE_GPA, averageTemperature_C = EarthConstantsAndCalculations.LITHOSPHERE_AVERAGE_TEMPERATURE_C, viscosity_cP = EarthConstantsAndCalculations.LITHOSPHERE_VISCOSITY_CP, material = lithosphereMaterial }); _earthLayersData.Add(new EarthLayerData { name = "Crust", outerRadius_m = EarthConstantsAndCalculations.CRUST_OUTER_RADIUS_M, // Earth's surface massPercentage = (float)EarthConstantsAndCalculations.CRUST_MASS_PERCENTAGE, averageDensity_kg_m3 = EarthConstantsAndCalculations.CRUST_AVERAGE_DENSITY_KG_M3, averagePressure_GPa = EarthConstantsAndCalculations.CRUST_AVERAGE_PRESSURE_GPA, averageTemperature_C = EarthConstantsAndCalculations.CRUST_AVERAGE_TEMPERATURE_C, viscosity_cP = EarthConstantsAndCalculations.CRUST_VISCOSITY_CP, material = crustMaterial }); // Water (Oceans) _earthLayersData.Add(new EarthLayerData { name = "Water", outerRadius_m = OceanCalculations.GetOceanOuterRadius_m(), massPercentage = (float)(EarthConstantsAndCalculations.HYDROSPHERE_TOTAL_MASS_KG / EarthConstantsAndCalculations.WGS84_TOTAL_EARTH_MASS_KG), averageDensity_kg_m3 = EarthConstantsAndCalculations.OCEAN_AVERAGE_DENSITY_KG_M3, averagePressure_GPa = 0.001, // Very low pressure at surface averageTemperature_C = 10.0, viscosity_cP = 1.0, // Water viscosity material = waterMaterial }); // Ice Caps (simplified as a top layer for visualization and calculation) // Note: The actual mass of ice will be dynamically updated by TrenchInstabilitySimulator // based on GRACE data. This 'massPercentage' here is for initial setup of the layer. _earthLayersData.Add(new EarthLayerData { name = "Ice", // For initial setup, use a radius that visually places it on top of water/crust outerRadius_m = OceanCalculations.GetOceanOuterRadius_m() + 100.0, // Example: 100m initial ice thickness for visual massPercentage = (float)(EarthConstantsAndCalculations.ESTIMATED_TOTAL_ICE_MASS_KG / EarthConstantsAndCalculations.WGS84_TOTAL_EARTH_MASS_KG), // Initial total percentage averageDensity_kg_m3 = EarthConstantsAndCalculations.ICE_AVERAGE_DENSITY_KG_M3, // Empirical density of ice averagePressure_GPa = 0.0, averageTemperature_C = -5.0, viscosity_cP = 1.0e13, // Ice viscosity (glacier flow) material = iceMaterial }); CreateEarthLayers(); } void CreateEarthLayers() { // Ensure Earth GameObject is at (0,0,0) in Unity coordinates for relative layer positioning if (transform.position != Vector3.zero) { Debug.LogWarning("Earth GameObject is not at (0,0,0). Layer scaling might be incorrect. Resetting position."); transform.position = Vector3.zero; } foreach (var layerData in _earthLayersData) { GameObject layerSphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); layerSphere.name = layerData.name; layerSphere.transform.parent = transform; // Make it a child of the Earth GameObject // Calculate Unity scale based on real-world radius and NBodySimulator's distance scale // Diameter in Unity units double diameterUnityUnits = (layerData.outerRadius_m * 2.0) / nBodySimulator.distanceScale_m_per_unity_unit; layerSphere.transform.localScale = Vector3.one * (float)diameterUnityUnits; // Assign material Renderer renderer = layerSphere.GetComponent(); if (renderer == null) renderer = layerSphere.AddComponent(); renderer.material = layerData.material; // Remove collider if it's not needed for physics interaction (prevents interference) Collider collider = layerSphere.GetComponent(); if (collider != null) { Destroy(collider); } // Add EarthLayerProperties component and assign data (RE-ADDED) EarthLayerProperties props = layerSphere.AddComponent(); props.layerName = layerData.name; props.outerRadius_m = layerData.outerRadius_m; props.massPercentage = layerData.massPercentage; props.averageDensity_kg_m3 = layerData.averageDensity_kg_m3; props.averagePressure_GPa = layerData.averagePressure_GPa; props.averageTemperature_C = layerData.averageTemperature_C; props.viscosity_cP = layerData.viscosity_cP; Debug.Log($"Created Layer: {layerData.name} with outer radius: {layerData.outerRadius_m / 1000.0:F2} km, Unity Scale: {diameterUnityUnits:F6}"); } } // Optional: You can add methods here to interact with these layers, // e.g., get a specific layer's properties, update them, etc. public EarthLayerProperties GetLayerProperties(string layerName) { foreach (Transform child in transform) { if (child.name == layerName) { return child.GetComponent(); } } return null; } } Planetary Instability Model PIM - Copyright (C) 2025 James Pacha