Add automatic heightmap files removal on Editor shutdown for deleted terrains
#1902
This commit is contained in:
@@ -602,3 +602,13 @@ bool ManagedEditor::CreateAsset(const String& tag, String outputPath)
|
||||
FileSystem::NormalizePath(outputPath);
|
||||
return AssetsImportingManager::Create(tag, outputPath);
|
||||
}
|
||||
|
||||
Array<Guid> ManagedEditor::GetAssetReferences(const Guid& assetId)
|
||||
{
|
||||
Array<Guid> result;
|
||||
if (auto* asset = Content::Load<Asset>(assetId))
|
||||
{
|
||||
asset->GetReferences(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -218,6 +218,13 @@ public:
|
||||
/// <param name="outputPath">Output asset path.</param>
|
||||
API_FUNCTION() static bool CreateAsset(const String& tag, String outputPath);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of asset references of a given asset.
|
||||
/// </summary>
|
||||
/// <param name="assetId">The asset ID.</param>
|
||||
/// <returns>List of referenced assets.</returns>
|
||||
API_FUNCTION() static Array<Guid> GetAssetReferences(const Guid& assetId);
|
||||
|
||||
public:
|
||||
API_STRUCT(Internal, NoDefault) struct VisualScriptStackFrame
|
||||
{
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using FlaxEngine;
|
||||
|
||||
namespace FlaxEditor.SceneGraph.Actors
|
||||
@@ -10,6 +14,15 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
[HideInEditor]
|
||||
public sealed class TerrainNode : ActorNode
|
||||
{
|
||||
private struct RemovedTerrain
|
||||
{
|
||||
public Guid SceneId;
|
||||
public Guid TerrainId;
|
||||
public string[] Files;
|
||||
}
|
||||
|
||||
private static List<RemovedTerrain> _cleanupFiles;
|
||||
|
||||
/// <inheritdoc />
|
||||
public TerrainNode(Actor actor)
|
||||
: base(actor)
|
||||
@@ -18,5 +31,68 @@ namespace FlaxEditor.SceneGraph.Actors
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool AffectsNavigation => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Delete()
|
||||
{
|
||||
// Schedule terrain data files for automatic cleanup
|
||||
if (_cleanupFiles == null)
|
||||
{
|
||||
_cleanupFiles = new List<RemovedTerrain>();
|
||||
Engine.RequestingExit += OnRequestingExit;
|
||||
}
|
||||
if (Actor is Terrain terrain)
|
||||
{
|
||||
var removed = new RemovedTerrain
|
||||
{
|
||||
SceneId = terrain.Scene?.ID ?? Guid.Empty,
|
||||
TerrainId = terrain.ID,
|
||||
Files = new string[4],
|
||||
};
|
||||
for (int i = 0; i < terrain.PatchesCount; i++)
|
||||
{
|
||||
var patch = terrain.GetPatch(i);
|
||||
if (patch.Heightmap)
|
||||
removed.Files[0] = patch.Heightmap.Path;
|
||||
if (patch.Heightfield)
|
||||
removed.Files[1] = patch.Heightfield.Path;
|
||||
if (patch.GetSplatmap(0))
|
||||
removed.Files[2] = patch.GetSplatmap(0).Path;
|
||||
if (patch.GetSplatmap(1))
|
||||
removed.Files[3] = patch.GetSplatmap(1).Path;
|
||||
}
|
||||
_cleanupFiles.Add(removed);
|
||||
}
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
void OnRequestingExit()
|
||||
{
|
||||
foreach (var e in _cleanupFiles)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Skip removing this terrain file sif it's still referenced
|
||||
var sceneReferences = Editor.GetAssetReferences(e.SceneId);
|
||||
if (sceneReferences != null && sceneReferences.Contains(e.TerrainId))
|
||||
continue;
|
||||
|
||||
// Delete files
|
||||
foreach (var file in e.Files)
|
||||
{
|
||||
if (file != null && File.Exists(file))
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Editor.LogWarning(ex);
|
||||
}
|
||||
}
|
||||
_cleanupFiles.Clear();
|
||||
_cleanupFiles = null;
|
||||
Engine.RequestingExit -= OnRequestingExit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,11 @@ TerrainPatch::~TerrainPatch()
|
||||
#endif
|
||||
}
|
||||
|
||||
RawDataAsset* TerrainPatch::GetHeightfield() const
|
||||
{
|
||||
return _heightfield.Get();
|
||||
}
|
||||
|
||||
void TerrainPatch::RemoveLightmap()
|
||||
{
|
||||
for (auto& chunk : Chunks)
|
||||
|
||||
@@ -149,6 +149,12 @@ public:
|
||||
return GetChunk(z * Terrain::ChunksCountEdge + x);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the heightfield collision data asset.
|
||||
/// </summary>
|
||||
/// <returns>The heightfield data asset.</returns>
|
||||
API_PROPERTY() RawDataAsset* GetHeightfield() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the splatmap assigned to this patch.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user