2

再会!我刚开始学习虚幻引擎 4.12 一个星期。由您自行决定 - 我对 C++ 编程知之甚少。(虽然我使用 PHP 进行编码,所以我在一定程度上理解了 OOP) - 而且,我只是对可视化脚本(蓝图)有点熟悉。

我想做的是通过加载一个新的静态网格来更改玩家的武器,该静态网格将来自文件路径。目前没有蓝图节点可以做到这一点,许多文章/论坛都建议构建我自己的蓝图节点。

我做了一些研究,发现了这个:Dynamic Load Object C++ ——它很有前途——但是,我不知道如何实现它。我尝试打开 MyProject.h 并将其粘贴到那里,但我不确定下一步该做什么 - 它会变成一个函数吗?还是蓝图节点?

我对如何实现我想要的其他建议(或方向)持开放态度。如果还有其他方法可以实现这一点,请分享并教育我。非常感谢!

真挚地,

克里斯

4

1 回答 1

2

静态负载只是帮手。只有通过 UFUNCTION(...) 宏标记该函数的标头,才能调用 C++ 函数。请参阅链接。

所以你可以创建你的函数,在它的实现中,你可以调用那个助手。例如:

// Helpers.h
static FORCEINLINE UTexture2D* GetTexture2DByName(const FName& name) {
    return LoadObjFromPath<UTexture2D>(name);
}

UFUNCTION(BlueprintCallable, Category = TCF2Helpers)
    static UTexture2D* GetTexture2DForBlock(UBuildableBlockInfo* blockInfo);


// Helpers.cpp
UTexture2D* UHelpers::GetTexture2DForBlock(UBuildableBlockInfo* blockInfo)
{
    if (!blockInfo)
        return nullptr;

    const FString baseFolder = TEXT("Texture2D'/Game/Textures/HUD/%s");

    if (blockInfo->IsEmptyHand)
        return GetTexture2DByName(*FString::Printf(*baseFolder, TEXT("EmptyHand.EmptyHand'")));

    // another lines of implementation
}

但是您需要问自己,是否真的需要对其进行硬编码。您可以指定类似

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Widgets")
    TSubclassOf<class UObjectWidget> wInGameMenu;

UPROPERTY(BlueprintReadOnly, Category = "Widgets")
    UObjectWidget* InGameMenu;

在覆盖函数 BeginPlay 的位置(这是由于动态创建小部件)我有:

if (wInGameMenu)
{
    InGameMenu = CreateWidget<UObjectWidget>(this, wInGameMenu);
}

UObjectWidget是 UUserWidget 的继承者,的小部件(在编辑器中创建)被重新设置为将该小部件作为继承基础。我定义了应该在包含它的对象的原型上创建哪个小部件。

我会这样实现它:(如果有人告诉我更好的方法,这可能会改变)

  • 创建WeaponManager作为 ActorComponent
  • 将Weapon创建为 SceneComponent(因此您可以将其附加到骨架套接字上)
  • 每个武器都有基于相同接口的自己的实现(可能覆盖共同祖先中定义的某些功能?)
  • 您可以拥有多个子子项(能量武器、射击武器等),因此您可以正确继承并避免多次实现同一事物。
  • 每个武器都会定义它的网格和属性——同样,如果你对网格路径进行硬编码(因为它是实现,所以没关系),你可以使用该列表末尾的代码)或者你可以在原型上设置它,如果你愿意喜欢在蓝图中编写代码。
  • 然后在WeaponManager中定义所有武器(例如TArray<TSubclassOf<UWeapon>>
  • 每个武器都应该定义EWeaponType - 游戏中所有武器的枚举,所以我可以将定义的武器与它在 TMap 中的类型匹配,然后简单地按需使用它(显示、隐藏、更改武器等)该类型应该被硬编码到所有实现的武器。

在构造函数中加载网格:

//TerminalObject.h
UCLASS()
class TAUCETIF2_API ATerminalObject : public AStaticMeshActor
{
    GENERATED_UCLASS_BODY()
};

// TerminalObject.cpp
ATerminalObject::ATerminalObject(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{

    static ConstructorHelpers::FObjectFinder<UStaticMesh> mesh(TEXT("StaticMesh'/Game/BuildingObjects/Meshes/terminal.terminal'"));

    checkf(mesh.Succeeded(), TEXT("Failed to find mesh"));

    auto mc = GetStaticMeshComponent();
    checkf(mc, TEXT("Failed to find mesh component"));

    mc->SetStaticMesh(mesh.Object);
}
于 2016-06-28T19:18:06.300 回答