首页 > 编程语言 >UE4 C++ 多人游戏中的简单聊天窗口

UE4 C++ 多人游戏中的简单聊天窗口

时间:2024-07-31 19:18:22浏览次数:9  
标签:HUD cont Controller C++ TextWidget break RPC 聊天 UE4

本质

不管是客户端还是服务器在输入文字后,按下回车发送,将触发RPC调用。然后通过RPC将发送者,输入文本等信息,传入到服务器,然后通过多播RPC传播到所有客户端的聊天框。

UI

UI利用三个组件

ScrollBox

用于在服务器以及每个客户端上显示消息的载体

TextBlock

本地将信息通过一个一个的TextBlock组装,然后将组装的结果添加到ScrollBox中实现消息的显示

UEditableText

每个机器上编辑发送消息的主体,该组件具有OnTextCommitted的委托,可以处理提交事件,可以在自定义一个OnSendText委托,用于当Committed时可以外部调用。

switch (CommitMethod)
	{
	case ETextCommit::Default:
		break;
	case ETextCommit::OnEnter:
		UE_LOG(LogTemp, Warning, TEXT("TextCommitted_OnEnter"));
		OnSendText.Broadcast(Text);
		SendText->SetText(FText::FromString(""));
		UGameplayStatics::GetPlayerController(GetWorld(), 0)->SetInputMode(FInputModeGameOnly());
		GetNowUserComponent(GetOwningPlayer())->ToggleChatWindow();
		break;
	case ETextCommit::OnUserMovedFocus:
		break;
	case ETextCommit::OnCleared:
		break;
	default:
		break;
	}

实现

将直接在GameMode中的PlayerController中增加用于Chat的Component。

ServerSentText

该函数是一个ServerRPC,当接受到OnSendText委托后,调用。
在函数内部,通过遍历当前World中具有ChatComponent的Controller,获得所有客户端的Actor。然后调用多播RPC实现消息的滚动

TArray<AActor*> Actors;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), AXBlasterPlayerController::StaticClass(), Actors);
for (auto& it : Actors)
{
	UActorComponent* cont = it->GetComponentByClass(UXChatComponent::StaticClass());
	if (cont && cont->Implements<UXChatInterface>())
	{
		IXChatInterface::Execute_ChatMessage(
			cont,
			Message,
			MessageType,
			PlayerName,
			SetMessageTypeColor(MessageType),
			ChatType
		);
	}
}

多播RPC MultiSendMessage

该函数在服务器上调用后,会在每个客户端进行执行,该函数主要处理发送信息的整合。
通过GetOwner()获取当前的Controller,然后判断Controller是不是本地的,如果不是那么就会跳过,只有是本地的才会进行消息的拼装,否则会出现多条相同的消息

	AXBlasterPlayerController* PIC = Cast<AXBlasterPlayerController>(GetOwner());
	if (!PIC->IsLocalController()) return;
	AXBlasterHUD* HUD = Cast<AXBlasterHUD>(PIC->GetHUD());
	if (HUD)
	{
		if (HUD->ChatWdg)
		{
			UXTextWidget* TextWidget = CreateWidget<UXTextWidget>(
				UGameplayStatics::GetPlayerController(GetWorld(), 0),
				HUD->ChatTextClass
			);
			if (TextWidget)
			{
				TextWidget->PlayerName = FText::FromString(SendName);
				TextWidget->InText = Message;
				TextWidget->MessType = MessageType;
				TextWidget->ChatType = EChatTypes::ECT_All;
				HUD->ChatWdg->ChatScrollBox->AddChild(TextWidget);
				HUD->ChatWdg->ChatScrollBox->ScrollToEnd();
			}
		}
	}

通过接口实现多播RPC的调用

由于在Server里是遍历了World中所有的Controller,使用接口可以表面获取实例来进行调用而且可以放置选择到那些没有Chat功能的Controller,因为在C++中会首先检验当前的实例是否实现了接口

if (cont && cont->Implements<UXChatInterface>())
	{
		IXChatInterface::Execute_ChatMessage(
			cont,
			Message,
			MessageType,
			PlayerName,
			SetMessageTypeColor(MessageType),
			ChatType
		);
	}

标签:HUD,cont,Controller,C++,TextWidget,break,RPC,聊天,UE4
From: https://www.cnblogs.com/XTG111/p/18279872

相关文章

  • Linux下C++动态链接库的生成以及使用
    目录一.前言二.生成动态链接库三.使用动态链接库一.前言这篇文章简单讨论一下Linux下如何使用gcc/g++生成和使用C++动态链接库(.so文件)。二.生成动态链接库先看下目录结构然后看下代码//demo.h#ifndefDEMO_H#defineDEMO_H#include<string>classDemo{......
  • 与陌生人聊天可能有益健康,也可能是新友谊的开始
    与陌生人聊天可能有益健康,也可能是新友谊的开始与陌生人聊天可能有益健康,也可能是新友谊的开始It’sgoodtotalk’,sosomepeoplesay.WhenIcommuteintoLondon,therearecertainlyplentyofpeopleconversingontheirmobilephones–sometimestooloudl......
  • 【C++BFS算法 二分查找】2812. 找出最安全路径
    本文涉及知识点C++BFS算法C++二分查找LeetCode2812.找出最安全路径给你一个下标从0开始、大小为nxn的二维矩阵grid,其中(r,c)表示:如果grid[r][c]=1,则表示一个存在小偷的单元格如果grid[r][c]=0,则表示一个空单元格你最开始位于单元格(0,0)。在......
  • 【C++】构造函数的深入学习
    一、初始化列表C++提供初始化列表语法用来初始化属性语法:构造函数():属性1(值1),属性2(值2)...{}classPeople{public://传统初始化操作Person(inta,intb,intc){A=a;B=b;C=c;}//初始化列表初始化属性Pers......
  • 【C++】对象模型和this指针
    一、成员变量和成员函数分开存储只有非静态成员变量才属于类的对象上①C++编译器会给每一个空对象分配一个字节的空间,为了区分空对象占内存的位置classPerson{}voidtest(){PersonP;//空类(类中什么也没有)中的空对象所占内存空间为1cout<<sizeof(P......
  • C++面向对象编程解析
    文章目录1.概述2.作用解析3.概念解析1.类和对象2.封装(Encapsulation)3.继承(Inheritance)4.多态(Polymorphism)1.概述C++是在C语言的基础上增加了面向对象编程(OOP)特性的编程语言。面向对象编程是一种编程范式,通过将程序组织成对象的集合,这些对象包含数据和行......
  • 关于使用C#注入C++的封装DLL后打印内容乱码
    最近因需要,用C++写了个钩子的DLL,一切工作测试通过后,放到C#里使用P/Invoke调用,发现部分乱码,最后反复测试,才发现一个问题,原来SetWindowsHookEx这个函数,也是分A版和W版,最后换了就正常了,附上对比。。乱码[DllImport("user32.dll",SetLastError=true]publicstaticex......
  • 搭建 STM32 网关服务器的全流程:集成嵌入式 C++、TCP/IP 通信、Flash 存储及 JWT 认证(
    引言随着物联网(IoT)技术的快速发展,基于STM32的服务器(类似网关)在数据采集、设备控制等方面的应用越来越广泛。本文将介绍搭建一个基于STM32的服务器所需的技术栈,以及详细的搭建步骤和代码示例。技术栈介绍在搭建基于STM32的服务器时,我们需要用到以下技术栈和组件:1.硬......
  • 基于 ChatGPT 的聊天软件合集打包分享
     「基于ChatGPT的聊天软件合集打包」链接:https://pan.quark.cn/s/ef1f5e9c48e4BotGem(原名AMA)官网:https://botgem.com/比较简单,有指令库;支持openai/AzureChatBox项目地址:https://github.com/Bin-Huang/chatbox说明文档:https://github.com/Bin-Huang/chatbox/blob/......
  • 【C++】auto
    1、概念auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。注意:使用auto变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此,auto并非是一种“类型”的声明,而是一个类型......