更新通信协议,添加角色菜单项

This commit is contained in:
997146918 2025-07-07 09:34:28 +08:00
parent 5737e415c9
commit 9fcd390366
8 changed files with 227 additions and 112 deletions

View File

@ -0,0 +1,5 @@
[/Script/AIGC.AIGCSetting]
ServerIP=127.0.0.1

View File

@ -2,42 +2,34 @@
#include "AIGC.h" #include "AIGC.h"
#include "AIGCSetting.h"
#include "AIGCStyle.h" #include "AIGCStyle.h"
#include "AssetToolsModule.h" #include "AssetToolsModule.h"
#include "FileHelpers.h" #include "FileHelpers.h"
#include "ISettingsModule.h"
#include "LevelEditor.h" #include "LevelEditor.h"
#include "ToolMenu.h" #include "ToolMenu.h"
#include "ToolMenus.h" #include "ToolMenus.h"
#include "WebSocketManager.h"
#include "AssetRegistry/AssetRegistryModule.h" #include "AssetRegistry/AssetRegistryModule.h"
#include "Misc/MessageDialog.h" #include "Misc/MessageDialog.h"
#include "UObject/SavePackage.h" #include "UObject/SavePackage.h"
#include "Widget/AIGCWindow.h" #include "Widget/AIGCWindow.h"
#include "Widget/CharacterWindow.h"
#define LOCTEXT_NAMESPACE "FAIGCModule" #define LOCTEXT_NAMESPACE "FAIGCModule"
#define AIGCWindowName FName("AIGC") #define AIGCWindowName FName("AIGC")
#define CharacterWindowName FName("Character")
void FAIGCModule::StartupModule() void FAIGCModule::StartupModule()
{ {
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
RegeisterSettings();
//添加style //添加style
FAIGCStyle::Initialize(); FAIGCStyle::Initialize();
FAIGCStyle::ReloadTextures(); FAIGCStyle::ReloadTextures();
// //注册Command
// FAIGCCommands::Register();
// PluginCommands = MakeShareable(new FUICommandList);
// //绑定动作
// PluginCommands->MapAction(
// FAIGCCommands::Get().MenuAction,
// FExecuteAction::CreateRaw(this, &FAIGCModule::MenuClicked),
// FCanExecuteAction());
//
// PluginCommands->MapAction(
// FAIGCCommands::Get().SubMenuAction,
// FExecuteAction::CreateRaw(this, &FAIGCModule::SubMenuClicked),
// FCanExecuteAction());
//添加菜单 //添加菜单
UToolMenu* menu = UToolMenus::Get()->FindMenu(FName("LevelEditor.MainMenu.AIGC")); UToolMenu* menu = UToolMenus::Get()->FindMenu(FName("LevelEditor.MainMenu.AIGC"));
if (!menu) if (!menu)
@ -62,16 +54,17 @@ void FAIGCModule::StartupModule()
FGlobalTabmanager::Get()->TryInvokeTab(AIGCWindowName); FGlobalTabmanager::Get()->TryInvokeTab(AIGCWindowName);
}))); })));
// // 填充第二个子菜单项 //添加人员配置菜单
// FToolMenuSection& SubSection2 = SubMenu->AddSection( FToolMenuSection& CharacterSection = SubMenu->AddSection("Character");
// "SubSection2"); SubSection.AddMenuEntry(
// SubSection.AddMenuEntry( "Character",
// "Submenu2", LOCTEXT("Character", "角色配置"),
// LOCTEXT("Action1Label", "生成模型2"), LOCTEXT("CharacterToolTip", ""),
// LOCTEXT("Action1Tooltip", "触发模型生成2"), FSlateIcon(FAIGCStyle::GetStyleSetName(), "AIGCStyle.AIChat"),
// FSlateIcon(FAIGCStyle::GetStyleSetName(), "AIGCStyle.AIChat"), FUIAction(FExecuteAction::CreateLambda([this]()
// FToolUIActionChoice( {
// FAIGCCommands::Get().SubMenuAction, *PluginCommands)); FGlobalTabmanager::Get()->TryInvokeTab(CharacterWindowName);
})));
}), }),
false, // 是否动态生成 false, // 是否动态生成
FSlateIcon()); FSlateIcon());
@ -81,42 +74,54 @@ void FAIGCModule::StartupModule()
} }
//注册窗口 //注册Chat窗口
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(AIGCWindowName, FOnSpawnTab::CreateRaw(this, &FAIGCModule::OnSpawnPluginTab)) FGlobalTabmanager::Get()->RegisterNomadTabSpawner(AIGCWindowName, FOnSpawnTab::CreateRaw(this, &FAIGCModule::OnSpawnAIChatTab))
.SetDisplayName(LOCTEXT("AIGCWindow", "AIGCWindow")) .SetDisplayName(LOCTEXT("AIGCWindow", "AIGCWindow"))
.SetMenuType(ETabSpawnerMenuType::Hidden); .SetMenuType(ETabSpawnerMenuType::Hidden);
//注册角色窗口
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(CharacterWindowName, FOnSpawnTab::CreateRaw(this, &FAIGCModule::OnSpawnCharacterTab))
.SetDisplayName(LOCTEXT("CharacterWindow", "CharacterWindow"))
.SetMenuType(ETabSpawnerMenuType::Hidden);
} }
// void FAIGCModule::SubMenuClicked()
// {
// UE_LOG(LogTemp, Warning, TEXT("Generate Model"));
// FMessageDialog::Open(EAppMsgType::Ok, FText::FromString("4444555"));
// }
void FAIGCModule::ShutdownModule() void FAIGCModule::ShutdownModule()
{ {
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, // 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. // we call this function before unloading the module.
UnregisterSettings();
UToolMenus::UnregisterOwner(this); UToolMenus::UnregisterOwner(this);
FAIGCStyle::Shutdown(); FAIGCStyle::Shutdown();
//FAIGCCommands::Unregister();
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(AIGCWindowName); FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(AIGCWindowName);
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(CharacterWindowName);
}
void FAIGCModule::RegeisterSettings()
{
#if WITH_EDITOR
ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
if (!SettingsModule)
return;
const auto Section = SettingsModule->RegisterSettings("Project", "Plugins", "AIGC",
FText::FromString(TEXT("AIGC")),
FText::FromString(TEXT("AIGC Setting")),
GetMutableDefault<UAIGCSetting>());
#endif
}
void FAIGCModule::UnregisterSettings()
{
#if WITH_EDITOR
ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
if (SettingsModule)
SettingsModule->UnregisterSettings("Project", "Plugins", "AIGC");
#endif
} }
TSharedRef<SDockTab> FAIGCModule::OnSpawnAIChatTab(const FSpawnTabArgs& SpawnTabArgs)
TSharedRef<SDockTab> FAIGCModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
{ {
FText WidgetText = FText::Format(
LOCTEXT("WindowWidgetText", "Add code to {0} in {1} to override this window's contents"),
FText::FromString(TEXT("FTestModule::OnSpawnPluginTab")),
FText::FromString(TEXT("Test.cpp"))
);
return SNew(SDockTab) return SNew(SDockTab)
.TabRole(ETabRole::NomadTab) .TabRole(ETabRole::NomadTab)
[ [
@ -130,6 +135,21 @@ TSharedRef<SDockTab> FAIGCModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTab
]; ];
} }
TSharedRef<SDockTab> FAIGCModule::OnSpawnCharacterTab(const FSpawnTabArgs& SpawnTabArgs)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
// Put your tab content here!
SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(SCharacterWindow)
]
];
}
void FAIGCModule::CreateOrAddData(const FString& DataTablePath, const FString& RowValue) void FAIGCModule::CreateOrAddData(const FString& DataTablePath, const FString& RowValue)
{ {
FString PackagePath, AssetName; FString PackagePath, AssetName;
@ -158,6 +178,18 @@ void FAIGCModule::CreateOrAddData(const FString& DataTablePath, const FString& R
UPackage::SavePackage(DataTable->GetPackage(), DataTable, *FilePath, SaveArgs); UPackage::SavePackage(DataTable->GetPackage(), DataTable, *FilePath, SaveArgs);
} }
UWebSocketManager* FAIGCModule::GetWebSocketManager()
{
return WebSocketManager;
}
void FAIGCModule::InitWebSocketManager()
{
auto& Settings = *GetDefault<UAIGCSetting>();
WebSocketManager = NewObject<UWebSocketManager>();
WebSocketManager->InitWebSocket(Settings.ServerIP);
}
#undef LOCTEXT_NAMESPACE #undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FAIGCModule, AIGC) IMPLEMENT_MODULE(FAIGCModule, AIGC)

View File

@ -19,10 +19,16 @@ void UWebSocketManager::InitWebSocket(const FString& ServerIP)
,*ServerIP, *(FGuid::NewGuid().ToString()) ))); ,*ServerIP, *(FGuid::NewGuid().ToString()) )));
} }
void UWebSocketManager::SendData(const FString& Data) void UWebSocketManager::SendData(const FString& cmd, const FString& Data)
{ {
//定义客户端协议
FNetProtocol protocol;
protocol.cmd = cmd;
protocol.data = Data;
FString JsonString;
FJsonObjectConverter::UStructToJsonObjectString(protocol, JsonString);
WebSocketHandler->SendText(Data); WebSocketHandler->SendText(JsonString);
} }
void UWebSocketManager::HandleConnected() void UWebSocketManager::HandleConnected()
@ -52,30 +58,38 @@ void UWebSocketManager::HandleOnMessageSend(const FString& Message)
void UWebSocketManager::HandleOnReceiveText(const FString& Message) void UWebSocketManager::HandleOnReceiveText(const FString& Message)
{ {
FAIServerData ServerData; // FAIServerData ServerData;
FJsonObjectConverter::JsonObjectStringToUStruct<FAIServerData>( // FJsonObjectConverter::JsonObjectStringToUStruct<FAIServerData>(
// Message,
// &ServerData,
// 0, // 检查标志位
// 0 // 转换标志位
// );
// switch (ServerData.statusCode)
// {
// case -1:
// UE_LOG(LogTemp, Error, TEXT("ai server error reason = %s "), *ServerData.messages[0]);
// OnDataReceiveDelaget.Broadcast(TArray<FString>());
// break;
// case 0:
// //normal heart tick
// break;
// case 1:
// UE_LOG(LogTemp, Warning, TEXT("Receive Text %s from WebSocket Server "), *Message);
// OnDataReceiveDelaget.Broadcast(ServerData.messages);
// break;
// case 2:
// UE_LOG(LogTemp, Error, TEXT("ai content generate format error,server is regerating..... "));
// break;
// default:
// break;
// }
FNetProtocol serverProtocol;
FJsonObjectConverter::JsonObjectStringToUStruct<FNetProtocol>(
Message, Message,
&ServerData, &serverProtocol,
0, // 检查标志位 0, // 检查标志位
0 // 转换标志位 0 // 转换标志位
); );
switch (ServerData.statusCode) OnDataReceiveDelaget.Broadcast(serverProtocol);
{
case -1:
UE_LOG(LogTemp, Error, TEXT("ai server error reason = %s "), *ServerData.messages[0]);
OnDataReceiveDelaget.Broadcast(TArray<FString>());
break;
case 0:
//normal heart tick
break;
case 1:
UE_LOG(LogTemp, Warning, TEXT("Receive Text %s from WebSocket Server "), *Message);
OnDataReceiveDelaget.Broadcast(ServerData.messages);
break;
case 2:
UE_LOG(LogTemp, Error, TEXT("ai content generate format error,server is regerating..... "));
break;
default:
break;
}
} }

View File

@ -106,13 +106,23 @@ void SAIGCWindow::Construct(const FArguments& InArgs)
EActiveTimerReturnType SAIGCWindow::OnPostPaint(double X, float Arg) EActiveTimerReturnType SAIGCWindow::OnPostPaint(double X, float Arg)
{ {
WebSocketManager = NewObject<UWebSocketManager>(); //init websocket
WebSocketManager->InitWebSocket(*ServerIP->GetInputText()); FAIGCModule* ModulePtr = FModuleManager::GetModulePtr<FAIGCModule>("AIGC");
WebSocketManager->OnConnectDelegate.AddLambda([this](bool bSuccess) if (ModulePtr)
{ {
GenerateButton->SetEnabled(bSuccess); UWebSocketManager* WebSocketManager = ModulePtr->GetWebSocketManager();
}); if (!WebSocketManager)
WebSocketManager->OnDataReceiveDelaget.AddRaw(this, &SAIGCWindow::HandleReceiveData); {
ModulePtr->InitWebSocketManager();
WebSocketManager = ModulePtr->GetWebSocketManager();
}
WebSocketManager->OnConnectDelegate.AddLambda([this](bool bSuccess)
{
GenerateButton->SetEnabled(bSuccess);
});
WebSocketManager->OnDataReceiveDelaget.AddRaw(this, &SAIGCWindow::HandleReceiveData);
}
return EActiveTimerReturnType::Stop; return EActiveTimerReturnType::Stop;
} }
@ -122,40 +132,50 @@ void SAIGCWindow::OnAIGenerateClicked()
GenerateButton->SetEnabled(false); GenerateButton->SetEnabled(false);
RequireGenerateCount = GenerateCount->GetNumber(); RequireGenerateCount = GenerateCount->GetNumber();
UE_LOG(LogTemp, Warning, TEXT("生成次数 %d prompt:%s"), RequireGenerateCount, *GeneratePromptJson()); UE_LOG(LogTemp, Warning, TEXT("生成次数 %d prompt:%s"), RequireGenerateCount, *GeneratePromptJson());
WebSocketManager->SendData(GeneratePromptJson()); FAIGCModule* ModulePtr = FModuleManager::GetModulePtr<FAIGCModule>("AIGC");
if (ModulePtr)
{
ModulePtr->GetWebSocketManager()->SendData(FNetCommand::AiChatGenerate, GeneratePromptJson());
}
} }
void SAIGCWindow::HandleReceiveData(TArray<FString> AiMessages) void SAIGCWindow::HandleReceiveData(FNetProtocol protocol)
{ {
UE_LOG(LogTemp, Warning, TEXT("AI当前进度 %d/%d"), GeneratedCount, RequireGenerateCount); // UE_LOG(LogTemp, Warning, TEXT("AI当前进度 %d/%d"), GeneratedCount, RequireGenerateCount);
//添加数据到dataTable中 // //添加数据到dataTable中
if (AiMessages.Num() > 0) // if (AiMessages.Num() > 0)
{ // {
FAIGCModule* ModulePtr = FModuleManager::GetModulePtr<FAIGCModule>("AIGC"); // FAIGCModule* ModulePtr = FModuleManager::GetModulePtr<FAIGCModule>("AIGC");
if (ModulePtr) { // if (ModulePtr) {
FString DataPath = FString::Printf(TEXT("/Game/Test/%s.%s"), *DataName->GetInputText(), *DataName->GetInputText()); // FString DataPath = FString::Printf(TEXT("/Game/Test/%s.%s"), *DataName->GetInputText(), *DataName->GetInputText());
FString Final = ""; // FString Final = "";
for (auto message: AiMessages) // for (auto message: AiMessages)
{ // {
Final += message + TEXT("|"); // Final += message + TEXT("|");
} // }
ModulePtr->CreateOrAddData(DataPath, Final); // ModulePtr->CreateOrAddData(DataPath, Final);
} // }
} // }
//
//是否生成足够数量 // //是否生成足够数量
if (GeneratedCount < RequireGenerateCount) // if (GeneratedCount < RequireGenerateCount)
{ // {
GeneratedCount++; // GeneratedCount++;
WebSocketManager->SendData(GeneratePromptJson()); // FAIGCModule* ModulePtr = FModuleManager::GetModulePtr<FAIGCModule>("AIGC");
} // if (ModulePtr)
else // {
{ // ModulePtr->GetWebSocketManager()->SendData(FNetCommand::AiChatGenerate, GeneratePromptJson());
GeneratedCount = 0; // }
GenerateButton->SetEnabled(true); //
UE_LOG(LogTemp, Warning, TEXT("生成结束!")); // }
} // else
// {
// GeneratedCount = 0;
// GenerateButton->SetEnabled(true);
// UE_LOG(LogTemp, Warning, TEXT("生成结束!"));
// }
} }

View File

@ -37,13 +37,22 @@ struct FNPCChatRow : public FTableRowBase {
class FAIGCModule : public IModuleInterface class FAIGCModule : public IModuleInterface
{ {
public: public:
TSharedRef<SDockTab> OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs); TSharedRef<SDockTab> OnSpawnAIChatTab(const FSpawnTabArgs& SpawnTabArgs);
TSharedRef<SDockTab> OnSpawnCharacterTab(const FSpawnTabArgs& SpawnTabArgs);
//void SubMenuClicked(); //void SubMenuClicked();
/** IModuleInterface implementation */ /** IModuleInterface implementation */
virtual void StartupModule() override; virtual void StartupModule() override;
virtual void ShutdownModule() override; virtual void ShutdownModule() override;
void RegeisterSettings();
void UnregisterSettings();
void CreateOrAddData(const FString& DataTablePath, const FString& RowValue); void CreateOrAddData(const FString& DataTablePath, const FString& RowValue);
class UWebSocketManager* GetWebSocketManager();
void InitWebSocketManager();
private: private:
TSharedPtr<class FUICommandList> PluginCommands; TSharedPtr<class FUICommandList> PluginCommands;
class UWebSocketManager* WebSocketManager = nullptr;
}; };
#undef LOCTEXT_NAMESPACE #undef LOCTEXT_NAMESPACE

View File

@ -45,4 +45,38 @@ struct FAIServerData
int32 statusCode; int32 statusCode;
UPROPERTY() UPROPERTY()
TArray<FString> messages; TArray<FString> messages;
}; };
USTRUCT()
struct FCharacterInfo
{
GENERATED_BODY()
FString name;
int32 age;
FString personality;
FString characterBackground;
FString chat_style;
};
USTRUCT()
struct FNetProtocol
{
GENERATED_BODY()
UPROPERTY()
FString cmd; //命令名称
UPROPERTY()
int32 status; //状态
UPROPERTY()
FString message; //响应消息
UPROPERTY()
FString data; //json数据
};
USTRUCT()
struct FNetCommand
{
GENERATED_BODY()
static FString CharacterList;
static FString AddCharacter;
static FString AiChatGenerate;
};

View File

@ -3,11 +3,12 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Definations.h"
#include "UObject/Object.h" #include "UObject/Object.h"
#include "WebSocketManager.generated.h" #include "WebSocketManager.generated.h"
DECLARE_MULTICAST_DELEGATE_OneParam(FOnConnectDelegate, bool); DECLARE_MULTICAST_DELEGATE_OneParam(FOnConnectDelegate, bool);
DECLARE_MULTICAST_DELEGATE_OneParam(FOnDataReceiveDelaget, TArray<FString>); DECLARE_MULTICAST_DELEGATE_OneParam(FOnDataReceiveDelaget, FNetProtocol);
/** /**
* *
*/ */
@ -17,7 +18,7 @@ class AIGC_API UWebSocketManager : public UObject
GENERATED_BODY() GENERATED_BODY()
public: public:
void InitWebSocket(const FString& ServerIP); void InitWebSocket(const FString& ServerIP);
void SendData(const FString& Data); void SendData(const FString& cmd, const FString& Data);
UFUNCTION() UFUNCTION()
void HandleConnected(); void HandleConnected();
UFUNCTION() UFUNCTION()

View File

@ -5,6 +5,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "ConfigItem_NumberSpin.h" #include "ConfigItem_NumberSpin.h"
#include "ConfigItem_Text.h" #include "ConfigItem_Text.h"
#include "Definations.h"
/** /**
* *
@ -22,7 +23,7 @@ public:
void OnAIGenerateClicked(); void OnAIGenerateClicked();
void InitWebClient(); void InitWebClient();
void HandleReceiveData(TArray<FString> String); void HandleReceiveData(FNetProtocol protocol);
private: private:
FString GeneratePromptJson(); FString GeneratePromptJson();
@ -39,6 +40,5 @@ protected:
TSharedPtr<SConfigItem_NumberSpin<int32>> GenerateCount; //生成数目 TSharedPtr<SConfigItem_NumberSpin<int32>> GenerateCount; //生成数目
TSharedPtr<SButton> GenerateButton; //生成按钮 TSharedPtr<SButton> GenerateButton; //生成按钮
UPROPERTY()
class UWebSocketManager* WebSocketManager;
}; };