Game.UI.Editor.TerrainPanelSystem
Assembly: Assembly-CSharp (game)
Namespace: Game.UI.Editor
Type: class
Base: EditorPanelSystemBase
Summary:
TerrainPanelSystem implements the editor UI panel for terrain editing tools and heightmap/worldmap import-export in the in-game editor. It hooks into PrefabSystem to enumerate terraforming prefabs (tools and materials), into ToolSystem to activate/deactivate prefab tools, and into TerrainSystem to read/write terrain textures and properties. It also integrates with the AssetDatabase to present and save heightmap image assets (in the "Heightmaps" folder). The class builds UI sections (tool buttons, heightmap controls) and handles user actions such as importing/exporting heightmaps and worldmaps, removing worldmaps, and updating terrain properties.
Fields
-
private struct UIPriorityComparer : IComparer<PrefabData>
Used to sort PrefabData for UI ordering. It retrieves TerraformingPrefab instances from PrefabSystem and compares UI priorities exposed by a UIObject component (falls back to -1 when not available). -
private static readonly string kHeightmapFolder = "Heightmaps"
Folder name used when listing and saving heightmap assets in the AssetDatabase. -
private PrefabSystem m_PrefabSystem
Reference to the runtime PrefabSystem used to look up prefabs (TerraformingPrefab etc.). -
private ToolSystem m_ToolSystem
Reference to the ToolSystem used to activate prefab tools. -
private TerrainSystem m_TerrainSystem
Reference to the TerrainSystem used to query and replace heightmap/worldmap textures and set terrain properties. -
private EntityQuery m_PrefabQuery
Entity query that selects entities that contain PrefabData and TerraformingData components, excluding Deleted and Temp entities. Used to enumerate available terraforming prefabs. -
private IconButtonGroup m_ToolButtonGroup
UI group that will contain icon buttons for height-targeting terraforming tools. -
private IconButtonGroup m_MaterialButtonGroup = new IconButtonGroup()
UI group that will contain icon buttons for material-targeting terraforming tools. -
private List<PrefabBase> m_ToolPrefabs = new List<PrefabBase>()
List used to track prefabs that represent editor tools/materials added to this panel; used to restore/clear state when panel starts/stops.
Properties
- (none declared public in this class)
This class doesn't declare public properties; it primarily exposes behavior through overridden lifecycle methods and private helpers.
Constructors
public TerrainPanelSystem()
Default public constructor. Marked with [Preserve] (the attribute is applied to lifecycle methods and constructor in source). Sets up nothing special; initialization is performed in OnCreate.
Methods
protected override void OnCreate()
Initializes references to PrefabSystem, ToolSystem, TerrainSystem and constructs the panel UI tree. Creates an EntityQuery that filters for PrefabData + TerraformingData and excludes Deleted/Temp. Builds two EditorSection blocks:- "Editor.TERRAIN_TOOLS": contains m_ToolButtonGroup (IconButtonGroup)
-
"Editor.HEIGHTMAPS": contains a FloatInputField (height scale), import/export buttons for heightmaps and worldmaps, and a remove worldmap button. The method sets the panel title and children/widgets for the UI.
-
protected override void OnGameLoaded(Context serializationContext)
Runs after the game is loaded. Queries the entity world for PrefabData + TerraformingData entities using m_PrefabQuery, sorts the result using UIPriorityComparer, and constructs IconButton lists: - For prefabs with TerraformingTarget.Height: add icon to m_ToolButtonGroup.
-
For prefabs with TerraformingTarget.Material: add icon to m_MaterialButtonGroup. Each icon uses ImageSystem.GetIcon(prefab) with a fallback icon, sets a tooltip from the localized asset name, an action that toggles m_ToolSystem ActivatePrefabTool, and a selected predicate that checks the active prefab. The method populates m_ToolPrefabs with the found terraform prefabs for lifecycle cleanup.
-
protected override void OnStartRunning()
Called when the panel starts running. Resets base.activeSubPanel to null so no subpanel remains active on start. -
protected override void OnStopRunning()
When the panel stops running, if the currently active prefab tool is one that belongs to this panel (m_ToolPrefabs contains it), it deactivates the prefab tool (calls m_ToolSystem.ActivatePrefabTool(null)). Then calls base.OnStopRunning(). -
protected override bool OnCancel()
Handles cancel/back action. If the currently active prefab tool belongs to this panel, deactivate it and consume the cancel (return false). Otherwise defer to base.OnCancel(). -
private void ShowImportHeightmapPanel()
Opens a LoadAssetPanel listing heightmap assets (GetHeightmaps()) and wires OnLoadHeightmap as the selection callback. -
private void ShowExportHeightmapPanel()
Opens a SaveAssetPanel for saving the current heightmap; uses OnSaveHeightmap as the save callback. -
private void ShowImportWorldmapPanel()
Opens a LoadAssetPanel for worldmap import; uses OnLoadWorldHeightmap as the selection callback. -
private void ShowExportWorldmapPanel()
Opens a SaveAssetPanel for saving the world heightmap; uses OnSaveWorldHeightmap as the save callback. The export and remove buttons are disabled if m_TerrainSystem.worldHeightmap is null. -
private void RemoveWorldmap()
Calls m_TerrainSystem.ReplaceWorldHeightmap(null) to clear the currently set world heightmap. -
private void RefreshTerrainProperties(float2 heightScaleOffset)
Sets the terrain properties on m_TerrainSystem by calling m_TerrainSystem.SetTerrainProperties(heightScaleOffset). Used by the FloatInputField accessor for height scaling. -
private static IEnumerable<AssetItem> GetHeightmaps()
Enumerates ImageAsset entries in AssetDatabase.global whose subPath starts with kHeightmapFolder. For each found ImageAsset yields an AssetItem with guid, fileName, displayName, image (asset.ToUri()) and tooltip. -
private void OnLoadHeightmap(Colossal.Hash128 guid)
Loads an ImageAsset from AssetDatabase.global by guid, reads a Texture2D (srgb true), validates it with TerrainSystem.IsValidHeightmapFormat(texture), displays an error dialog on invalid format (DisplayHeightmapError), otherwise calls m_TerrainSystem.ReplaceHeightmap(texture). -
private void OnLoadWorldHeightmap(Colossal.Hash128 guid)
Same as OnLoadHeightmap but calls m_TerrainSystem.ReplaceWorldHeightmap(texture) on success. -
private void DisplayHeightmapError()
Constructs and shows a message dialog via GameManager.instance.userInterface.appBindings.ShowMessageDialog, using localized strings: "Editor.INCORRECT_HEIGHTMAP_TITLE" and "Editor.INCORRECT_HEIGHTMAP_MESSAGE". The message is supplied substitution values for WIDTH and HEIGHT using TerrainSystem.kDefaultHeightmapWidth and TerrainSystem.kDefaultHeightmapHeight. -
private void OnSaveHeightmap(string fileName, Colossal.Hash128? overwriteGuid)
Convenience overload that delegates to OnSaveHeightmap(fileName, overwriteGuid, worldMap: false). -
private void OnSaveWorldHeightmap(string fileName, Colossal.Hash128? overwriteGuid)
Convenience overload that delegates to OnSaveHeightmap(fileName, overwriteGuid, worldMap: true). -
private unsafe void OnSaveHeightmap(string fileName, Colossal.Hash128? overwriteGuid, bool worldMap)
Saves either the current heightmap or the current world heightmap to the user AssetDatabase. Behavior: - Closes subpanel.
- If overwriteGuid is provided and the user asset exists, deletes existing asset to overwrite.
- Chooses texture = worldMap ? m_TerrainSystem.worldHeightmap : m_TerrainSystem.heightmap.
- Allocates a NativeArray
sized width * height (Allocator.Persistent). - Uses AsyncGPUReadback.RequestIntoNativeArray(ref output, texture).WaitForCompletion() to read pixels from GPU into the NativeArray (ushort data).
- Calls TextureUtilities.SaveImage with the native pointer (output.GetUnsafeReadOnlyPtr()) to produce an image byte[] (PNG, bit depth 16 per channel).
- Creates an AssetDataPath under kHeightmapFolder and writes the bytes into a newly added ImageAsset in AssetDatabase.user (either creating or overwriting by guid).
-
Ensures output NativeArray is disposed in finally block. Note: uses unsafe pointer conversion and GPU readback; this code may block until the readback completes.
-
private UIPriorityComparer..ctor(PrefabSystem prefabSystem)
Nested comparer constructor that stores PrefabSystem reference. -
private int UIPriorityComparer.Compare(PrefabData a, PrefabData b)
Compare implementation that gets TerraformingPrefab for each PrefabData, fetches UIObject component via TryGet, and compares component.m_Priority. If UIObject is absent on either prefab, returns -1.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Example: Update height scale offset X when creating the panel.
// (This code runs inside the panel instance.)
float2 current = m_TerrainSystem.heightScaleOffset;
current.x = 5000f; // set desired height scale X
RefreshTerrainProperties(current);
}
Notes and implementation considerations:
- Heightmap import/export expects image assets with the correct dimensions/format. DisplayHeightmapError provides the expected default width/height constants to the user when an incorrect image is selected.
- Saving heightmaps uses AsyncGPUReadback to fetch GPU texture data into a NativeArray