---@class SkillManager 技能管理器,区别于 BuffManager,技能管理器不会创建,都是瞬时的,但是会记录每个玩家使用技能的时间和 CD local BaseDir = "Script.Blueprint.SceneObj.Skill." local SkillManager = {}; --- 在最开始的时候进行全部加载 SkillManager.Config = nil; SkillManager.Owner = nil; SkillManager.Skills = {}; -- 所有的技能 SkillManager.OwnerSkills = {}; function SkillManager:Init(InOwner) UGCLogSystem.Log("[SkillManager:Init] 执行") -- 加载 Config self.Config = require(BaseDir .. 'SkillConfig'); self.Owner = InOwner; GlobalTickTool:AddTick(self, self.OnTick) for i, v in pairs(self.Config) do self:InitSingle(i, v); end end function SkillManager:InitSingle(i, v) local Item = require(BaseDir .. 'Script.Skill_' .. v.Name); self.Skills[i] = Item; Item.SkillID = i; if not table.isEmpty(v.Params) then for Name, Value in pairs(v.Params) do Item[Name] = Value; end end local HadInit = table.func(Item, "Init"); Item.HadInit = HadInit; end function SkillManager:OnTick(dt, st) if st == nil then return ; end for PlayerKey, Skills in pairs(self.OwnerSkills) do for SkillId, TimeInfo in pairs(Skills) do if not TimeInfo.CanExec then if TimeInfo.EndTime <= st then TimeInfo.CanExec = true; self:ResetSkill(SkillId, PlayerKey); end end end end end function SkillManager:GetSkillItem(InSkillId) if self.Skills[InSkillId] == nil then self:InitSingle(InSkillId, self.Config[InSkillId]); end return self.Skills[InSkillId]; end -- 发送 RPC function SkillManager:SendSkillRPC(InFuncName, InSkillId, InPlayerKey, ...) if IsServer then UnrealNetwork.CallUnrealRPC_Multicast_Unreliable(self.Owner, "SendSkillRPC", InFuncName, InSkillId, InPlayerKey, ...); end end --- 添加技能 ---@param InSkillId int32 function SkillManager:AddSkill(InSkillId, InPlayerKey, ...) assert(InSkillId ~= nil); UGCLogSystem.LogTree(string.format("[SkillManager:AddSkill] self.Config ="), self.Config) UGCLogSystem.Log("[SkillManager:AddSkill] InSkillId = %s", tostring(InSkillId)); assert(self.Config[InSkillId] ~= nil); local Item = self:GetSkillItem(InSkillId); if Item == nil then UGCLogSystem.Log("[SkillManager:AddSkill] SkillId = %d 的技能没有成功加入表中", InSkillId); return false; end -- 检查能量是否够,如果不够那么就无法执行 local Cost = self.Config[InSkillId].Cost; if IsServer then if Cost ~= nil and Cost > 0 then -- 获取 PS 里面的能量 local PS = UGCGameSystem.GetPlayerStateByPlayerKey(InPlayerKey); if UE.IsValid(PS) then if not self:AddSkillEnergy(-Cost) then return false; end end end end -- 验证一下是否可以执行 if self.OwnerSkills[InPlayerKey] == nil then self.OwnerSkills[InPlayerKey] = {}; else local SkillInfo = self.OwnerSkills[InPlayerKey][InSkillId]; if SkillInfo ~= nil then -- 没有到执行的时间呢 if not SkillInfo.CanExec then if IsServer then return false; end end end end -- 执行 Item.SkillId = InSkillId; local bSuccess = table.func(Item, "Add", InPlayerKey, ...); -- 执行成功 if not bSuccess then UGCLogSystem.Log("[SkillManager:AddSkill] 没有执行 %s 的 AddSkill 成功,请检查", self.Config[InSkillId].Name) return false; end -- 那就添加进去 local StartTime = UE.GetServerTime(); local Cooldown = self.Config[InSkillId].Cooldown; if Cooldown == nil then Cooldown = 0; end self.OwnerSkills[InPlayerKey][InSkillId] = { StartTime = StartTime, EndTime = StartTime + Cooldown; CanExec = false; -- 在冷却 }; if IsServer then self:SendSkillRPC("AddSkill", InSkillId, InPlayerKey, ...); end return true; end function SkillManager:RemoveSkill(InSkillId, InPlayerKey) table.func(self:GetSkillItem(InSkillId), "Remove", InPlayerKey); end function SkillManager:ResetSkill(InSkillId, InPlayerKey) table.func(self:GetSkillItem(InSkillId), "Reset", InPlayerKey); if IsServer then self:SendSkillRPC("ResetSkill", InSkillId, InPlayerKey); else end end return SkillManager;