【UE5内でプログラミングをできるようにする】その1 線をつなげる

オブジェクト同士をつなぐ

完成イメージ

今回の目標は、UEのブループリントみたいなのをステージ上で実現したいという目的もあるので、各ノードをつなげるラインみたいなのを実現したいですね。

というわけで、とりあえずアクター同士を線で繋げられるようにしてみようと思います。

C++クラスを作って、以下のようにします。

BP_Block_Asset.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "IConnectable.h"
#include "BP_Block_Asset.generated.h"

UCLASS()
class MYGAME_API ABP_Block_Asset : public AActor, public IIConnectable
{
    GENERATED_BODY()

public:
    // Sets default values for this actor's properties
    ABP_Block_Asset();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    // IIConnectable implementation
    virtual void ConnectTo(UObject* Other) override;
    virtual void DisconnectFrom(UObject* Other) override;

    // Block properties
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Block Properties")
    int32 BlockValue;

    // Function to execute
    virtual void ExecuteFunction();

private:
    void UpdateConnectionLines();
    TArray<IIConnectable*> ConnectedBlocks; // List of connected blocks
};

BP_Block_Asset.cpp

#include "BP_Block_Asset.h"
#include "DrawDebugHelpers.h"

// Sets default values
ABP_Block_Asset::ABP_Block_Asset()
{
    PrimaryActorTick.bCanEverTick = true;
}

// Called when the game starts or when spawned
void ABP_Block_Asset::BeginPlay()
{
    Super::BeginPlay();
}

// Called every frame
void ABP_Block_Asset::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
    UpdateConnectionLines();
}

// IIConnectable implementation
void ABP_Block_Asset::ConnectTo(UObject* Other)
{
    IIConnectable* OtherConnectable = Cast<IIConnectable>(Other);
    if (OtherConnectable && !ConnectedBlocks.Contains(OtherConnectable))
    {
        ConnectedBlocks.Add(OtherConnectable);
        UE_LOG(LogTemp, Log, TEXT("Connected to another block."));
    }
}

void ABP_Block_Asset::DisconnectFrom(UObject* Other)
{
    IIConnectable* OtherConnectable = Cast<IIConnectable>(Other);
    if (OtherConnectable && ConnectedBlocks.Contains(OtherConnectable))
    {
        ConnectedBlocks.Remove(OtherConnectable);
        UE_LOG(LogTemp, Log, TEXT("Disconnected from another block."));
    }
}

// Example function implementation
void ABP_Block_Asset::ExecuteFunction()
{
    UE_LOG(LogTemp, Log, TEXT("Executing function in block."));
}

// Update visual connection lines
void ABP_Block_Asset::UpdateConnectionLines()
{
    for (IIConnectable* ConnectedBlock : ConnectedBlocks)
    {
        if (ConnectedBlock)
        {
            AActor* ConnectedActor = Cast<AActor>(ConnectedBlock);
            if (ConnectedActor)
            {
                FVector Start = GetActorLocation();
                FVector End = ConnectedActor->GetActorLocation();
                DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, -1, 0, 5.0f);
            }
        }
    }
}

全体の流れ

  1. インターフェースの定義 (IConnectable.h)

    • IConnectable は UInterface を基にしてインターフェースを定義します。

  2. クラスでのインターフェースの実装 (BP_Block_Asset)

    • インターフェースを実装するクラス (BP_Block_Asset) で、インターフェースのメソッドを IIConnectable を使って実装します。

次のステップ: 機能の実装とテスト

1. 派生クラスの作成

各Blockが持つ特有の機能を追加するために、BP_Block_Asset を基底クラスとした派生クラスを作成します。例えば、BP_Block_Storage や BP_Block_Logic などです。

BP_Block_Storage.h

#pragma once

#include "CoreMinimal.h"
#include "BP_Block_Asset.h"
#include "BP_Block_Storage.generated.h"

UCLASS()
class MYGAME_API ABP_Block_Storage : public ABP_Block_Asset
{
    GENERATED_BODY()

public:
    ABP_Block_Storage();

protected:
    virtual void ExecuteFunction() override;
};

BP_Block_Storage.cpp

#include "BP_Block_Storage.h"

ABP_Block_Storage::ABP_Block_Storage()
{
    // Initialization code
}

void ABP_Block_Storage::ExecuteFunction()
{
    // Implement storage-specific functionality
    UE_LOG(LogTemp, Log, TEXT("Executing storage function in block."));
}

それでは、組んだらテストしてみます。

この記事が気に入ったらサポートをしてみませんか?