Skip to content

Instantly share code, notes, and snippets.

@ldl19691031
Created August 24, 2024 04:49
Show Gist options
  • Save ldl19691031/8d9e536dcfc8551d618afee9a6a6e1e0 to your computer and use it in GitHub Desktop.
Save ldl19691031/8d9e536dcfc8551d618afee9a6a6e1e0 to your computer and use it in GitHub Desktop.
RenderStaticMeshWithoutComponentsinUnrealEngine
// Fill out your copyright notice in the Description page of Project Settings.
#include "LightWeightSMActor.h"
#include "Engine/StaticMeshActor.h"
#include "StaticMeshSceneProxyDesc.h"
#include "PrimitiveSceneDesc.h"
// Sets default values
ALightWeightSMActor::ALightWeightSMActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ALightWeightSMActor::BeginPlay()
{
Super::BeginPlay();
UWorld* world = GetWorld();
if (MeshActorTemplate && world)
{
Primitives.Empty();
for (int32 i = 0; i < 100; i++)
{
//Initialize
TSharedPtr<FStaticMeshSceneProxyDesc> ProxyDesc = MakeShared<FStaticMeshSceneProxyDesc>(MeshActorTemplate->GetStaticMeshComponent());
FStaticMeshSceneProxyDesc* staticMeshSceneProxyDesc = ProxyDesc.Get();
FPrimitiveSceneProxyDesc* ProxyDescPtr = staticMeshSceneProxyDesc;
FPrimitiveSceneDesc* PrimitiveSceneDesc = new FPrimitiveSceneDesc();
PrimitiveSceneDesc->ProxyDesc = ProxyDescPtr;
PrimitiveSceneDesc->World = world;
PrimitiveSceneDesc->PrimitiveUObject = this;
PrimitiveSceneDesc->AttachmentRootPosition = GetActorLocation() + FVector(i* Interval, 0, 0);
PrimitiveSceneDesc->PrimitiveSceneData = new FPrimitiveSceneInfoData();
PrimitiveSceneDesc->PrimitiveSceneData->SceneProxy = new FStaticMeshSceneProxy(*staticMeshSceneProxyDesc, false);
const FTransform trs = FTransform(FVector(i * Interval, 0, 0));
PrimitiveSceneDesc->RenderMatrix = trs.ToMatrixWithScale();
PrimitiveSceneDesc->LocalBounds = MeshActorTemplate->GetStaticMeshComponent()->GetStaticMesh()->GetBounds();
PrimitiveSceneDesc->Bounds = PrimitiveSceneDesc->LocalBounds.TransformBy(PrimitiveSceneDesc->RenderMatrix);
Primitives.Add(PrimitiveSceneDesc);
ProxyDescs.Add(ProxyDesc);
}
world->Scene->BatchAddPrimitives(Primitives);
}
}
void ALightWeightSMActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
UWorld* world = GetWorld();
if (world)
{
for (FPrimitiveSceneDesc* PrimitiveSceneDesc : Primitives)
{
world->Scene->RemovePrimitive(PrimitiveSceneDesc);
}
}
Super::EndPlay(EndPlayReason);
}
void ALightWeightSMActor::BeginDestroy()
{
UWorld* world = GetWorld();
if (world)
{
for (FPrimitiveSceneDesc* PrimitiveSceneDesc : Primitives)
{
world->Scene->RemovePrimitive(PrimitiveSceneDesc);
}
}
Super::BeginDestroy();
}
// Called every frame
void ALightWeightSMActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "LightWeightSMActor.generated.h"
UCLASS(Blueprintable, Abstract)
class ALightWeightSMActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ALightWeightSMActor();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void BeginDestroy() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere)
float Interval = 500.0f;
UPROPERTY(EditAnywhere)
class AStaticMeshActor* MeshActorTemplate;
TArray<FPrimitiveSceneDesc*> Primitives;
TArray<TSharedPtr<struct FStaticMeshSceneProxyDesc>> ProxyDescs;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment