#pragma once #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "DescentTerrainActor.generated.h" class UProceduralMeshComponent; class UMaterialInterface; /** * Owner of the pooled chunk components (DESIGN_UE.md sections 1.3, 2.1, 2.6). It has no logic: the terrain * subsystem hands a chunk its mesh by acquiring a component here and gives it back when the chunk unloads. A pool * entry has no collision (rock is queried through the density field), no navigation, no overlap events. */ UCLASS() class THEDESCENT_API ADescentTerrainActor : public AActor { GENERATED_BODY() public: ADescentTerrainActor(); virtual void BeginPlay() override; /** A hidden, empty component from the pool (a new one when the pool is empty), placed at the chunk origin. */ UProceduralMeshComponent* AcquireChunkComponent(const FVector& OriginUU); /** Empties the component and puts it back in the pool. */ void ReleaseChunkComponent(UProceduralMeshComponent* Comp); int32 NumActive() const { return NumActiveComps; } int32 NumPooled() const { return Pool.Num(); } /** The material every chunk uses: /Game/Materials/MI_Terrain, else M_Terrain, else the engine default (logged once). */ UMaterialInterface* GetTerrainMaterial() const { return TerrainMaterial; } void SetTerrainMaterial(UMaterialInterface* Material); private: UPROPERTY() TObjectPtr TerrainMaterial; UPROPERTY() TArray> Pool; UPROPERTY() TArray> AllComps; int32 NumActiveComps = 0; };