--[[ 需要委托绑定初始化:InitUGCSendRPCSystem 服务器客户端处均可初始化,仅一方初始化则只能在该位置发起RPC 建议在服务器和客户端均执行InitUGCSendRPCSystem InTargetObj内的目标RPC函数必须调用UGCSendRPCSystem.RPCFunc(...)如下 function UGCGameState:UGCSendRPCSystemFunc(...) UGCSendRPCSystem.RPCFunc(...) end ]]-- UGCSendRPCSystem = UGCSendRPCSystem or {} ---@class ERPCType ---@field Client2Server int32 ---@field Server2Client int32 ---@field Multicast int32 UGCSendRPCSystem.ERPCType = { Client2Server = 0x1, Server2Client = 0x2, Multicast = 0x4, } UGCSendRPCSystem.DelegationObj = nil UGCSendRPCSystem.DelegationFuncName = "" ---@param InTargetObj AActor* ---@param InUGCSendRPCSystemFuncName string function UGCSendRPCSystem.InitUGCSendRPCSystem(InTargetObj, InUGCSendRPCSystemFuncName) if UE.IsValid(InTargetObj) and type(InTargetObj[InUGCSendRPCSystemFuncName]) == "function" then UGCSendRPCSystem.DelegationObj = InTargetObj UGCSendRPCSystem.DelegationFuncName = InUGCSendRPCSystemFuncName end end --- RPC自动发送 TargetPlayer为nil则广播到所有客户端,为table则发送到包含的客户端,为int32则发送到目标客户端 --- 为 nil 的时候仅在 Server, ---@param RPCFuncName string UGCSendRPCSystem的函数名称 ---@param InTargetPlayer nil | table | int32 ---@tparam ... 事件输入的可变参数 function UGCSendRPCSystem.AutoTriggerRPC(RPCFuncName, InTargetPlayer, ...) if not UGCSendRPCSystem.CheckUGCSendRPCSystem() then UGCLogSystem.LogError("[UGCSendRPCSystem_AutoTriggerRPC] not initialized") return false end if InTargetPlayer == nil then if UGCGameSystem.IsServer() then UnrealNetwork.CallUnrealRPC_Multicast(UGCSendRPCSystem.DelegationObj, UGCSendRPCSystem.DelegationFuncName, RPCFuncName, ...) else local TargetController = STExtraGameplayStatics.GetFirstPlayerController(UGCGameSystem.GameState) if UE.IsValid(TargetController) then UnrealNetwork.CallUnrealRPC(TargetController, UGCSendRPCSystem.DelegationObj, UGCSendRPCSystem.DelegationFuncName, RPCFuncName, ...) end end elseif type(InTargetPlayer) == "number" then local TargetController = nil if UGCGameSystem.IsServer() then TargetController = UGCGameSystem.GetPlayerControllerByPlayerKey(InTargetPlayer) else TargetController = STExtraGameplayStatics.GetFirstPlayerController(UGCGameSystem.GameState) end if UE.IsValid(TargetController) then UnrealNetwork.CallUnrealRPC(TargetController, UGCSendRPCSystem.DelegationObj, UGCSendRPCSystem.DelegationFuncName, RPCFuncName, ...) end elseif type(InTargetPlayer) == "table" and UGCGameSystem.IsServer() then for _, PlayerKey in pairs(InTargetPlayer) do local TargetController = UGCGameSystem.GetPlayerControllerByPlayerKey(PlayerKey) if UE.IsValid(TargetController) then UnrealNetwork.CallUnrealRPC(TargetController, UGCSendRPCSystem.DelegationObj, UGCSendRPCSystem.DelegationFuncName, RPCFuncName, ...) end end end end function UGCSendRPCSystem.RPCFunc(FuncName, ...) UGCSendRPCSystem[FuncName](...) end function UGCSendRPCSystem.CheckUGCSendRPCSystem() return UE.IsValid(UGCSendRPCSystem.DelegationObj) end ---@param RPCFuncName string ---@param RPCType ERPCType ---@param InTargetPlayer PlayerKey | AActor | table function UGCSendRPCSystem.ExecRPC(RPCFuncName, RPCType, InTargetPlayer, ...) -- 首先检查当前是什么端 if RPCType & UGCSendRPCSystem.ERPCType.Client2Server == 1 then if UGCGameSystem.IsServer() then if type(InTargetPlayer) == 'number' then --local PC = UGCGameSystem.GetPlayerControllerByPlayerKey(InTargetPlayer); elseif type(InTargetPlayer) == 'table' and UE.IsValid(InTargetPlayer) then -- 当前是 Actor if InTargetPlayer[RPCFuncName] ~= nil and type(InTargetPlayer[RPCFuncName]) == 'function' then InTargetPlayer[RPCFuncName](...); end else end else UGCSendRPCSystem.AutoTriggerRPC(RPCFuncName, InTargetPlayer, ...); end end if RPCType & UGCSendRPCSystem.ERPCType.Server2Client == 1 then if UGCGameSystem.IsServer() then UGCSendRPCSystem.AutoTriggerRPC(RPCFuncName, InTargetPlayer, ...); else end end if RPCType & UGCSendRPCSystem.ERPCType.Multicast == 1 then -- 检查 InTargetPlayer if UGCGameSystem.IsServer() then UGCSendRPCSystem.AutoTriggerRPC(RPCFuncName, nil, InTargetPlayer, ...); else end end end ------------------------------------------- Delegation Func ------------------------------------------- --- RPC委托调用事件 function UGCSendRPCSystem.RPCEvent(TargetPlayer, EventType, ...) UGCSendRPCSystem.AutoTriggerRPC("RPC_RPCEvent", TargetPlayer, EventType, ... ) end function UGCSendRPCSystem.RPC_RPCEvent(EventType, ...) UGCEventSystem.SendEvent(EventType, ...) end --- RPC委托触发Actor的函数 function UGCSendRPCSystem.ActorRPCNotify(TargetPlayer, TargetActor, FuncName, ...) UGCSendRPCSystem.AutoTriggerRPC("RPC_ActorRPCNotify", TargetPlayer, TargetActor, FuncName, ... ) end function UGCSendRPCSystem.RPC_ActorRPCNotify(TargetActor, FuncName, ...) UGCLogSystem.Log("[UGCSendRPCSystem.RPC_ActorRPCNotify] FuncName = %s", FuncName); TargetActor[FuncName](TargetActor, ...) end --- RPC委托触发模式编辑器的事件 function UGCSendRPCSystem.PlayActionEvent(TargetPlayer, EventName, ...) UGCSendRPCSystem.AutoTriggerRPC("RPC_PlayActionEvent", TargetPlayer, EventName, ... ) end function UGCSendRPCSystem.RPC_PlayActionEvent(EventName, ...) UGCGameSystem.SendModeCustomEvent(EventName, ...) end --- 客户端显示隐藏UI function UGCSendRPCSystem.ClientShowUI(TargetPlayer, UIType, bShow, NeedClosePeerPanel, ...) if UGCGameSystem.IsServer() then if bShow == nil then bShow = true end if NeedClosePeerPanel == nil then NeedClosePeerPanel = false end UGCSendRPCSystem.AutoTriggerRPC("RPC_ClientShowUI", TargetPlayer, UIType, bShow, NeedClosePeerPanel, ... ) else UGCLogSystem.LogError("[UGCSendRPCSystem_ClientShowUI] 仅服务器调用生效 UIType:%s", tostring(UIType)) end end function UGCSendRPCSystem.RPC_ClientShowUI(UIType, bShow, NeedClosePeerPanel, ...) if bShow then WidgetManager:ShowPanel(UIType, NeedClosePeerPanel, ...) else WidgetManager:ClosePanel(UIType) end end function UGCSendRPCSystem.ExeStaticLogic(TargetPlayer, LogicType, FuncName, ...) UGCSendRPCSystem.AutoTriggerRPC("RPC_ExeStaticLogic", TargetPlayer, LogicType, FuncName, ... ) end function UGCSendRPCSystem.RPC_ExeStaticLogic(LogicType, FuncName, ...) if table.hasValue(LogicConfig.ELogicType, LogicType) then UGCLogSystem.Log("[UGCSendRPCSystem_RPC_ExeStaticLogic] FuncName:%s", FuncName) local LogicStatic = require(LogicConfig.RequireList[LogicType]) UGCLogSystem.LogTree("[UGCSendRPCSystem_RPC_ExeStaticLogic] ", LogicStatic) LogicStatic[FuncName](...) else UGCLogSystem.LogError("[UGCSendRPCSystem_RPC_ExeStaticLogic] LogicConfig.ELogicType[%s] is nil ", tostring(LogicType)) end end