【UE4】ランライムに生成されるActorComponent内のMesh情報をエディタ上で表示する
はじめに
開発していると「この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しておくのを忘れないようにしておきましょう