2

良い一日!アンリアル エンジン 4.12 の勉強を始めて 1 週間が経ちました。あなたの裁量のために - 私は 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として作成する
  • 武器を 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 に答える