【问题标题】:Dynamically create a SphereComponent in UnrealEngine在 UnrealEngine 中动态创建一个 SphereComponent
【发布时间】:2022-01-07 17:21:14
【问题描述】:

我正在尝试在关卡启动 2 秒后动态创建一个 SphereComponent。为此,我有以下代码:

void ACollidingPawnSpawnPawns::DelayedFunction() {
         // The first parameter 'SphereComponent' is the main component in the level and it has been created using the CreateDefaultSubobject method in the constructor of this class.  But that method can't be used outside the constructor.
         USphereComponent *dynamicallyCreatedSphere = NewObject<USphereComponent>(SphereComponent, USphereComponent::StaticClass());
             dynamicallyCreatedSphere ->InitSphereRadius(30.0f);
             dynamicallyCreatedSphere ->SetCollisionProfileName(TEXT("Pawn"));
             dynamicallyCreatedSphere ->SetRelativeLocation(FVector(155.0f, 165.0f, 45.0f));
             dynamicallyCreatedSphere ->SetVisibility(true);
 }

运行关卡后,我看不到这个动态球体弹出。

对于确实显示的主要“SphereComponent”,此代码位于构造函数中:

// Our root component will be a sphere that reacts to physics
 SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));
 RootComponent = SphereComponent;
 SphereComponent->InitSphereRadius(40.0f);
 SphereComponent->SetCollisionProfileName(TEXT("Pawn"));
 
    // Create and position a mesh component so we can see where our sphere is
     UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
     SphereVisual->SetupAttachment(RootComponent);
     static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
     if (SphereVisualAsset.Succeeded())
     {
         SphereVisual->SetStaticMesh(SphereVisualAsset.Object);
         SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));
         SphereVisual->SetWorldScale3D(FVector(0.8f));
     }

但我又不能使用 CreateDefaultSubobject 在构造函数之外创建 UStaticMeshComponent。

所以我想我要在我的关卡中看到我的 dynamicCreatedSphere,我必须创建一个 UStaticMeshComponent 并且我需要 FObjectFinder 方法的一些变体来调用(这个 FObjectFinder 在构造函数之外也不起作用)。

我已经坚持了一段时间了。有人知道怎么做吗?

2021 年 12 月 2 日更新 感谢下面https://stackoverflow.com/a/70180682/4722577 的建议,这是我必须动态创建球体的最终代码:

在cpp文件中:

void ACollidingPawnSpawnPawns::spawnPawns()
{
    if (dynamicallyCreatedSphere == nullptr) {
        //dynamicallyCreatedSphere = NewObject<USphereComponent>(USphereComponent::StaticClass()); // compiles
        dynamicallyCreatedSphere = NewObject<USphereComponent>(SphereComponent, USphereComponent::StaticClass());
        //dynamicallyCreatedSphere->SetupAttachment(SphereComponent);
        dynamicallyCreatedSphere->InitSphereRadius(30.0f);
        dynamicallyCreatedSphere->SetCollisionProfileName(TEXT("Pawn"));
        dynamicallyCreatedSphere->SetRelativeLocation(FVector(155.0f, 165.0f, 45.0f));
        dynamicallyCreatedSphere->SetVisibility(true);


        dynamicMesh = NewObject<UStaticMeshComponent>(this);
        dynamicMesh->AttachToComponent(dynamicallyCreatedSphere, FAttachmentTransformRules::KeepWorldTransform);
        dynamicMesh->RegisterComponent();
        dynamicMesh->SetStaticMesh(StaticMesh);
    }
}

在 .h 文件中,我有以下 3 行:

UPROPERTY(EditAnywhere)
UStaticMesh* StaticMesh;

USphereComponent* dynamicallyCreatedSphere = nullptr;
UStaticMeshComponent* dynamicMesh = nullptr;

将 StaticMesh 声明为 UProperty 允许我在 UE 界面中手动选择网格。然后当我运行关卡时,StaticMesh 被插入到 dynamicMesh 变量中。

【问题讨论】:

    标签: c++ unreal-engine4 unreal-engine5


    【解决方案1】:

    首先,只有NewObject可以在构造函数之外创建组件:

    void ACollidingPawnSpawnPawns::DelayedFunction() 
    {
        // you should specify outer as current actor (because this component is part of it)
        USphereComponent* DynamicallyCreatedSphere = NewObject<USphereComponent>(this, USphereComponent::StaticClass());
        DynamicallyCreatedSphere->RegisterComponent();
        // when component is dynamically created, you can use AttachToComponent, not SetupAttachment
        DynamicallyCreatedSphere->AttachToComponent(GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
        DynamicallyCreatedSphere->InitSphereRadius(30.0f);
        DynamicallyCreatedSphere->SetCollisionProfileName(TEXT("Pawn"));
        DynamicallyCreatedSphere->SetRelativeLocation(FVector(155.0f, 165.0f, 45.0f));
        DynamicallyCreatedSphere->SetVisibility(true);
    }
    

    您可以使用LoadObject 代替FObjectFinder 来使用指定路径加载某些内容。但我认为这是不合时宜的方式,因为 ref 是硬编码的。 在 UCLASS 中使用以下代码:

    UPROPERTY(EditAnywhere) 
    UStaticMesh* StaticMesh;
    

    并直接指定静态网格:SphereVisual-&gt;SetStaticMesh(StaticMesh);

    之后,您可以继承 C++ 类来蓝图并从 Content Browser 中选择 StaticMesh。

    【讨论】:

    • 完美,成功了!我没有考虑在 UnrealEngine 上选择网格,然后在代码引用中这样做。
    猜你喜欢
    • 2017-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多