[UE4]C++コードで作った関数をBlueprintから呼ぶ


何番煎じかわからないですが自分のメモがてら記事にしてみました。
Blueprintで大体の事はできるUnrealですが、いざ既存のC++Libraryのメソッドを使ってみたかったり、Blueprintではロジックを組みのが困難、または肥大化してしまいそうなケースが多々あります。
また、Unrealは独自のC++ルールが存在し、ビルドシステムも特殊です。
今回はその基本となる、まず独自メソッドをC++で実装し、Blueprintで実行するところまでいきたいと思います
お付き合いくださいませ。
VisualStudioがインストール済みである前提でスタートいたします。 私の環境は Windows10, UE4.22.3、 VisualStudio2017 です。



・プロジェクトの新規作成

まずは新規でプロジェクトを生成しましょう。
" NewProject -> C++ -> BasicCode " を選択し"CppTestProject"と名前を付けて " CreateProject" してください
C++ Window から生成することで、最初からVisualStudioのプロジェクトファイルである .sln(ソリューションファイル)がプロジェクト内に一緒に生成されます。
別にBlueprintから作っても、あとから .uproject を右クリックして "Generate VisualStudio Project files" をクリックすると生成されるので順序はどちらでも大丈夫です。


New Projectから C++ の Basic Code を選択して...


Create Project!!


生成したプロジェクトの .sln ファイルを開くとプロジェクトのソースコードが一覧できます
このプロジェクトをビルドするとUnrealEditorが立ち上がり、生成したプロジェクトのEditor画面が開きます。


無事生成されましたでしょうか!?OKそうだったらお次へどうぞ!



・UEエディタから新規C++コンポーネントの作成

それではEditorからC++コードを追加します。
ContentBrowserの "Add New -> New C++ Classes" をクリックして "Add C++ Class" ウィンドウを開きます。


そして "Actor" を選択して "Next"をクリックし、名前は "MyCppActor" とし、右にはPublicかPrivateか選ぶフィールドあるので "Private" にして "Create Class" してください。
このPublicかPrivateを選ぶ意味は、今回作るクラスをモジュールとして外部に公開するかどうかです。
この辺の詳しい説明はまたどこかでするとして、とりあえず「自分で使う分にはPrivate」で問題ありません。
追加した時点で一度Editor側でコンパイルが走るので待ちましょう。




当然VisualStudio側から直接C++コードを追加することもできるのですが、はじめのうちはEditorからの作法に乗っておいた方がいいでしょう。

それではVisualStudioウィンドウに移動してプロジェクト内に先ほど追加したC++クラスが存在するのを確認しましょう。


...いましたか?いたら次のステップへGO(^^)



・実装コードの記述してコンパイル

それでは実際にコードを記述していきます。

MyCppActor.h

	
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyCppActor.generated.h"

UCLASS()
class AMyCppActor : public AActor
{
	GENERATED_BODY()
	
public:	
	AMyCppActor();

	//UEで扱うための変数
	//EditAnyware UE EditorからでもBlueprintからでも変更できるプロパティ
	//BlueprintReadWrite Blueprint側で Get Set メソッドを使用できるようにする
	//Category 変数のカテゴリ。無くても良い
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iwax UE Cpp")
		FVector Location;

	//UEで扱うための関数
	//BlueprintCallable Blueprintから呼び出し可能な関数
	//Category UFUNCTIONの場合は必須項目
	UFUNCTION(BlueprintCallable, Category = "Iwax UE Cpp")
		static void printFunction();

protected:
	//ゲーム開始時に呼ばれる関数
	virtual void BeginPlay() override;

	//ゲーム終了時に呼ばれる関数
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

public:	

	//ゲーム中、毎フレーム呼ばれる関数
	virtual void Tick(float DeltaTime) override;

};
	
	

MyCppActor.cpp

	
#include "MyCppActor.h"

//GENgineを使う場合にインクルード
//Engineへのポインタを扱い実行コアから情報を取得する
#include "Engine.h"

//============================================================
AMyCppActor::AMyCppActor()
{
	//これをtrueにしないとTick関数は動作しない	
	PrimaryActorTick.bCanEverTick = true;

	//位置の初期化
	Location.Set(10, 10, 0);

}


//============================================================
void AMyCppActor::BeginPlay()
{
	Super::BeginPlay();
	
	//UE C++で文字列を扱う FString 変数を宣言し、GetActorLabel()で自身のActor名を取得する
	FString Message = GetActorLabel() + " BeginPlay()";

	//GEngineの存在確認
	if (GEngine)
	{
		//5秒間、赤色でメッセージを表示
		GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, Message);
	}
}


//============================================================
void AMyCppActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);

	//BeginPlayとほぼ一緒 出力の色だけ変えている
	FString Message = GetActorLabel() + " EndPlay()";
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, Message);
	}

}


//============================================================
void AMyCppActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	//Locationの現在位置を出力
	FString Message = FString::Printf(TEXT("Actor Position x:%f, y%f, z%f"), Location.X, Location.Y, Location.Z);
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Green, Message);
	}
}

//============================================================
void AMyCppActor::printFunction()
{
	//BeginPlayとほぼ一緒 出力の色だけ変えている
	FString Message = "Hello world!";
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Blue, Message);
	}
}
	
	

上記コードの入力ができたらEditor側に戻って実際にコンパイルをしてみましょう!
コンパイルが無事に済んだら次のステップへどうぞ




・Blueprintから実行してみる

それでは先ほどコンパイルしたC++コードをBlueprint側から読んでみたいと思います。
まず、LevelBlueprintを使うために現在のMapを保存しておきましょう。
どこでもかまいませんが、私は新規に"Maps"というフォルダを作り"MyMap"という名で保存することにします


保存出来たら先ほどコンパイルしたMyCppActorをEditorのViewにドラッグアンドドロップします。


WorldOutlinerに追加されたらLebelBlueprintを開いて...


以下のようにノードを並べてみましょう


したらば、いざプレイです!!

ちょっと画面小さくて何やってるかイマイチわからない笑
操作としてはspaceキーを押すと"Hello World!!"がプリントされて、
追加したMyCppActorのDetailsにある "Iwax UE Cpp -> Location"のパラメータを変更すると、画面にプリントされている値が変化します



・お疲れさまでした

以上が基本中の基本となるUEでのC++の扱い方となります。
如何だったでしょうか?なんとなく感覚つかめましたか?
まだまだ継承する基本クラスの把握や非同期処理、Pluginの作り方などDeepな部分が沢山ありますが、それを少しずつ吸収していって楽しいUEライフを送りましょう。
この記事がそんなUEライフを過ごそうとしている誰かの助けになれば幸いです。
それではまた次回の記事でお会いしましょう。


copyright @2019 Hiromitsu Iwanaka