[UE5.3][VisualStudio]C++プラグインを作る方法

ポジTAさんのこのぺーじをvs2022でやる

https://zenn.dev/posita33/books/ue5_starter_cpp_and_bp_001/viewer/chap_01_vs2019_setup

C++Pluginの作り方

C++ Pluginの作成

プロジェクトを作成する際に「C++」でプロジェクトを作成します。

[Edit] > [Plugins]を選択します。

独自のPluginを作成するには左上の「Add」ボタンをクリックします。

プラグインの作成手順は以下の手順になります。

  1. Pluginのテンプレートを選択する
  2. Plugin名を入力する
  3. Plugin情報を入力する(任意)
  4. Create Pluginをクリック

Author制作者名
DescriptionPluginの説明
Author URL制作者のPlugin説明用のURLを書いておくとPluginの制作者名をクリックするとURLに移動する
Is Beta Versionチェックボックスを有効にすると、Plugin名の横にBetaが表示される

Pluginのウィンドウで作成したPlugin名を検索すると一覧に登録されています。

Editボタンや(Plugin名).pluginファイルで設定をより詳細に変更できます。

色々設定して128×128のアイコン設定して。。

ContentsBrowserやVisualStudioに追加されたPluginが表示されます。

以下の感じで吐き出される

furcraeaBluePrintLib.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Modules/ModuleManager.h"

class FfurcraeaBluePrintLibModule : public IModuleInterface
{
public:

	/** IModuleInterface implementation */
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
};

furcraeaBluePrintLib.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "furcraeaBluePrintLib.h"

#define LOCTEXT_NAMESPACE "FfurcraeaBluePrintLibModule"

void FfurcraeaBluePrintLibModule::StartupModule()
{
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
	
}

void FfurcraeaBluePrintLibModule::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.
	
}

#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FfurcraeaBluePrintLibModule, furcraeaBluePrintLib)

furcraeaBluePrintLibBPLibrary.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Kismet/BlueprintFunctionLibrary.h"
#include "furcraeaBluePrintLibBPLibrary.generated.h"

/* 
*	Function library class.
*	Each function in it is expected to be static and represents blueprint node that can be called in any blueprint.
*
*	When declaring function you can define metadata for the node. Key function specifiers will be BlueprintPure and BlueprintCallable.
*	BlueprintPure - means the function does not affect the owning object in any way and thus creates a node without Exec pins.
*	BlueprintCallable - makes a function which can be executed in Blueprints - Thus it has Exec pins.
*	DisplayName - full name of the node, shown when you mouse over the node and in the blueprint drop down menu.
*				Its lets you name the node using characters not allowed in C++ function names.
*	CompactNodeTitle - the word(s) that appear on the node.
*	Keywords -	the list of keywords that helps you to find node when you search for it using Blueprint drop-down menu. 
*				Good example is "Print String" node which you can find also by using keyword "log".
*	Category -	the category your node will be under in the Blueprint drop-down menu.
*
*	For more info on custom blueprint nodes visit documentation:
*	https://wiki.unrealengine.com/Custom_Blueprint_Node_Creation
*/
UCLASS()
class UfurcraeaBluePrintLibBPLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()

	UFUNCTION(BlueprintCallable, meta = (DisplayName = "Execute Sample function", Keywords = "furcraeaBluePrintLib sample test testing"), Category = "furcraeaBluePrintLibTesting")
	static float furcraeaBluePrintLibSampleFunction(float Param);
};

furcraeaBluePrintLibBPLibrary.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "furcraeaBluePrintLibBPLibrary.h"
#include "furcraeaBluePrintLib.h"

UfurcraeaBluePrintLibBPLibrary::UfurcraeaBluePrintLibBPLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{

}

float UfurcraeaBluePrintLibBPLibrary::furcraeaBluePrintLibSampleFunction(float Param)
{
	return -1;
}

参考URL

全部ポジTAさんですありがとうございます。

https://zenn.dev/posita33/books/ue5_posilab_ue_research_and_development/viewer/category_350_pulugin_start

[UE5.3]C++プロジェクトをリフレッシュプロジェクトファイルの作成時にエラーが発生しました

Running D:/Program Files/Epic Games/UE_5.3/Engine/Build/BatchFiles/Build.bat  -projectfiles -project="D:/Sandbox/UE53CratePlugin/UE5_VS/UE5_VS.uproject" -game -rocket -progress
Using bundled DotNet SDK version: 6.0.302
Running UnrealBuildTool: dotnet "..\..\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll" -projectfiles -project="D:/Sandbox/UE53CratePlugin/UE5_VS/UE5_VS.uproject" -game -rocket -progress
Log file: C:\Users\furcr\AppData\Local\UnrealBuildTool\Log_GPF.txt

Generating VisualStudio2019 project files:
Discovering modules, targets and source code for project...
Visual Studio 2019 does not support .NET 6.0 C# projects, these projects will not be added to the generated solution.
Please generate the Visual Studio 2022 solution if .NET 6.0 C# project support is required.
Microsoft platform targets must be compiled with Visual Studio 2022 17.4 (MSVC 14.34.x) or later for the installed engine. Please update Visual Studio 2022 and ensure no configuration is forcing WindowsTargetRules.Compiler to VisualStudio2019. The current compiler version was detected as: 14.29.30154

つまりは

D:/Program Files/Epic Games/UE_5.3/Engine/Build/BatchFiles/Build.bat -projectfiles -project="D:/Sandbox/UE53CratePlugin/UE5_VS/UE5_VS.uproject" -game -rocket -progress を実行しています
バンドルされた DotNet SDK バージョン 6.0.302 を使用しています
UnrealBuildTool を実行しています: dotnet "..\..\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll" -projectfiles -project="D:/Sandbox/UE53CratePlugin/UE5_VS/UE5_VS.uproject" -game -rocket -progress
ログ ファイル: C:\Users\furcr\AppData\Local\UnrealBuildTool\Log_GPF.txt

VisualStudio2019 プロジェクト ファイルを生成しています:
プロジェクトのモジュール、ターゲット、ソース コードを検出しています...
Visual Studio 2019 .NET 6.0 C# プロジェクトをサポートしていないため、これらのプロジェクトは生成されたソリューションに追加されません。
.NET 6.0 C# プロジェクトのサポートが必要な場合は、Visual Studio 2022 ソリューションを生成してください。
インストールされているエンジンでは、Microsoft プラットフォーム ターゲットを Visual Studio 2022 17.4 (MSVC 14.34.x) 以降でコンパイルする必要があります。Visual Studio 2022 を更新し、WindowsTargetRules.Compiler を VisualStudio2019 に強制する構成がないことを確認してください。現在のコンパイラ バージョンは 14.29.30154 として検出されました。

VS2022をつかえってこと

したらエラーでなくなった  

[Maya]Mayaで同じトポロジーを持ったオブジェクトの頂点番号を合わせる ReorderVertices (Shift+クリックではありません)(1つのポリゴンを囲むようにクリックしてください)

mel :ReorderVertex;

Plug-in Manager内の「meshReorder. mll」にチェックマークを入れると機能がアクティブになります。
~Mayaの機能「Reorder Vertices」~
Maya2017から新規に追加された機能で、頂点番号を後から調整することが可能です。

以下より
https://help.autodesk.com/view/MAYAUL/2025/JPN/?guid=GUID-8CF82D97-203C-4056-BEF2-EA0CD27336ED

https://help.autodesk.com/view/MAYACRE/JPN/?guid=GUID-8CF82D97-203C-4056-BEF2-EA0CD27336ED

頂点の順序を変更するには

1,頂点の順序を変更するポリゴン オブジェクトのヒストリを削除します。
2,ディスプレイ> ポリゴン > コンポーネント ID > 頂点(Display > Polygons > Component IDs > Vertices)に移動し、オブジェクトの頂点 ID を選択して表示します。
3,頂点の順序を変更(Reorder Vertices)コマンドを選択します。
4,設定する新しい頂点の順序の最初の 3 つの頂点に関連する 3 つの隣接する頂点をクリックします。
(Shift+クリックではありません)(1つのポリゴンを囲むようにクリックしてください)
Maya では、設定した初期パスに基づいて、残りの頂点が並べ替えられます。

注: 頂点の順序を変更(Reorder Vertices)コマンドは、異なるコマンドやツールに切り替えるまでアクティブであるため、希望の順序になるまで新しい頂点の順序を繰り返し試すことができます。


頂点を手動で並べ替えるのではなく、頂点の順序を転送(Transfer Vertex Order)コマンドを使用して、1 つのオブジェクトから別のオブジェクトに頂点の順序を転送できます。

注: 最良の結果を得るには、まず、2 つのメッシュのトポロジが類似していることを確認します。
1 つのメッシュから別のメッシュに頂点の順序を転送するには

1,転送に関連する両方のオブジェクトのヒストリを削除します。
2,ディスプレイ > ポリゴン > コンポーネント ID > 頂点(Display > Polygons > Component IDs > Vertices)に移動し、オブジェクトの頂点 ID を選択して表示します。
頂点の順序を転送(Transfer Vertex Order)コマンドを選択します。
ソース オブジェクト上で 3 つの隣接する頂点をクリックします。
(Shift+クリックではありません)(1つのポリゴンを囲むようにクリックしてください)
ソース オブジェクト上で選択した 3 つの頂点とトポロジ的に関連しているターゲット オブジェクト上の 3 つの隣接する頂点をクリックします。
(Shift+クリックではありません)(1つのポリゴンを囲むようにクリックしてください)
選択した 3 つのベース頂点とソース オブジェクトが相対関係になるように、残りの頂点が並べ替えられます。

参考URL

[ue5.3.2]最適化用 debug shader 重い、Texture重いとか 最適化UE5night デバッグ&チューニングナイトのメモ

ライティングあり>最適化ビューモード>シェーダー複雑度

level選択してサイズマップすれば重い原因がわかる。

マップの中で重いテクスチャなどを見つける Level>サイズマップ

Niniteは雑にStaticMeshアセットに全部使ってしまった方が軽いらしい。

: プロジェクト設定->入力->Console->Console Keysでキーを追加。
デフォルトで「`」が割り当たっているが、日本語キーボードだと打つことが出来ないため、「@」キーを追加しておく。

@stat anim でどの処理が何秒つかってるかが見れる

他コマンドはこちら

https://historia.co.jp/archives/1342

@fpsでstat FPSを選ぶとFPSが表示できる

Build Configurationの内容DevelopmentやShippingなどを判別して毎のEventを取得できる。

テクスチャ>アセットアクション>プロパティマトリクスでMaximam Texture Sizeと検索して1024してみたりとか。

フレームレートを固定する。

プロジェクト設定>検索>FrameRate

こんな設定にしたら40FPSでかつキャラクタきれいに見えた

最終的に選んだ設定これだけ贅沢にして24FPS 

マテリアル品質もやりようある。

#UE5night デバッグ&チューニングナイトを開催してくださったぽちおさんならびに沢山の解答をくださった方々に感謝です。

関連

Unreal Engine 5: How To Fix “Video Memory Has Been Exhausted” (Temporary Fix For Development)

https://dev.epicgames.com/community/learning/tutorials/yrl7/unreal-engine-5-how-to-fix-video-memory-has-been-exhausted-temporary-fix-for-development

[UE5.3.2]Widgetを表示したり消したりしてshippingでは2重に表示されたりをどうにか解決したメモ。

基本はサチナシさんの教えてくれたこの二つのブログ

なんだけど結局どっちもやんなきゃ解決しなかったよ

変数初期化+ガベージコレクション+ブールでの判断

どこからでも呼べるようにGameModeにかいてるんだけど、こんなかんじで大丈夫だった。

ちなみに中身はあんまり関係ないけど乗せておく

WBP_NextText

イベントグラフ1

イベントグラフ2

イベントグラフ3

関数 If AnimSHow Hide

関数 Talker to Anim

関数 Set Text Function

おわり。

[ue5.3.2]キーボードイベントが反応しない場合の処置

今回はキー押してカメラを切り替えたい

レベルブループリント使ってキーは拾えるけど、レベルはバージョンアップで壊れがちなのでBPにしておきたい。

今回の場合はBP_CameraManagerなどを作ってレベルに配置することでカメラをコントロール可能にした

Auto Receive Input 「Player 0」などにしておくとキーイベントが使える。

どっちもきくようになった

[UE5.3.2]パッケージ化 292Wrapped by AutomationException: Cook failed. UE5

LogScript: Error: Script Msg: /Game/0_furcraeaTokyo/13_matahuman_UQ5motion/MF_Idle_MHUQ5 : アニメーション アセット (/Game/0_furcraeaTokyo/13_matahuman_UQ5motion/MF_Idle_MHUQ5.MF_Idle_MHUQ5) のターゲット USkeleton を取得できません
LogScript: Error: Script Msg: /Game/0_furcraeaTokyo/13_matahuman_UQ5motion/MF_Idle_MHUQ5 : 指定された USkeleton が無効

出力をよく見ているとが赤い文字の行がみつかりました。

MF_Idle_MHUQ5を検索して削除したらなおりました。

赤い文字の行を直していけば治るエラーでした。

参考URL

https://forums.unrealengine.com/t/unknown-cook-failure-cookcommand-automation-cs-249-wrapped-by-automationexception-cook-failed/138364/13

[UE5.3.2] UE5ぷちコンジェットコースター向け Blender の ベジェカーブ(BezierCurve)からUE5のSplineに座標わたせたよ(精度の問題で未完成)まとめ

ベジェカーブ作る前に日本語の場合は英語モードに切り替えなきゃスクリプトエラーになります。

BezierCurveはできるだけ大きく描きます。

BlenderPython

# Blender import
import bpy
import math
import bmesh
import csv

print("start python code....------------------------------------------>>>")

basedir="F:/SandBox/UE5PuchiCon22/Blender_Curve_To_Spline/"
with open(basedir+"/test.csv",'w',newline='') as file:

    writer = csv.writer(file,delimiter = ',') 
    count = 0
    writer.writerow(["","x","y","z",
            "i_x","i_y","i_z",
            "o_x","o_y","o_z"])
    
    print("bpy.data.curves= "+str(bpy.data.curves))
    for obj in bpy.data.curves:
        print("obj.name= "+str(obj.name))
        for object in bpy.data.objects:
            print("object.name= "+object.name)
        ob_curve = bpy.data.objects.get(obj.name)
        print("ob_curve= "+str(ob_curve))
        if(str(ob_curve)=="None"):
            print("ob_curve =is= NoneType")
        else:
            for curve in obj.splines:
                print("curve= "+str(curve))
                
                for bezpoint in curve.bezier_points:
                    print("bezpoint= "+str(bezpoint))
                    if(str(bezpoint)=="NoneType"):
                        print("bezpoint =is= NoneType")
                    else:
                        xyz = ob_curve.matrix_world @ bezpoint.co
                        xyz_left = ob_curve.matrix_world @ bezpoint.handle_left
                        xyz_right = ob_curve.matrix_world @ bezpoint.handle_right
                        count += 1
                        writer.writerow([count, xyz[0], xyz[1], xyz[2],
                        xyz_left[0], xyz_left[1], xyz_left[2],
                        xyz_right[0], xyz_right[1], xyz_right[2]])
            

出力されたCSV

値はかなり大きめじゃないとだめよ

,x,y,z,i_x,i_y,i_z,o_x,o_y,o_z
1,13.595291137695312,230.46768188476562,70.73152160644531,158.9687042236328,225.82052612304688,70.73152160644531,-178.57012939453125,236.6106414794922,70.73152160644531
2,-207.3365020751953,-38.245094299316406,120.08828735351562,-198.0128631591797,17.276376724243164,181.6839141845703,-222.84031677246094,-130.56887817382812,17.66411781311035
3,43.76624298095703,-265.9769287109375,0.0,-181.01539611816406,-265.9769287109375,0.0,258.02471923828125,-265.9769287109375,0.0
4,231.6976318359375,-64.63948059082031,49.9024543762207,191.0831298828125,-174.81529235839844,-94.65201568603516,255.28945922851562,-0.641462504863739,133.87005615234375

CSVにそって構造体作ります。ブループリント>構造体

CSVをUEにドラッグして読みこみ

BP_SplineにSplinrコンポーネント付けて、コンストラクションスクリプトでこれつくります。

なにかは描かれた

こっから先は精度の問題?

できたっていうのかなこれ。

ZIP
Blender_Curve_To_Spline.zip

https://drive.google.com/file/d/1n4y_EoBTJDpaKdJnUNLTfLLxueqsYcGm/view?usp=sharing

UE532_CurveSpline2.zip

https://drive.google.com/file/d/1uk8QwaZbL_PE1HEF8umtN76axFFBJAoC/view?usp=sharing

参考URL

https://blenderartists.org/t/world-location-of-bezier-points/1219282

https://teratail.com/questions/146037

Text Editorでデバッグ時にprintで出力したものがPython Consoleに出てこなくて困っていましたが、勘違いしていました。Python Consoleではなくて、System Consoleの方に出てきます。

メニューバー Window > Toggle System Console で別ウィンドウでコマンドプロンプトがたちあがります。

https://wiz.ooo/cg/2054

https://docs.blender.org/api/current/bpy.ops.mesh.html

https://zenn.dev/hotcocoa/articles/5c5ab06c40862b

https://reflectorange.net/archives/193.html

[C++]やさしいC++ プログラムをクラスで部品化する ちゃんと class という文字でクラス宣言できる。シンプルでOK

CarClass.cpp

#include <iostream>
using  namespace std;

//Carクラスの宣言
class Car{
	private:
		int num;
		double gas;

	public:
		Car();
		void  show();

};

//Car Class Member関数の定義 コンストラクタ
Car::Car()
{
	num=0;
	gas=0.0;
	cout << "車を作成しました \n";

}
//Car Class Member関数の定義 メソッド
void Car::show()
{
	cout << "車のナンバーは" << num << "です。\n";
	cout << "gasは" << gas << "です。\n";
}
//Car インスタンスの生成
int main(){
	Car car1;
	car1.show();
	return 0;
};

cd_samples5_6_class.cmd


C:\samples\chapter05\CarClass>cd C:\samples\chapter05\CarClass\

C:\samples\chapter05\CarClass>g++ CarClass.cpp -o CarClass.exe

C:\samples\chapter05\CarClass>CarClass.exe
車を作成しました
車のナンバーは0です。
gasは0です。

C:\samples\chapter05\CarClass>cmd /k
C:\samples\chapter05\CarClass>





[C++]スラスラわかるC++ プログラムをクラスで部品化する

HealthChecker.cpp

#include <iostream>
#include <string>
using namespace std;
#include "HealthChecker.h"

// 標準BMIを表すメンバ定数の実体
const int HealthChecker::STD_BMI = 22;

// BMIを返すメンバ関数の実装
double HealthChecker::getBmi() {
  // まだBMIが計算されていなかったら計算する
  if (this->bmi == 0) {
    double mHeight = this->height / 100;
    this->bmi = this->weight / mHeight / mHeight;
  }

  // BMIを返す
  return this->bmi;
}

// コンストラクタの実装
HealthChecker::HealthChecker(string name, double height, double weight) {
  // メンバ変数に初期値を設定する
  this->name = name;
  this->height = height;
  this->weight = weight;
  this->bmi = 0;
}

// 氏名を返すメンバ関数の実装
string HealthChecker::getName() {
  return this->name;
}

// 標準BMIを返すメンバ関数の実装
int HealthChecker::getStdBmi() {
  return HealthChecker::STD_BMI;
}

// 標準体重を返すメンバ関数の実装
double HealthChecker::getStdWeight() {
  double mHeight = this->height / 100;
  return HealthChecker::STD_BMI * mHeight * mHeight;
}

HealthChecker.h

class HealthChecker {
  private:
    static const int STD_BMI;		// 標準BMIを表すメンバ定数
    string name;			// 氏名を格納するメンバ変数
    double height;			// 身長を格納するメンバ変数
    double weight;			// 体重を格納するメンバ変数
    double bmi;				// BMIを格納するメンバ変数
  public:
    static int getStdBmi();		// 標準BMIを返すメンバ関数
    double getStdWeight();		// 標準体重を返すメンバ関数
    double getBmi();			// BMIを返すメンバ関数
    string getName();			// 氏名を返すメンバ関数
    HealthChecker(string name, double height, double weight); // コンストラクタ
};

list5_6.cpp

#include <iostream>
#include <string>
using namespace std;
#include "HealthChecker.h"

int main() {
  // HealthCheckerクラスのインスタンスを生成する
  HealthChecker yamada("山田一郎", 170, 67.5);

  // BMIの値を表示する
  cout << "BMIは、" << yamada.getBmi() << "です。" << endl;

  return 0;
}

cd_samples5_6_class.cmd


C:\samples\chapter05>cd C:\samples\chapter05\

C:\samples\chapter05>g++ list5_6.cpp HealthChecker.cpp -o list5_6.exe

C:\samples\chapter05>list5_6.exe
BMIは、23.3564です。

C:\samples\chapter05>cmd /k
C:\samples\chapter05>