[UE5.3.2][VisualStudio][Cpp]UnrealEngineのCPPプラグインからOpenAI(ChatGPT4o)を呼んで返り値jsonからパースしてPython部分を抜き出して実行!!できた!!!

今回も以下の続き

furcraeaUEOpenAIBPLibrary.h

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
#include "furcraeaUEOpenAIBPLibrary.generated.h"

UCLASS()
class UfurcraeaUEOpenAIBPLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()

public:
    UfurcraeaUEOpenAIBPLibrary(const FObjectInitializer& ObjectInitializer);

    UFUNCTION(BlueprintCallable, Category = "furcraeaUEOpenAI")
    static FString furcraeaUEOpenAISampleFunction(FString Param);

private:
    static FString SendChatCompletionRequest(FString UserMessage);
    static void OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);

    static void ResponseMessageToPythonCode(FString ResponseMessage);

    static bool RunMyPython(int32& ProcessId,
        FString FullPathOfProgramToRun, TArray<FString> CommandlineArgs, bool Hidden);
};

furcraeaUEOpenAIBPLibrary.cpp

#include "furcraeaUEOpenAIBPLibrary.h"
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"
#include "Json.h"
#include "JsonUtilities.h"
#include "String.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"
#include "Engine/Engine.h"
#include "PythonBridge.h"


//IMPLEMENT_GAME_MODULE(FDefaultGameModuleImpl, furcraeaUEOpenAIBPLibrary);

UfurcraeaUEOpenAIBPLibrary::UfurcraeaUEOpenAIBPLibrary(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
    UE_LOG(LogTemp, Warning, TEXT("Hello World! UfurcraeaUEOpenAIBPLibrary ObjectInitializer"));
}

FString UfurcraeaUEOpenAIBPLibrary::furcraeaUEOpenAISampleFunction(FString Param)
{
    FString UserMessage = Param;
    FString ResponseMessage = TEXT("");
    UE_LOG(LogTemp, Warning, TEXT("Hello World! furcraeaUEOpenAISampleFunction"));
    
	ResponseMessage= SendChatCompletionRequest(UserMessage);
    return ResponseMessage;
}

FString UfurcraeaUEOpenAIBPLibrary::SendChatCompletionRequest(FString UserMessage)
{
    FString ApiKey = TEXT("sk-から始まるキー");

    if (!FModuleManager::Get().IsModuleLoaded("Http"))
    {
        FModuleManager::Get().LoadModule("Http");
    }

    FHttpModule* Http = &FHttpModule::Get();
    if (!Http)
    {
        UE_LOG(LogTemp, Error, TEXT("Failed to get FHttpModule instance"));
        return FString();
    }

    TSharedRef<IHttpRequest, ESPMode::ThreadSafe> HttpRequest = Http->CreateRequest();
    HttpRequest->SetURL("https://api.openai.com/v1/chat/completions");
    HttpRequest->SetVerb("POST");
    HttpRequest->SetHeader("Content-Type", "application/json");
    HttpRequest->SetHeader("Authorization", "Bearer " + ApiKey);

    FString Content = FString::Printf(TEXT(R"(
    {
        "model": "gpt-4o-mini",
        "messages": [{"role": "user", "content": "%s"}],
        "temperature": 0.7
    }
    )"), *UserMessage);

    HttpRequest->SetContentAsString(Content);

    //HttpRequest->OnProcessRequestComplete().BindUObject(this, &UfurcraeaUEOpenAIBPLibrary::OnResponseReceived);
    HttpRequest->OnProcessRequestComplete().BindLambda([](FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
        {
            OnResponseReceived(Request, Response, bWasSuccessful);
        });
    HttpRequest->ProcessRequest();

    return FString();
}

void UfurcraeaUEOpenAIBPLibrary::OnResponseReceived(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
    if (bWasSuccessful && Response.IsValid())
    {
        FString ResponseContent = Response->GetContentAsString();
        TSharedPtr<FJsonObject> JsonObject;
        TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(ResponseContent);

        if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
        {
            FString MessageContent = JsonObject->GetArrayField("choices")[0]->AsObject()->GetObjectField("message")->GetStringField("content");
            UE_LOG(LogTemp, Warning, TEXT("OnResponseReceived() Response Message: %s"), *MessageContent);
            ResponseMessageToPythonCode(MessageContent);
        }
        else
        {
            UE_LOG(LogTemp, Error, TEXT("Failed to parse JSON response"));
        }
    }
    else
    {
        UE_LOG(LogTemp, Error, TEXT("Request failed"));
    }
}


static std::string replaceOtherStr(std::string& replacedStr, std::string from, std::string to) {
    const unsigned int pos = replacedStr.find(from);
    const int len = from.length();

    if (pos == std::string::npos || from.empty()) {
        return replacedStr;
    }

    return replacedStr.replace(pos, len, to);
}


void UfurcraeaUEOpenAIBPLibrary::ResponseMessageToPythonCode(FString ResponseMessage)
{
    //ResponseMessage の文字列から「```python」で始まり「```」で終わるまでの文字列を抜き出して
    


        // FString から標準文字列に変換
        FString aFString= ResponseMessage;
        std::string aString = TCHAR_TO_ANSI(*aFString);
        long aStartIndex = aString.find("```python");
        
        long aEndIndex = aString.rfind("```");

		long aLength = aEndIndex - aStartIndex;
        std::string aPythonCode =aString.substr(aStartIndex+9, aLength-9);

        replaceOtherStr(aPythonCode, "?", "//");
		// 標準文字列から FString に変換
		FString PythonCode = FString(aPythonCode.c_str());
        

        UE_LOG(LogTemp, Warning, TEXT("ResponseMessageToPythonCode() StartIndex: %u"), aStartIndex);
        UE_LOG(LogTemp, Warning, TEXT("ResponseMessageToPythonCode() EndIndex: %u"), aEndIndex);

        if (aStartIndex != 0 && aEndIndex != 0)
        {
            


            //FString PythonCode2 = ResponseMessage.Mid(StartIndex + 1, PythonCodeLength);
            UE_LOG(LogTemp, Warning, TEXT("ResponseMessageToPythonCode() 1 PythonCode: %s"), *PythonCode);
            //UE_LOG(LogTemp, Warning, TEXT("ResponseMessageToPythonCode() 2 PythonCode2: %s"), *PythonCode2);
            
             // Define the file path in the Saved directory
            FString FilePath = FPaths::ProjectSavedDir() / TEXT("ExtractedPythonCode.py");

            // Save the Python code to the file
            if (FFileHelper::SaveStringToFile(PythonCode, *FilePath))
            {
                UE_LOG(LogTemp, Warning, TEXT("Python code saved to: %s"), *FilePath);

                // Ensure the file path is correctly formatted for the exec command
                FString RelativeFilePath = FPaths::ConvertRelativePathToFull(FilePath);
                FString Command = FString::Printf(TEXT("py \"%s\""), *RelativeFilePath);
                //FString Command = FString::Printf(TEXT("\"%s\""), *RelativeFilePath);
				//GEngine->Exec(nullptr, *Command);

                UPythonBridge* bridge = UPythonBridge::Get();
                bridge->FunctionImplementedInPython();
                bridge->ExecuteCommand(RelativeFilePath);
            }
            else
            {
                UE_LOG(LogTemp, Error, TEXT("Failed to save Python code to file"));
            }


        }
        else 
        {
            UE_LOG(LogTemp, Warning, TEXT("ResponseMessageToPythonCode() PythonCode: in None"));
        }

    
}


PythonBridge.h (https://forums.unrealengine.com/t/running-a-python-script-with-c/114117/4)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Engine.h"
#include "UObject/NoExportTypes.h"
#include "PythonBridge.generated.h"

/**
 * 
 */
UCLASS(Blueprintable)
class FURCRAEAUEOPENAI_API UPythonBridge : public UObject
{
	GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable, Category = Python)
    static UPythonBridge* Get();

    UFUNCTION(BlueprintImplementableEvent, Category = Python)
    void FunctionImplementedInPython() const;

    UFUNCTION(BlueprintImplementableEvent, Category = Python)
    void ExecuteCommand(const FString& CommandName) const;
};

PythonBridge.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "PythonBridge.h"

UPythonBridge* UPythonBridge::Get()
{
    TArray<UClass*> PythonBridgeClasses;
    GetDerivedClasses(UPythonBridge::StaticClass(), PythonBridgeClasses);
    int32 NumClasses = PythonBridgeClasses.Num();
    if (NumClasses > 0)
    {
        return Cast<UPythonBridge>(PythonBridgeClasses[NumClasses - 1]->GetDefaultObject());
    }
	return nullptr;
}
/*
void UPythonBridge::FunctionImplementedInPython() const
{
    UE_LOG(LogTemp, Warning, TEXT("Hello World! FunctionImplementedInPython"));
}

void UPythonBridge::ExecuteCommand(const FString& CommandName) const
{
    UE_LOG(LogTemp, Warning, TEXT("Hello World! ExecuteCommand"));
}
*/

Project/Content/Python/init_unreal.py

import unreal
@unreal.uclass()
class PythonBridgeImplementation(unreal.PythonBridge):
    @unreal.ufunction(override=True)
    def function_implemented_in_python(self):
        print("function_implemented_in_python")
    @unreal.ufunction(override=True)
    def execute_command(self, command_name):
        print("execute_command  command_name="+command_name)
        exec(open(command_name).read())

で完成!! Cubeがちゃんと並ぶかは五分五分です。

AIのコマンド

https://dev.epicgames.com/documentation/en-us/unreal-engine/python-api/?application_version=5.3に乗ってるpythonでpep8に準拠してunrealengine5.3のpythonでレベルにcubeを10個並べて

出力されたpython


import unreal

def spawn_cubes(num_cubes=10, spacing=200.0):
    # //??????????
    actor_spawned = []
    world = unreal.EditorLevelLibrary.get_editor_world()

    # ??????????????????
    cube_mesh = unreal.EditorAssetLibrary.load_asset('/Engine/BasicShapes/Cube')

    for i in range(num_cubes):
        # ??????????????
        spawn_location = unreal.Vector(i * spacing, 0, 0)

        # ?????????
        cube_actor = unreal.EditorLevelLibrary.spawn_actor_from_object(cube_mesh, spawn_location)
        actor_spawned.append(cube_actor)

    return actor_spawned

# ?????10????
spawned_cubes = spawn_cubes()

管理用

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

参考URL

https://forums.unrealengine.com/t/running-a-python-script-with-c/114117/4

[UE5.3.2][VisualStudio][Cpp]UnrealEngineのCPPプラグインからOpenAI(ChatGPT4o)を呼んで返り値jsonからパースしてメッセージをとる

今回は以下の続き

前は戻ったjsonをそのまま表示していたが今度は中身のみを表示する

.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Http.h"
#include "Json.h"
#include "GameFramework/Actor.h"
#include "CurlApiTest.generated.h"


UCLASS()
class FURCRAEAUEOPENAI_API ACurlApiTest : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ACurlApiTest();

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

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



	UFUNCTION(BlueprintCallable, Category = "Http")
	void SendChatCompletionRequest();
	void ProcessResponseSimple(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
	//void ProcessResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful);
};

.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "CurlApiTest.h"
#include "CurlRequest.h"
#include "Http.h"
#include "Json.h"
#include "Misc/Paths.h"
#include "Misc/ConfigCacheIni.h"

// Sets default values
ACurlApiTest::ACurlApiTest()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

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

// Called every frame
void ACurlApiTest::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}



void ACurlApiTest::SendChatCompletionRequest()
{
	FString ApiKey = TEXT("sk-から始まる秘密鍵");

	TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
	HttpRequest->SetURL("https://api.openai.com/v1/chat/completions");
	HttpRequest->SetVerb("POST");
	HttpRequest->SetHeader("Content-Type", "application/json");
	HttpRequest->SetHeader("Authorization", "Bearer " + ApiKey);

	// JSON Body
	FString Content = TEXT(R"(
    {
        "model": "gpt-4o-mini",
        "messages": [{"role": "user", "content": "Say this is a test!"}],
        "temperature": 0.7
    }
    )");

	HttpRequest->SetContentAsString(Content);

	HttpRequest->OnProcessRequestComplete().BindUObject(this, &ACurlApiTest::ProcessResponseSimple);
	/*
	HttpRequest->OnProcessRequestComplete().BindLambda([this](FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
		{
			ProcessResponse(Request, Response, bWasSuccessful);
		});
	*/
	HttpRequest->ProcessRequest();
}



void ACurlApiTest::ProcessResponseSimple(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
	if (bWasSuccessful && Response.IsValid())
	{
		FString ResponseContent = Response->GetContentAsString();
		TSharedPtr<FJsonObject> JsonObject;
		TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(ResponseContent);

		if (FJsonSerializer::Deserialize(Reader, JsonObject) && JsonObject.IsValid())
		{
			FString MessageContent = JsonObject->GetArrayField("choices")[0]->AsObject()->GetObjectField("message")->GetStringField("content");
			UE_LOG(LogTemp, Warning, TEXT("Response Message: %s"), *MessageContent);
		}
		else
		{
			UE_LOG(LogTemp, Error, TEXT("Failed to parse JSON response"));
		}
	}
	else
	{
		UE_LOG(LogTemp, Error, TEXT("Request failed"));
	}


}

WBP_ApiTestにボタン追加して

SendChatCompletionRequest を呼び出した

できた!

[UE5.3.2][VisualStudio][Cpp]UnrealEngineのCPPプラグインからOpenAI(ChatGPT4o)を呼んでみるのできた。

プラグインの作り方はこの記事から

furcraeaUEOpenAI ってプラグイン作って

D:\Sandbox\UE53CratePlugin\UE53CreatePlugin\Plugins\furcraeaUEOpenAI\Source\furcraeaUEOpenAI\furcraeaUEOpenAI.Build.cs のPublicDependencyModuleNames

“HTTP”, “Json”,

を追加

// Some copyright should be here...

using UnrealBuildTool;

public class furcraeaUEOpenAI : ModuleRules
{
	public furcraeaUEOpenAI(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
		
		PublicIncludePaths.AddRange(
			new string[] {
				// ... add public include paths required here ...
			}
			);
				
		
		PrivateIncludePaths.AddRange(
			new string[] {
				// ... add other private include paths required here ...
			}
			);
			
		
		PublicDependencyModuleNames.AddRange(
			new string[]
			{
				"Core","HTTP", "Json", 
				// ... add other public dependencies that you statically link with here ...
			}
			);
			
		
		PrivateDependencyModuleNames.AddRange(
			new string[]
			{
				"CoreUObject",
				"Engine",
				"Slate",
				"SlateCore",
				// ... add private dependencies that you statically link with here ...	
			}
			);
		
		
		DynamicallyLoadedModuleNames.AddRange(
			new string[]
			{
				// ... add any modules that your module loads dynamically here ...
			}
			);
	}
}

C++クラス作成で

でActorを選択

パブリック押して名前入力

.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

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

UCLASS()
class FURCRAEAUEOPENAI_API ACurlApiTest : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ACurlApiTest();

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

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

	UFUNCTION(BlueprintCallable, Category = "Http")
	void CurlSendRequest3();
};

.cpp

// Fill out your copyright notice in the Description page of Project Settings.


#include "CurlApiTest.h"
// Sets default values
ACurlApiTest::ACurlApiTest()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

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

// Called every frame
void ACurlApiTest::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}


void ACurlApiTest::CurlSendRequest3()
{
	FString ApiKey = TEXT("sk-からはじまるKEY");

	TSharedRef<IHttpRequest> HttpRequest = FHttpModule::Get().CreateRequest();
	HttpRequest->SetURL("https://api.openai.com/v1/chat/completions");
		
	HttpRequest->SetVerb("POST");
	HttpRequest->SetHeader("Content-Type", "application/json");
	HttpRequest->SetHeader("Authorization", "Bearer " + ApiKey);

	// JSON Body
	FString Content = TEXT(R"(
    {
        "model": "gpt-4o-mini",
        "messages": [{"role": "user", "content": "Say this is a test!"}],
        "temperature": 0.7
    }
    )");

	HttpRequest->SetContentAsString(Content);
	//
	HttpRequest->OnProcessRequestComplete().BindLambda([](FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
		{
			if (bWasSuccessful && Response.IsValid())
			{
				FString ResponseContent = Response->GetContentAsString();
				UE_LOG(LogTemp, Warning, TEXT("%s"), *ResponseContent);
			}
			else
			{
				UE_LOG(LogTemp, Error, TEXT("Request failed"));
			}
		});
	HttpRequest->ProcessRequest();
}

BP_CurlApiTestを作成

現在のレベルに置く

レベルを保存

新規ブループリントから Widget BluePrint >User Widgetで作成 WBP_ApiTest

ボタン配置

ボタンに下記ノード作成

作成BluePrintからゲームモード「GM_ApiTest_GameMode」を作成。

ワールドセッティングからレベルに割り当て

で再生

作ったボタンおしてみると!応答が返ってきた!!

[VisualStudio][cpp]VisualStudioのSolution ExplorerのSolutionの左のアイコンの意味が分からなくて困ってたらNugetの環境が壊れてどうにか直したメモ

一時停止の標識でありますか?

警告アイコン:ビルドエラーや警告がある場合に表示されます。問題を示すための視覚的なインディケーターです。

ソリューション エクスプローラーについて学習する

https://t.co/j3jj610LZh

クリーンが失敗するけど対策わからん ========== Clean: 47 succeeded, 0 failed, 1 skipped ========== ========== Clean completed at 1:51 and took 01.955 seconds ==========

スキップされたプロジェクトのクリーンが失敗した理由は、ログのメッセージに「Project not selected to build for this solution configuration」とあります。これは、そのプロジェクトが現在のソリューション構成ではビルド対象として選択されていないためです。

このメッセージは、特定のプロジェクトが現在のビルド設定で無視されるように設定されていることを示しています。設定を変更することで、このプロジェクトもクリーンビルドの対象に含めることができます。

UE5はクリーン無視だもんな

NuGet クリーンすると D:\Program Files\Epic Games\UE_5.4\Engine\Source\Programs\Shared\EpicGames.Core\obj\Development\net6.0\ref\EpicGames.Core.dll が消えて エンジン再インストールになるのかもこれ。 めっちゃ罠やん。というのはちがくて

クリーンとビルドの順番を

UE5 のあと Project にすればよいみたい。

NuGet クリーンが引き起こす問題は時々厄介です。 コンソールで

Update-Package -reinstall コマンドを実行して、すべてのNuGetパッケージを再インストールしてみてください。 キャッシュのクリア: NuGetキャッシュをクリアしてみてください。 nuget locals all -clear コマンドを実行します。

Powershell

Get-ChildItem -Path “$env:USERPROFILE\.nuget\packages” -Recurse | Remove-Item -Recurse -Force

  1. エディタとゲームを終了:現在動作中のエディタとゲームをすべて終了してください。
  2. Live Coding の無効化:エディタ内またはゲーム内でコードを反復する場合は、Ctrl+Alt+F11 を押して Live Coding を無効にしてください。
  3. ビルドの再開:上記の手順を実行後、再度ビルドプロセスを開始してください。

でビルドしたらうまくいった

[VS2022][UE5]Azure Dev OpsでUE5プロジェクトをGitで管理する

ここ

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

でVS2022だと画面が違うのでキャプチャを張りなおします。

Azure DevOpsからVSへ接続しながらクローンします。

VS で View > TeamExplorer

コマンドプロンプトは見つからなかったので

Explorer 右クリックして その他のオプションを確認 > Open Git Bash here します。

git lfs install します。

git lfs install

git lfs track “*.uasset” します。

git lfs track "*.uasset"

.gitattributes が生成されます。

VS にもどって Git Changes

Commit And Push します。

UEProjectName/Content/BP_GitLFSTestActor.assetというファイルを作成し、

ファイルに 123456789 //1byte以上ないと git lfs ls-files 反応しない を書き込みますl。

123456789 //1byte以上ないと git lfs ls-files 反応しない

チームエクスプローラーからリモートリポジトリにPushします。

git lfs ls-filesで確認します。

git lfs ls-files

15e2b0d3c3 * ActionCombat/Content/BP_GitLFSTestActor.uasset が出てくればOKです

最後に.gitattributesファイル内を以下にして   Commit And Push します。

#以下のサイトを参考に作成
#https://historia.co.jp/archives/12245/

*.uasset filter=lfs diff=lfs merge=lfs -text
*.umap filter=lfs diff=lfs merge=lfs -text
*.bmp filter=lfs diff=lfs merge=lfs -text
*.float filter=lfs diff=lfs merge=lfs -text
*.pcx filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.exr filter=lfs diff=lfs merge=lfs -text
*.dds filter=lfs diff=lfs merge=lfs -text
*.hdr filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.obj filter=lfs diff=lfs merge=lfs -text
*.fbx filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.xlsx filter=lfs diff=lfs merge=lfs -text
*.docx filter=lfs diff=lfs merge=lfs -text
*.pptx filter=lfs diff=lfs merge=lfs -text

VS2022UE5_ProjectBase2.zip

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

[UE5.3.2]Udemy Master Dynamic Combat, AI Challenges, and C++ Techniques to Create Your Own Epic Action Games in UE5 でのエラー PlayerAnimInstance.gen.cpp.obj : error LNK2001: unresolved external symbol  の解決方法

1>PlayerAnimInstance.gen.cpp.obj : error LNK2001: unresolved external symbol "public: static struct UE::Math::TIntPoint<int> const UE::Math::TIntPoint<int>::ZeroValue" (?ZeroValue@?$TIntPoint@H@Math@UE@@2U123@B)
1>Throwaway.gen.cpp.obj : error LNK2001: unresolved external symbol "public: static struct UE::Math::TIntPoint<int> const UE::Math::TIntPoint<int>::ZeroValue" (?ZeroValue@?$TIntPoint@H@Math@UE@@2U123@B)
1

リンクエラー(LNK2001)が発生しているようですね。このエラーは、コンパイラが ActionCombat.cpp.obj ファイル内で参照されているシンボルの定義を見つけられないことを示しています。以下のような原因が考えられます:

  1. 関数定義の欠如:ヘッダーファイルで宣言されたすべての関数に対応する定義がソースファイルにあることを確認してください。
  2. 関数シグネチャの不一致:宣言と定義の関数シグネチャが完全に一致していることを確認してください。
  3. ライブラリの不足:シンボルが外部ライブラリの一部である場合、そのライブラリがプロジェクト設定で正しくリンクされていることを確認してください。
  4. インクルードディレクティブ:必要なヘッダーファイルがすべてソースファイルにインクルードされていることを確認してください。

以下の手順でこのエラーをトラブルシューティングし、解決することができます:

  • 関数の宣言と定義を確認:ヘッダーファイルで宣言されたすべての関数に対応する定義がソースファイルにあることを確認します。
  • ヘッダーファイルのインクルードを確認:関数が宣言されているヘッダーファイルが、関数を使用するすべてのソースファイルにインクルードされていることを確認します。
  • 必要なライブラリをリンク:関数が静的または動的ライブラリの一部である場合、そのライブラリがビルドプロセス中にリンクされていることを確認します。
  • 関数の可視性を確認:関数が現在のスコープ内でアクセス可能であり、他のソースファイルで定義されている場合は extern として正しくマークされていることを確認します。

Games/ActionCombat 右クリックして Clean を実行してから Buildする。

やったーー!解決

[Maya][RIG]maya PythonのOpenMaya の Vector で任意の座標からもっとも近い線分上の点、PoleVecterを求める

こんな感じの状態、

# -*- coding: utf-8 -*-
import maya.cmds as cmds
from maya import OpenMaya
#任意の1点と線分の両端の座標から線分上のもっとも近い点を返す
def xGetClosestPoint(myPoint, begin, end):
    myVector3D = OpenMaya.MVector(myPoint[0] - begin[0], myPoint[1] - begin[1], myPoint[2] - begin[2])
    baseVector3D = OpenMaya.MVector(end[0] - begin[0], end[1] - begin[1], end[2] - begin[2])
    nDotProduct = myVector3D * baseVector3D
    print("nDotProduct= "+str(nDotProduct))
    if (nDotProduct > 0):
        print("Big if")
        nBaseLength = baseVector3D.length()
        print("nBaseLength= "+str(nBaseLength))
        nProjection = nDotProduct / nBaseLength
        
        if (nProjection < nBaseLength):
            print("small if")
            scaleValue = nProjection / nBaseLength
            print("scaleValue= "+str(scaleValue))
            baseVector3D = baseVector3D * scaleValue
            
            return [begin[0] + baseVector3D[0], begin[1] + baseVector3D[1], begin[2] + baseVector3D[2]]
        else:
            print("small else")
            return end

    else:
        print("Big else")
        return begin;
    

sel = cmds.ls(sl =True)

# get Translate
start = cmds.xform(sel[0],q=1 ,ws =True,t=True)
mid = cmds.xform(sel[1],q=1 ,ws =True,t=True)
end = cmds.xform(sel[2],q=1 ,ws =True,t=True)

# Vector for Translate
#startV = OpenMaya.MVector(start[0] ,start[1],start[2])
#midV = OpenMaya.MVector(mid[0] ,mid[1],mid[2])
#midV = OpenMaya.MVector(end[0] ,end[1],end[2])

c_vPos = xGetClosestPoint(mid, start, end)
cmds.xform("pSphere1",ws =True,translation=(c_vPos[0], c_vPos[1], c_vPos[2]) )

線状に乗った!!

参考URL

野中文雄先生の任意の座標からもっとも近い線分上の点を求める

http://www.fumiononaka.com/TechNotes/Flash/FN1104002.html

MAYAチュートリアル:Pythonで極ベクトルを正しく配置する方法

[UE5][C++]git通したC++プロジェクトに.slnがなくて→Genalate Visual Studio Project Files →UE5 が無い→フォルダ開いて解決っていうメモ

[UE5][C++]git通したC++プロジェクトに.slnがなくて→

Genalate Visual Studio Project Files →

UE5 が無いとか小一時間悩んだら、ただフォルダ開いて無いとかゆー慌てっぷりで、草

フォルダ開いて解決 ひどいw

関連URL

Attach

https://stackoverflow.com/questions/34498992/visual-studio-run-button-changed-to-attach-to-a-process