我正在尝试使用for循环创建多个UStaticMeshComponent
,但虚幻引擎会继续在CreateDefaultSubobject
中的Object.h
上触发断点(不是我的代码,它来自UE4核心API)。当我创建单个组件时,它工作正常。我对UnrealEngine和C ++还是很陌生,所以我可能在做一些愚蠢的事情,但是请保持简单:)
非常感谢您的帮助。
标题
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "FlowSphere.generated.h"
UCLASS()
class CPP_PRACTICE_3_API AFlowSphere : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AFlowSphere();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
private:
//UPROPERTY()
//TArray<UStaticMeshComponent*> StaticMeshComponents;
UStaticMeshComponent* test;
};
C ++
#include "FlowSphere.h"
// Sets default values
AFlowSphere::AFlowSphere()
{
int32 amount = 100;
RootComponent = CreateDefaultSubobject<USceneComponent>("SceneComponent");
for (int32 i = 0; i < amount; i++) {
//WHEN I INCLUDE THE LINE BELOW, UE4 START MAKING BREAKPOINT
UStaticMeshComponent* item = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Sphere"));
item.AttachTo(this->RootComponent);
}
//THIS WORKS FINE
this->test = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("HELLO"));
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AFlowSphere::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AFlowSphere::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
它在UE4 API的Object.h
上触发断点的地方
/**
* Create a component or subobject
* @param TReturnType class of return type, all overrides must be of this type
* @param SubobjectName name of the new component
* @param bTransient true if the component is being assigned to a transient property. This does not make the component itself transient, but does stop it from inheriting parent defaults
*/
template<class TReturnType>
TReturnType* CreateDefaultSubobject(FName SubobjectName, bool bTransient = false)
{
UClass* ReturnType = TReturnType::StaticClass();
return static_cast<TReturnType*>(CreateDefaultSubobject(SubobjectName, ReturnType, ReturnType, /*bIsRequired =*/ true, /*bIsAbstract =*/ false, bTransient));
}
答案 0 :(得分:1)
所以我最近不得不做同样的事情并遇到了很多问题,但要解决的两个主要问题是:
以下是正确的代码。
#include "FlowSphere.h"
#include "Components/StaticMeshComponent.h"
#include "UObject/ConstructorHelpers.h"
// Sets default values
AFlowSphere::AFlowSphere()
{
int32 amount = 100;
RootComponent = CreateDefaultSubobject<USceneComponent>("SceneComponent");
for (int32 i = 0; i < amount; i++) {
FName name = *FString::Printf(TEXT("Sphere %i"), i);
FName c_name = *FString::Printf(TEXT("ChildSceneComponent %i"), i);
UPROPERTY(EditAnywhere)
USceneComponent* ChildSceneComponent
= CreateDefaultSubobject<USceneComponent>(c_name);
// instead of the regular static mesh, create and instance static mesh object with name assigned
UInstancedStaticMeshComponent* item = CreateDefaultSubobject<UStaticMeshComponent>(name);
item->RegisterComponent();
// assign property to mesh if not you'll get a static mesh null property error like i did
auto MeshAsset = ConstructorHelpers::FObjectFinder<UStaticMesh>(TEXT("StaticMesh'/Engine/BasicShapes/Sphere.Sphere'"));
if (MeshAsset.Object != nullptr)
{
item->SetStaticMesh(MeshAsset.Object);
}
item->SetFlags(RF_Transactional);
// add instance to actor level
this->AddInstanceComponent(item);
// make the scene component for the mesh to be visible
RootComponent = Root;
// attach mesh to the scene component of the actor in form of a Hierarchy
item->AttachToComponent(ChildSceneComponent, FAttachmentTransformRules::KeepWorldTransform, m_name);
ChildSceneComponent->AttachToComponent(Root, FAttachmentTransformRules::KeepWorldTransform, c_name);
// set mesh transform based on the ith position
FTransform t(FVector(250 * i, i, i));
// activate the new copy of the mesh
Mesh->AddInstance(t);
// Offset and scale the child scene from the root scene as a precaution
ChildSceneComponent->SetRelativeTransform(
FTransform(FRotator(0, 0, 0),
FVector(250 * i, i, i),
FVector(0.1f))
);
}
PrimaryActorTick.bCanEverTick = true;
}
答案 1 :(得分:0)
您对CreateDefaultSubobject的两次不同调用使用了相同的名称。
我在新的UE4 C ++项目中运行了您的代码,并收到以下错误消息:
致命错误: [文件:D:\ Build ++ UE4 \ Sync \ Engine \ Source \ Runtime \ CoreUObject \ Private \ UObject \ UObjectGlobals.cpp] [Line:3755]已经有默认的子对象StaticMeshComponent Sphere FlowSphere /Script/MyProject.Default__FlowSphere存在。
此外,您发布的代码未编译。
item.AttachTo(this->RootComponent);
应该是:
item->AttachTo(this->RootComponent);
,并且您还需要包含“ Components / StaticMeshComponent.h”。这是更正的代码:
#include "FlowSphere.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
AFlowSphere::AFlowSphere()
{
int32 amount = 100;
RootComponent = CreateDefaultSubobject<USceneComponent>("SceneComponent");
for (int32 i = 0; i < amount; i++) {
FName name = *FString::Printf(TEXT("Sphere %i"), i);
UStaticMeshComponent* item = CreateDefaultSubobject<UStaticMeshComponent>(name);
item->AttachTo(this->RootComponent);
}
this->test = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("HELLO"));
PrimaryActorTick.bCanEverTick = true;
}