require("Script.Global.BuffSystem.Config.BuffActionConfig") require("Script.Global.BuffSystem.Config.BuffAssetConfig") -- 其中BuffCauser, CauserActor, EndTime不进行同步,仅服务器拥有 -- BuffInst = {BuffAssetType, OwnerPawn, BuffCauser, CauserActor, EndTime, BuffActions} BuffManager = BuffManager or { -- 可配置参数 ---------------------------------------------------- -- Tick的帧数 TickFPS = 24; -- 可配置参数 End ------------------------------------------------ -- 已注册的GameState RegisteredGameState = nil; -- 已Require的 BuffAsset BuffAssetList = {}; -- 正在使用中的Buff实例 [BuffID] = BuffInst (类型为table,参考上述对BuffInst的描述) BuffInstList = {}; -- 玩家拥有的Buff 这里由于用于同步,因此Val里面的信息为列表而非字典 [Pawn] = {[BuffID] = BuffAssetType}, ...} AllPlayerOwnedBuffs = {}; -- 客户端上一次同步AllPlayerOwnedBuffs的table [Pawn] = {[BuffID] = BuffAssetType}, ...} ClientAllPlayerOwnedBuffs = {}; -- 这个函数用于衔接服务器和客户端的AllPlayerOwnedBuffs同步,因为Pawn作为Key值不能进行OnRep同步 {{Pawn, {[BuffID] = BuffAssetType, ...}}, ...} OwnedBuffInfo = {}; -- Buff起始时间和结束时间 [BuffID] = {StartTime, EndTime} 这里是列表而不是字典 BuffTimeInfo = {}; -- 那些自动移除的Buff,用于有时间限制的Buff AutoRemoveBuffList = {}; -- 已绑定死亡清除函数的玩家 {[Pawn] = 1} BoundOnEndPlayDelegatePlayers = {}; } --- 这里统一一下获取时间的函数 function BuffManager.GetGameTime() if BuffManager.RegisteredGameState then return KismetSystemLibrary.GetGameTimeInSeconds(BuffManager.RegisteredGameState) else return 0. end end -- ReplicatedProperties ---------------------------------------------------------------------------------------- -- 需要GameState同步的变量 BuffManager.ReplicatedProperties = { "OwnedBuffInfo" } -- 需要GameState同步的函数 BuffManager.RPCFunc = { "DoBuffActionFunction" } -- 需要在GameState中辅助同步的变量,用逗号作为间隔,将其加入UGCGameState:GetReplicatedProperties()的末尾 function BuffManager.GetReplicatedProperties() return table.unpack(BuffManager.ReplicatedProperties) end -- AllPlayerOwnedBuffs function BuffManager.DOREPONCE_OwnedBuffInfo() BuffManager.OwnedBuffInfo = {} -- 分解AllPlayerOwnedBuffs for Pawn, BuffInfo in pairs(BuffManager.AllPlayerOwnedBuffs) do BuffManager.OwnedBuffInfo[#BuffManager.OwnedBuffInfo + 1] = {Pawn, BuffInfo} end BuffManager.RegisteredGameState.OwnedBuffInfo = BuffManager.OwnedBuffInfo UGCLogSystem.LogTree("[BuffManager_DOREPONCE_OwnedBuffInfo] Finish", BuffManager.OwnedBuffInfo) end function BuffManager.OnRep_OwnedBuffInfo() BuffManager.OwnedBuffInfo = BuffManager.RegisteredGameState.OwnedBuffInfo UGCLogSystem.LogTree("[BuffManager_OnRep_OwnedBuffInfo] OwnedBuffInfo:", BuffManager.OwnedBuffInfo) BuffManager.AllPlayerOwnedBuffs = {} -- 重构AllPlayerOwnedBuffs for i, v in pairs(BuffManager.OwnedBuffInfo) do if v[1] and v[2] then BuffManager.AllPlayerOwnedBuffs[v[1]] = v[2] end end -- 客户端校验玩家拥有的Buff并进行创建和删除操作 BuffManager.ClientUpdateAllPlayerOwnedBuffs() end -- ReplicatedProperties End ------------------------------------------------------------------------------------ -- Register ---------------------------------------------------------------------------------------------------- --- 初始化注册 该函数需要在GameState的服务器和客户端中同时调用 ---@param InGameState UGCGameState_C GameState作为辅助同步的Actor function BuffManager.InitRegister(InGameState) BuffManager.RegisteredGameState = InGameState -- 初始化一下Tick的时间 BuffManager.LastTickTime = BuffManager.GetGameTime() -- 启用Tick BuffManager.TickHandle = UGCEventSystem.SetTimerLoop(BuffManager.RegisteredGameState, BuffManager.Tick, 1./BuffManager.TickFPS) -- 注册一下RPC函数 BuffManager.RegisterRPCFunc(InGameState) if UGCGameSystem.IsServer() then -- 注册参数 BuffManager.RegisterParam(InGameState) -- 校验Pawn的有效性,不为当前游玩的PlayerPawn则移除其所有Buff BuffManager.CheckPawnIsValidHandle = UGCEventSystem.SetTimerLoop(BuffManager.RegisteredGameState, BuffManager.CheckPawnIsValid, 1) else -- 注册OnRep函数 BuffManager.RegisterClientOnRepFunc(InGameState) -- 每秒校验一下同步的Buff BuffManager.UpdateAllPlayerOwnedBuffsHandle = UGCEventSystem.SetTimerLoop(BuffManager.RegisteredGameState, BuffManager.ClientUpdateAllPlayerOwnedBuffs, 1) end end -- 注册RPC函数 function BuffManager.RegisterRPCFunc(InGameState) for i, FuncName in pairs(BuffManager.RPCFunc) do InGameState[FuncName] = function(GameState, ...) BuffManager[FuncName](...) end end end -- 注册参数 function BuffManager.RegisterParam(InGameState) UGCLogSystem.Log("[BuffManager_RegisterParam]") for i, PropertyName in pairs(BuffManager.ReplicatedProperties) do -- 这里要保证两个同名 if BuffManager[PropertyName] then InGameState[PropertyName] = BuffManager[PropertyName] UGCLogSystem.Log("[BuffManager_RegisterParam] PropertyName:%s", tostring(PropertyName)) end end end -- 注册客户端OnRep函数 function BuffManager.RegisterClientOnRepFunc(InGameState) UGCLogSystem.Log("[BuffManager_RegisterClientOnRepFunc]") for i, PropertyName in pairs(BuffManager.ReplicatedProperties) do local OnRepFuncName = "OnRep_" .. PropertyName if BuffManager[OnRepFuncName] then InGameState[OnRepFuncName] = function(InGameState) UGCLogSystem.Log("[BuffManager_RegisterClientOnRepFunc] Exe") BuffManager[OnRepFuncName]() end BuffManager[OnRepFuncName]() UGCLogSystem.Log("[BuffManager_RegisterClientOnRepFunc] OnRepFuncName:%s", tostring(OnRepFuncName)) end end end -- Register End ------------------------------------------------------------------------------------------------ --- 获取单个Action实例,该实例主要用于拷贝和实例的RPC function BuffManager.GetSimpleAction(InActionType) local SimpleAction = BuffManager.SimpleAction[InActionType] if SimpleAction == nil then local BuffFileName = BuffActionConfig.ActionFileName[InActionType] -- UGCLogSystem.Log("[BuffManager_GetCopyAction] BuffFileName:%s", tostring(BuffFileName)) if BuffFileName then SimpleAction = require(BuffActionConfig.ActionRootPath .. "." .. BuffFileName) BuffManager.SimpleAction[InActionType] = SimpleAction else return nil end end return SimpleAction end --- 作为BuffAction拷贝临时模板列表 BuffManager.SimpleAction = {} --- 获取拷贝的BuffAction ---@param InActionType BuffActionConfig.EActionType ---@param CopyAction table 拷贝出的Action function BuffManager.GetCopyAction(InActionType) -- UGCLogSystem.Log("[BuffManager_GetCopyAction] InActionType:%s", tostring(InActionType)) local SimpleAction = BuffManager.GetSimpleAction(InActionType) -- UGCLogSystem.Log("[BuffManager_GetCopyAction] Finish") return table.NewLuaObj(SimpleAction) end function BuffManager.GetBuffAssetInfo(InBuffAssetType) if BuffManager.BuffAssetList[InBuffAssetType] == nil then BuffManager.BuffAssetList[InBuffAssetType] = require(BuffAssetConfig.AssetRootPath .. "." .. BuffAssetConfig.BuffFileName[InBuffAssetType]) end return BuffManager.BuffAssetList[InBuffAssetType] end --- 获取一个新的BuffID function BuffManager.GetNewBuffID() if BuffManager.NowBuffID == nil then BuffManager.NowBuffID = 1; else BuffManager.NowBuffID = 1 + BuffManager.NowBuffID; end return BuffManager.NowBuffID end --- 由于需要做同步处理,因此该变量在服务器和客户端需要采用不同的变量 function BuffManager.GetAllPlayerOwnedBuffs() if UGCGameSystem.IsServer() then return BuffManager.AllPlayerOwnedBuffs else return BuffManager.ClientAllPlayerOwnedBuffs end end --- 获取Buff的拥有者 ---@param InBuffID uint function BuffManager.GetBuffOwner(InBuffID) -- 服务器和客户端需要两套进行 local TargetAllPlayerOwnedBuffs = BuffManager.GetAllPlayerOwnedBuffs() for Pawn, PlayerOwnedBuff in pairs(TargetAllPlayerOwnedBuffs) do for BuffID, BuffActionType in pairs(PlayerOwnedBuff) do if BuffID == InBuffID then return Pawn end end end return -1 end --- 获取Buff的结束时间 ---@param InBuffID uint function BuffManager.GetBuffEndTime(InBuffID) local BuffInst = BuffManager.BuffInstList[InBuffID] if BuffInst then return BuffInst.EndTime end return -1 end --- 判断BuffAsset是否一直存在 function BuffManager.BuffIsAlwaysExists(InBuffAssetType) local BuffAssetInfo = BuffManager.GetBuffAssetInfo(InBuffAssetType) if BuffAssetInfo then return BuffAssetInfo.IsAlwaysExists end return false end --- 判断玩家是否拥有这个Buff function BuffManager.PlayerHasBuff(InPawn, InBuffAssetType) local PlayerOwnedBuff = BuffManager.GetAllPlayerOwnedBuffs()[InPawn] if PlayerOwnedBuff then for BuffID, BuffAssetType in pairs(PlayerOwnedBuff) do if BuffAssetType == InBuffAssetType then return true end end end return false end --- 获取玩家拥有的BuffAsset所有的BuffID function BuffManager.GetPlayerOwnedBuffIDFromBuffAssetType(InPawn, InBuffAssetType) local Res = {} local PlayerOwnedBuff = BuffManager.GetAllPlayerOwnedBuffs()[InPawn] if PlayerOwnedBuff then for BuffID, BuffAssetType in pairs(PlayerOwnedBuff) do if BuffAssetType == InBuffAssetType then Res[#Res + 1] = BuffID end end end return Res end --- 通过BuffID获取BuffInst信息 function BuffManager.GetBuffInstInfoFromBuffID(InBuffID) return BuffManager.BuffInstList[InBuffID] end --- 调用BuffInst里所有BuffAction的函数 function BuffManager.ExeBuffActionsFuncFromBuffInst(InBuffInst, FuncName, ...) if InBuffInst then for i, ActionInst in pairs(InBuffInst.BuffActions) do ActionInst[FuncName](ActionInst, ...) end end end --- Server --- 给玩家加入一个Buff,添加有很多种情况,不一定是创建新的Buff ---@param BuffCauser AController* @施加Buff的玩家或AI。 ---@param CauserActor AActor* @施加Buff的Actor,比如说PlayerPawn、燃烧瓶Actor等等 ---@return BuffID 如果失败则返回-1 这里的BuffID可能是之前已创建的,因为有些Buff为刷新时间的Buff function BuffManager.PlayerAddBuff(InPawn, InBuffAssetType, BuffCauser, CauserActor) UGCLogSystem.Log("[BuffManager_PlayerAddBuff] InBuffAssetType:%s", tostring(InBuffAssetType)) if UE.IsValid(InPawn) then -- 获取Buff资产的信息,该参数不可修改 local ConstBuffAsset = BuffManager.GetBuffAssetInfo(InBuffAssetType) if ConstBuffAsset then -- 获取Buff叠加类型 多次获得该Buff时所需要做的处理(延长时间或者叠加) local BuffRepeatedType = ConstBuffAsset.BuffRepeatedType -- 玩家拥有这个Buff的所有的BuffID local OwnedThisBuffIDs = BuffManager.GetPlayerOwnedBuffIDFromBuffAssetType(InPawn, InBuffAssetType) -- 玩家是否拥有这个Buff local PlayerHaveThisBuff = (#OwnedThisBuffIDs > 0) -- 获取Buff层数 local BuffLayer = #OwnedThisBuffIDs -- 通过叠加模式进行Switch分别处理 if BuffRepeatedType == BuffAssetConfig.EBuffRepeatedType.TimeExpand then --- Buff是时间刷新类型的Buff进行的处理 -- 判断玩家是否已有这个Buff if PlayerHaveThisBuff then --- 有这个Buff则调用Action刷新函数 -- 获取唯一的BuffID local OnceBuffID = OwnedThisBuffIDs[1] -- 获取已创建的Buff的实例 local BuffInst = BuffManager.GetBuffInstInfoFromBuffID(OnceBuffID) -- 判断Buff是否为永久存在的 if not BuffManager.BuffIsAlwaysExists(InBuffAssetType)then --- 该Buff不是永久存在的则需要刷新Buff的持续时间 BuffManager.AddBuffValidityTime(OnceBuffID, ConstBuffAsset.ValidityTime) end -- 调用一下刷新函数 BuffManager.ExeBuffActionsFuncFromBuffInst(BuffInst, "LuaResetAction") -- 若玩家已拥有这个永久存在的Buff且不为叠加模式的Buff则直接返回对应的ID return OnceBuffID else --- 没有这个Buff则创建一个并加入进去 -- New一个BuffID local BuffID = BuffManager.GetNewBuffID() -- 创建一个Buff给玩家 BuffManager.CreateBuffToPawn(BuffID, InPawn, InBuffAssetType, BuffCauser, CauserActor) return BuffID end elseif BuffRepeatedType == BuffAssetConfig.EBuffRepeatedType.Superposition then --- Buff是可重叠类型的Buff进行的处理 -- 判断是否超出层数 if ConstBuffAsset.LayerMax > BuffLayer then -- New一个BuffID local BuffID = BuffManager.GetNewBuffID() UGCLogSystem.Log("[BuffManager_PlayerAddBuff] BuffID:%s", tostring(BuffID)) -- 创建一个Buff给玩家 BuffManager.CreateBuffToPawn(BuffID, InPawn, InBuffAssetType, BuffCauser, CauserActor) return BuffID end end end end return -1 end --- 隔帧同步OwnedBuffInfo function BuffManager.IntervalFrameSyncOwnedBuffInfo() -- 这里是为了防止一帧中刷新多次参数,导致复杂度变为n^2,所做出的隔帧同步的处理 if BuffManager.SyncOwnedBuffInfoHandle == nil then BuffManager.SyncOwnedBuffInfoHandle = UGCEventSystem.SetTimer( UGCGameSystem.GameState, function() BuffManager.DOREPONCE_OwnedBuffInfo() BuffManager.SyncOwnedBuffInfoHandle = nil end, 0.01 ) end end --- 给玩家创建一个Buff,无需校验Pawn之类传入参数,在调用前需要验证好这些参数 ---@return BuffID function BuffManager.CreateBuffToPawn(InBuffID, InPawn, InBuffAssetType, InBuffCauser, InCauserActor) UGCLogSystem.Log("[BuffManager_CreateBuffToPawn]") local BuffActions = {} local ConstInBuffAsset = BuffManager.GetBuffAssetInfo(InBuffAssetType) for i, ActionInfo in pairs(ConstInBuffAsset.Actions) do local ActionType = ActionInfo.ActionType local Params = ActionInfo.Params -- New一个BuffAction local NewAction = BuffManager.GetCopyAction(ActionType) -- 调用BuffAction的初始化函数 NewAction:InitBuffAction(InBuffID, InPawn, Params) -- getmetatable(NewAction):InitBuffAction(InBuffID, InPawn, Params) -- 调用LuaDoAction函数 NewAction:LuaDoAction() -- 加入列表 BuffActions[ActionType] = NewAction end -- 获取Buff结束的GameTime,Client不对该时间进行判断,仅靠服务器的同步进行关闭等操作 local EndTime = ConstInBuffAsset.IsAlwaysExists and -1 or BuffManager.GetGameTime() + ConstInBuffAsset.ValidityTime -- 加入InstList BuffManager.BuffInstList[InBuffID] = {BuffAssetType = InBuffAssetType, OwnerPawn = InPawn, BuffCauser = InBuffCauser, CauserActor = InCauserActor, EndTime = EndTime, BuffActions = BuffActions} -- 设置玩家拥有的Buff if BuffManager.GetAllPlayerOwnedBuffs()[InPawn] == nil then BuffManager.GetAllPlayerOwnedBuffs()[InPawn] = {} end BuffManager.GetAllPlayerOwnedBuffs()[InPawn][InBuffID] = InBuffAssetType if UGCGameSystem.IsServer() then -- 隔帧同步玩家拥有的Buff BuffManager.IntervalFrameSyncOwnedBuffInfo() -- 玩家绑定Actor结束函数 BuffManager.PlayerBindOnEndPlayDelegate(InPawn) end end --- 增加Buff持续时间 此处无需验证BuffID function BuffManager.AddBuffValidityTime(InBuffID, InAddTime) UGCLogSystem.Log("[BuffManager_AddBuffValidityTime]") ---@param BuffInst table {BuffAssetType, OwnerPawn, BuffCauser, CauserActor, EndTime, BuffActions} local BuffInst = BuffManager.BuffInstList[InBuffID] local BuffAssetType = BuffInst.BuffAssetType local ConstBuffAssetInfo = BuffManager.GetBuffAssetInfo(BuffAssetType) local BuffEndTime = BuffManager.BuffInstList[InBuffID].EndTime -- 限制Buff增加的时间到最大时间 local AddTime = math.clamp(BuffManager.GetGameTime() - BuffEndTime + InAddTime, 0, ConstBuffAssetInfo.MaxValidityTime) UGCLogSystem.Log("[BuffManager_AddBuffValidityTime] InBuffID:%s, BuffEndTime:%s", tostring(InBuffID), tostring(BuffEndTime)) BuffManager.BuffInstList[InBuffID].EndTime = BuffManager.BuffInstList[InBuffID].EndTime + AddTime UGCLogSystem.Log("[BuffManager_AddBuffValidityTime] Finish BuffEndTime:%s", tostring(BuffManager.BuffInstList[InBuffID].EndTime)) -- 刷新所需同步的起始时间和结束时间 end --- 移除一个Buff function BuffManager.RemoveBuffFromBuffID(InBuffID) UGCLogSystem.Log("[BuffManager_RemoveBuffFromBuffID] InBuffID:%s", tostring(InBuffID)) -- BuffInst = {BuffAssetType, OwnerPawn, BuffCauser, CauserActor, EndTime, BuffActions} local BuffInst = BuffManager.BuffInstList[InBuffID] if BuffInst then -- 调用所有Action的移除函数 BuffManager.ExeBuffActionsFuncFromBuffInst(BuffInst, "LuaUndoAction") -- 清除BuffInst BuffManager.BuffInstList[InBuffID] = nil -- 获取该Buff的拥有者 local OwnerPlayer = BuffManager.GetBuffOwner(InBuffID) -- 清除该玩家对应的BuffID BuffManager.GetAllPlayerOwnedBuffs()[OwnerPlayer][InBuffID] = nil if UGCGameSystem.IsServer() then -- 隔帧同步OwnedBuffInfo BuffManager.IntervalFrameSyncOwnedBuffInfo() end end end --- 移除玩家的某个Buff ---@param Layer 移除的层数 function BuffManager.PlayerRemoveBuffFromBuffAssetType(InPawn, InBuffAssetType, Layer) UGCLogSystem.Log("[BuffManager_PlayerRemoveBuffFromBuffAssetType]") if BuffManager.GetAllPlayerOwnedBuffs()[InPawn] and Layer > 0 then for BuffID, BuffAssetType in pairs(BuffManager.GetAllPlayerOwnedBuffs()[InPawn]) do if InBuffAssetType == BuffAssetType then BuffManager.RemoveBuffFromBuffID(BuffID) Layer = Layer - 1 if Layer <= 0 then break end end end end end -- 清除玩家所有的Buff,一般用于玩家死亡 function BuffManager.ClearPlayerBuff(InPawn) UGCLogSystem.Log("[BuffManager_ClearPlayerBuff]") if BuffManager.GetAllPlayerOwnedBuffs()[InPawn] then for BuffID, BuffAssetType in pairs(BuffManager.GetAllPlayerOwnedBuffs()[InPawn]) do BuffManager.RemoveBuffFromBuffID(BuffID) end end BuffManager.GetAllPlayerOwnedBuffs()[InPawn] = nil end --- 玩家绑定死亡函数 function BuffManager.PlayerBindOnEndPlayDelegate(InPawn) if BuffManager.BoundOnEndPlayDelegatePlayers[InPawn] == nil then InPawn.OnEndPlay:Add(BuffManager.PlayerEndPlay, InPawn) InPawn.OnDeath:Add(BuffManager.PlayerDeath, InPawn) BuffManager.BoundOnEndPlayDelegatePlayers[InPawn] = 1 end end --- 玩家死亡函数 进行清除操作 ---@param DeadCharacter:ASTExtraCharacter function BuffManager.PlayerEndPlay(InPawn) UGCLogSystem.Log("[BuffManager_PlayerEndPlay]") -- 移除玩家已绑定死亡函数 BuffManager.BoundOnEndPlayDelegatePlayers[InPawn] = nil -- 清除玩家的Buff BuffManager.ClearPlayerBuff(InPawn) end function BuffManager.Tick() -- 获取DeltaSeconds local NowTime = BuffManager.GetGameTime() local DeltaSeconds = NowTime - BuffManager.LastTickTime -- 判断Buff时间是否到了该移除Buff的时候 local AllBuffID = table.getKeys(BuffManager.BuffInstList) -- UGCLogSystem.LogTree("[BuffManager_Tick] AllBuffID:", AllBuffID) for _, BuffID in pairs(AllBuffID) do local EndTime = BuffManager.GetBuffEndTime(BuffID) -- EndTime小于0则代表无限时长的Buff if EndTime > 0 and EndTime < NowTime then -- 由于时间间隔不同,所以需要做最后一次Tick的判断,传入的时间差是 local TempDeltaSeconds = EndTime - BuffManager.LastTickTime if TempDeltaSeconds > 0 then BuffManager.ExeBuffActionsFuncFromBuffInst(BuffManager.BuffInstList[BuffID], "LuaUpdateAction", TempDeltaSeconds) end BuffManager.RemoveBuffFromBuffID(BuffID) end end -- 调用BuffAction的Tick函数 for BuffID, BuffInst in pairs(BuffManager.BuffInstList) do BuffManager.ExeBuffActionsFuncFromBuffInst(BuffInst, "LuaUpdateAction", DeltaSeconds) end BuffManager.LastTickTime = NowTime end --- 客户端校验玩家拥有的Buff并进行创建和删除操作 function BuffManager.ClientUpdateAllPlayerOwnedBuffs() --UGCLogSystem.LogTree("[BuffManager_ClientUpdateAllPlayerOwnedBuffs]", BuffManager.AllPlayerOwnedBuffs) -- 先进行移除操作 for Pawn, PlayerOwnedBuff in pairs(BuffManager.ClientAllPlayerOwnedBuffs) do for BuffID, BuffAssetType in pairs(PlayerOwnedBuff) do if BuffManager.AllPlayerOwnedBuffs[Pawn] == nil or BuffManager.AllPlayerOwnedBuffs[Pawn][BuffID] == nil then BuffManager.RemoveBuffFromBuffID(BuffID) end end end -- 再进行添加操作 for Pawn, PlayerOwnedBuff in pairs(BuffManager.AllPlayerOwnedBuffs) do for BuffID, BuffAssetType in pairs(PlayerOwnedBuff) do if BuffManager.ClientAllPlayerOwnedBuffs[Pawn] == nil or BuffManager.ClientAllPlayerOwnedBuffs[Pawn][BuffID] == nil then if UE.IsValid(Pawn) then BuffManager.CreateBuffToPawn(BuffID, Pawn, BuffAssetType) end end end end end --- 校验Pawn是否有效,无效则清除对应Buff function BuffManager.CheckPawnIsValid() local AllPawn = UGCGameSystem.GetAllPlayerPawn() local HaveBuffPawn = table.getKeys(BuffManager.GetAllPlayerOwnedBuffs()) for Pawn, _ in pairs(HaveBuffPawn) do if not table.hasValue(AllPawn, Pawn) then BuffManager.ClearPlayerBuff(Pawn) end end end --- 用于Action的RPC函数, 这里不能保证客户端已同步Buff,因此采用传入BuffID是否为nil的方式判断是否使用单个实例的方法去调RPC,如果是客户端调服务器就肯定可以 function BuffManager.RPCActionFunc(InPlayerKey, BuffID, BuffActionType, FuncName, ...) UGCSendRPCSystem.ActorRPCNotify(InPlayerKey, UGCGameSystem.GameState, "DoBuffActionFunction", BuffID, BuffActionType, FuncName, ...) end function BuffManager.DoBuffActionFunction(BuffID, BuffActionType, FuncName, ...) local BuffInst = BuffManager.BuffInstList[BuffID] if BuffID == nil then --- 调单例的函数 local SimpleAction = BuffManager.GetSimpleAction(BuffActionType) if SimpleAction then SimpleAction[FuncName](SimpleAction, ...) else return false end elseif BuffInst and BuffInst.BuffActions[BuffActionType] and BuffInst.BuffActions[BuffActionType][FuncName] then --- 调BuffInst里的Action对应的函数 local BuffAction = BuffInst.BuffActions[BuffActionType] BuffAction[FuncName](BuffAction, ...) else return false end return true end