はじめに
開発していると「このMeshは動的に入れ替わるからエディタ上ではまだ生成されていないし、デフォルトで余計なMeshは表示させたくない」といったクラス設計にすることが多々あると思います
しかしまだ動的に生成されるオブジェクトはそのままだとエディタ上で確認できず「このMeshはどれくらい大きいのか?比較できない」といった状況になります
その際の対処法をまとめておきます
結論:OnRegisterを使おう
実装
今回のサンプルの構造としてはUTestComponentを持つATestActorを継承したBPクラスを作成し、ATestCharactorをB;ueprintエディタ上で設定します
ATestActorとATestCharactorは特筆することはないのでてきとーに用意してください
確認
エディタで確認すると表示しているのはATestActorを継承したBlueprintですが、設定してATestCharacotrが表示されていることがわかるとおもいます(椅子のMeshがATestCharacotr)
Sample Code
// Fill out your copyright notice in the Description page of Project Settings.
# pragma once
# include "CoreMinimal.h"
# include "Components/SceneComponent.h"
# include "TestComponent.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class SANDBOX_API UTestComponent : public USceneComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UTestComponent();
protected:
// Called when the game starts
virtual void BeginPlay() override;
virtual void OnRegister() override;
virtual void OnUnregister() override;
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
void CreateCharactor();
void DestroyCharactor();
private:
UPROPERTY(EditAnywhere)
TSubclassOf<class ATestCharactor> charactorClass;
UPROPERTY()
class ATestCharactor* meshActor = nullptr;
UPROPERTY()
bool bCreatedCharactor = false;
};
// Fill out your copyright notice in the Description page of Project Settings.
# include "TestComponent.h"
# include "Engine/World.h"
# include "TestCharactor.h"
// Sets default values for this component's properties
UTestComponent::UTestComponent()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
}
void UTestComponent::OnRegister()
{
Super::OnRegister();
CreateCharactor();
}
void UTestComponent::OnUnregister()
{
DestroyCharactor();
Super::OnUnregister();
}
void UTestComponent::CreateCharactor()
{
if (charactorClass != nullptr)
{
DestroyCharactor();
FActorSpawnParameters spawnParameters;
spawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
meshActor = GetWorld()->SpawnActor<ATestCharactor>(charactorClass,FTransform(), spawnParameters);
//自身の子オブジェクトとしてぶら下げる
meshActor->AttachToComponent(this,FAttachmentTransformRules::KeepRelativeTransform);
}
}
void UTestComponent::DestroyCharactor()
{
if (meshActor != nullptr)
{
meshActor->Destroy();
meshActor = nullptr;
}
}
...
注意点
OnUnregisterを忘れないように
OnRegisterはPlay時に呼ばれたり、PlayInから停止して非実行状態に戻ってきたときにも再度呼ばれたりするので生成するクラスが増えてしまったりするのでOnUnregisterで生成しておいたMeshはDestroyしておくのを忘れないようにしておきましょう