大家好!我刚刚开始学习虚幻引擎4.12一个星期了。请注意,我对c++编程知之甚少。(虽然我使用PHP编写代码,所以我在某种程度上理解OOP) -而且,我只是对可视化脚本(蓝图)有点熟悉。
我想做的是通过加载一个新的静态网格来改变玩家的武器,该静态网格将来自文件路径。目前还没有蓝图节点这样做,许多文章/论坛都建议建立自己的蓝图节点。
我做了一些研究,我发现了这个:动态加载对象c++ -它是非常有前途的-但是,我没有实现它的知识。我试着打开MyProject.h并将其粘贴在那里,我不确定下一步该做什么-它是否成为一个函数?还是蓝图节点?
关于如何实现我想要的,我愿意接受其他的建议(或方向)。如果有其他方法可以做到这一点,请分享和教育我。非常感谢!真诚克里斯静态加载只是辅助。只有当你用UFUNCTION(…)宏标记函数头时,你才能调用c++函数。请看这个链接。
你可以创建你的函数在它的实现中,你可以调用那个helper。例如:
// 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的继承者,我的小部件(在编辑器中创建)被重命名为将该小部件作为继承基。我定义了应该在保存它的对象的原型上创建哪个小部件。
我会这样实现它:(如果有人告诉我更好的方法,这可能会改变)
- 创建武器库作为ActorComponent
- 创建武器作为SceneComponent(所以你可以把它附加在骨架套接字上)
- 每个武器将有它自己的实现基于相同的接口(可能覆盖一些函数定义在共同的祖先?)
- 你可以有多个子(能量武器,射击武器等),所以你有正确的继承,你避免了多个实现相同的东西。
- 每一个武器将定义它的网格和属性-再次,如果你硬编码的网格路径(这是OK的,因为它是实现),你可以使用这样的代码在该列表的末尾),或者你可以在原型上设置,如果你想在蓝图中编码的东西。然后在WeaponManager中定义所有武器(例如
TArray<TSubclassOf<UWeapon>>
) - 每个武器应该定义EWeaponType - enum在游戏中的所有武器,所以我可以匹配定义的武器与它的类型在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);
}