先说思路,目前我的项目内游戏模式(GameMode)用于处理登录登出,在GameMode中每次登入会将登入的控制器转换为指定的控制器并存入容器中待用;在控制器中,我有多个成员函数用于处理为登入的玩家创建Pawn和Widget,在创建Pawn时会尝试从游戏实例(GameInstance)获取最初进入游戏时玩家自己设置的信息,之后设置给Pawn。服务端用于记录和分发信息给客户端,而使用它们的客户端则是递交申请并接收服务端信息。
现在最大的问题是,有一个服务器函数,用于在玩家登入后将GameMode内的信息获取并存入自己的控制器数组,一旦完成添加,执行一个广播函数,通知客户端执行客户端函数刷新大厅玩家信息,这个用于刷新信息的客户端函数,能够获取到服务端发过来的数组信息,它需要将这些信息在发给Widge内的一个蓝图函数,由这个蓝图函数来刷新客户端的UI显示。但是,这个刷新仅仅只在后续加入的客户端中有显示,之前加入的客户端只会显示当这些客户端加入的时候的服务端内的玩家信息,而后续加入的客户端则没有加载后加入服务端的客户端。
我不理解广播函数不是会通知所有的在服务端内的客户端执行函数吗?为什么只有当时加入的客户端能够刷新UI,之前的客户端不会刷新,而且当我尝试强制将从Gamemode内获取的控制器指定为Widget时会出现指针指向无效地址的错误,但在最终到客户端函数执行之前,我已经在广播函数中进行了控制器有效性判断
以下是最后在客户端上运行的更新控件信息成员函数(最终是链接widget内的一个蓝图函数刷新)
-
void ABaseLobbyController::Client_UpdatePlayerInfo_Implementation(const TArray& Names, const TArray& IDs, ABaseLobbyController* Controller)
{
UE_LOG(LogTemp, Log, TEXT(“In Client Update info is Local Controller is valid.”));
if (Controller)
{
if (Controller->LobbyWidget)
{
UE_LOG(LogTemp, Error, TEXT(“In Client_UpdatePlayerInfo_Implementation LobbyWidget found, updating UI.”));
UFunction* Function = Controller->LobbyWidget->FindFunction(FName(“UpdatePlayer”));
if (Function)
{
struct FBlueprintFunctionParams
{
TArray BlueprintsNames;
TArray BlueprintsIDs;
};FBlueprintFunctionParams Params; Params.BlueprintsNames = Names; Params.BlueprintsIDs = IDs; // 调用蓝图函数更新 UI UE_LOG(LogTemp, Error, TEXT("Ready call blueprints function!.")); Controller->LobbyWidget->ProcessEvent(Function, &Params); UE_LOG(LogTemp, Error, TEXT("Ready call blueprints function is finished !!!.")); } else { UE_LOG(LogTemp, Error, TEXT("No Function found on LobbyWidget!")); } } } else { UE_LOG(LogTemp, Error, TEXT("In Multicast_UpdatePlayerInfo_Implementation LobbyWidget no Found !!!.")); }
}