プログラムから床を生成するためにたくさんのアクタを設置した場合、それが画面内にたくさん含まれるときに20fps程度まで処理落ちしてしまいます。
ビューポートで一つ一つ手置きでマップを作るのは大変なためプログラムで壁やステージ等を作成しようと考えているのですが、どれだけ調べてもさらにたくさんのアクタを設置しても動作が軽くなる方法が分かりませんでした。
対策を教えていただけると嬉しいです。
// Fill out your copyright notice in the Description page of Project Settings.
#include "SpawnFloor.h"
#include "VanillaLib.h"
#include "Engine.h" // GEngine ( ログ出力 )
#include "Materials/MaterialInstanceDynamic.h"
#include "BoxColor.h"
#include <string>
// Sets default values
ASpawnFloor::ASpawnFloor()
{
// 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;
count = 0;
UStaticMeshComponent* visual_mesh;
visual_mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
visual_mesh->SetupAttachment(RootComponent);
visual_mesh->SetCollisionEnabled(ECollisionEnabled::Type::NoCollision); // あたり判定無し
visual_mesh->SetHiddenInGame(true); // 描画しない
static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Cube.Shape_Cube"));
if (CubeVisualAsset.Succeeded())
{
visual_mesh->SetStaticMesh(CubeVisualAsset.Object);
visual_mesh->SetRelativeLocation(FVector(0.0f, 0.0f, 0.0f));
}
}
// Called when the game starts or when spawned
void ASpawnFloor::BeginPlay()
{
Super::BeginPlay();
float size = GetActorScale().X * 100;
FRotator rot(0.f, 0.f, 0.f);
FActorSpawnParameters params;
params.bAllowDuringConstructionScript = true;
params.bDeferConstruction = false;
params.bNoFail = true;
params.Instigator = nullptr;
params.Name = { };
params.ObjectFlags = EObjectFlags::RF_NoFlags;
params.OverrideLevel = nullptr;
params.Owner = this;
params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
params.Template = nullptr;
const int box_num_rx = 15;
const int box_num_ry = 15;
for (int ix = 0; ix < box_num_rx * 2 + 1; ix++)
{
for (int iy = 0; iy < box_num_ry * 2 + 1; iy++)
{
float color_add = VanillaLib::GetRandF(0.4f, 0.2f);
ABoxColor::SetGlobalColor(FLinearColor(color_add, color_add, 0.8f));
FVector pos(size * ix - size * box_num_rx, size * iy - size * box_num_ry, 130.f - VanillaLib::GetRandF(30.f));
auto Something = GetWorld()->SpawnActor<ABoxColor>(pos, rot, params);
}
}
//GEngine->AddOnScreenDebugMessage(-1, 5, FColor::White, "床を生成しました");
}
// Called every frame
void ASpawnFloor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (count == 100)
{
}
count++;
}
// 追記 -------------------------------------------------------------------
// Called when the game starts or when spawned
void ASpawnFloor::BeginPlay()
{
Super::BeginPlay();
float size = GetActorScale().X * 100;
FRotator rot(0.f, 0.f, 0.f);
FActorSpawnParameters params;
params.bAllowDuringConstructionScript = true;
params.bDeferConstruction = false;
params.bNoFail = true;
params.Instigator = nullptr;
params.Name = { };
params.ObjectFlags = EObjectFlags::RF_NoFlags;
params.OverrideLevel = nullptr;
params.Owner = this;
params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
params.Template = nullptr;
//auto my_actor = GetWorld()->SpawnActor<AActor>(AActor::StaticClass());
//my_actor->SetActorLocation(FVector(0, 0, 140));
//UInstancedStaticMeshComponent* ISMComp = NewObject<UInstancedStaticMeshComponent>(my_actor);
//ISMComp->RegisterComponent();
////ISMComp->SetStaticMesh(StaticLoadObject(UMaterial::StaticClass(), nullptr, TEXT("/Game/StarterContent/Materials/M_Basic_Wall")));
//ISMComp->SetFlags(EObjectFlags::RF_Transactional);
//this->AddInstanceComponent(ISMComp);
//TActorIterator<ABoxColor> box_color_iterator(GetWorld());
//ABoxColor* box_color_actor = *box_color_iterator;
//
//TArray<UInstancedStaticMeshComponent*> components;
//box_color_actor->GetComponents<UInstancedStaticMeshComponent>(components);
auto my_actor = GetWorld()->SpawnActor<ABoxColor>(FVector(0.f, 0.f, 140.f), rot, params);
UInstancedStaticMeshComponent* ISMComp = NewObject<UInstancedStaticMeshComponent>(my_actor, UInstancedStaticMeshComponent::StaticClass());
//ISMComp->AttachToComponent(box_color_actor->GetRootComponent(), FAttachmentTransformRules::KeepWorldTransform);
//ISMComp->SetStaticMesh(StaticLoadObject(UMaterial::StaticClass(), nullptr, TEXT("/Game/StarterContent/Materials/M_Basic_Wall")));
ISMComp->SetFlags(EObjectFlags::RF_Transactional);
//ISMComp->SetWorldLocation(pos);
//UStaticMeshComponent* visual_mesh;
//visual_mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
//visual_mesh->SetupAttachment(RootComponent);
//auto material_instance =
// visual_mesh->CreateAndSetMaterialInstanceDynamicFromMaterial(
// 0, Cast<UMaterial>(StaticLoadObject(UMaterial::StaticClass(), nullptr, TEXT("/Game/StarterContent/Materials/M_Basic_Wall"))));
////// マテリアルインスタンスへスカラーパラメーターを設定する。与える値の型は float
////material_instance->SetScalarParameterValue("scalar_parameter_name", 1.23f);
////// マテリアルインスタンスへベクターパラメーターを設定する。与える値の型は FLinearColor
//material_instance->SetVectorParameterValue("Color", FLinearColor(0.5f,0.5f,0.5f));
//static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Cube.Shape_Cube"));
//if (CubeVisualAsset.Succeeded())
//{
// //visual_mesh->SetStaticMesh(CubeVisualAsset.Object);
// GEngine->AddOnScreenDebugMessage(-1, 5, FColor::White, "Succeeded");
// //ISMComp->SetStaticMesh(CubeVisualAsset.Object);
//}
ISMComp->RegisterComponent();
//this->AddInstanceComponent(ISMComp);
FTransform transform;
transform.SetScale3D(FVector(1.f, 1.f, 1.f));
const int box_num_rx = 15;
const int box_num_ry = 15;
for (int ix = 0; ix < box_num_rx * 2 + 1; ix++)
{
for (int iy = 0; iy < box_num_ry * 2 + 1; iy++)
{
float color_add = VanillaLib::GetRandF(0.4f, 0.2f);
ABoxColor::SetGlobalColor(FLinearColor(color_add, color_add, 0.8f));
FVector pos(size * ix - size * box_num_rx, size * iy - size * box_num_ry, 130.f - VanillaLib::GetRandF(30.f));
//auto Something = GetWorld()->SpawnActor<ABoxColor>(pos, rot, params);
transform.SetLocation(pos);
ISMComp->AddInstance(transform);
}
}
//for (int ix = 0; ix < box_num_rx * 2 + 1; ix++)
//{
// for (int iy = 0; iy < box_num_ry * 2 + 1; iy++)
// {
// TArray<UActorComponent*> currentICs = this->GetInstanceComponents();
// for (UActorComponent* ic : currentICs)
// ic->DestroyComponent();
// }
//}
//GEngine->AddOnScreenDebugMessage(-1, 5, FColor::White, "床を生成しました");
}