---@class WB_BuffButton_C:UUserWidget ---@field Image_CD UImage ---@field Image_Icon UImage ---@field NewButton_Main UNewButton ---@field TextBlock_CD UTextBlock --Edit Below-- ---@type WB_BuffButton_C local WB_BuffButton = { bInitDoOnce = false; }; require('Script.Blueprint.SceneObj.Buff.BuffConfig') WB_BuffButton.BuffType = EBuffType.AddSpeed; WB_BuffButton.CanClick = true; WB_BuffButton.BuffState = EBuffState.None; WB_BuffButton.CDMaterial = nil; WB_BuffButton.BuffIndex = 0; WB_BuffButton.BuffEndTimes = {}; function WB_BuffButton:Construct() self:LuaInit(); end function WB_BuffButton:LuaInit() if self.bInitDoOnce then return ; end self.NewButton_Main.OnClicked:Add(self.OnClickBuff, self); UITool.EnableButtonScroll(self.NewButton_Main); UGCEventSystem.AddListener(EventTypes.PlayerUseBuff, self.OnPlayerUseBuff, self) UGCEventSystem.AddListener(EventTypes.ChangeBuffs, self.OnChangeBuffs, self) self:GetDynamicMaterial(); self:ResetBuff(); self:SetBuffType(self.BuffType); -- 获取一下 self.bInitDoOnce = true; end function WB_BuffButton:SetBuffIndex(InIndex) self.BuffIndex = InIndex; if LocalPlayerController.Buffs[InIndex] ~= nil then self:SetBuffType(LocalPlayerController.Buffs[InIndex]); end end function WB_BuffButton:GetBuffIndex() return self.BuffIndex end function WB_BuffButton:SetBuffType(InType) if self.BuffType == InType then return false; end self.BuffType = InType; GameState.BuffManager:ChangeBuffIcon(InType, self.Image_Icon); UGCLogSystem.Log("[WB_BuffButton:SetBuffType] Buff = %s", BuffConfig[InType].Name); return true; end function WB_BuffButton:GetBuffType() return self.BuffType; end function WB_BuffButton:OnClickBuff() -- 发送 RPC if self.CanClick then UnrealNetwork.CallUnrealRPC(LocalPlayerController, LocalPlayerController, "AddBuff", self:GetBuffType()); self.CanClick = false; end end function WB_BuffButton:OnChangeBuffs(InPlayerKey, InBuffs) if InPlayerKey ~= LocalPlayerKey then return ; end if self:SetBuffType(InBuffs[self.BuffIndex]) then -- 检查是否之前点击过 local Times = self.BuffEndTimes[self.BuffType]; if Times == nil then return ; end local st = UE.GetServerTime(); if Times.Cooldown + Times.StartTime + Times.Continue >= st then self:ChangeState(EBuffState.None); else if Times.StartTime <= st then return ; end if Times.StartTime + Times.Continue <= st then self:ChangeState(EBuffState.Using); else self:ChangeState(EBuffState.Cooling); end end end end function WB_BuffButton:ResetBuff() self:ChangeState(EBuffState.None); end WB_BuffButton.BuffStateInfo = { [EBuffState.None] = { IconColor = { 1, 1, 1, 1 }, TextColor = { 1, 1, 1, 0 }, CDColor = { 1, 1, 1, 0 } }, [EBuffState.Using] = { IconColor = { 0.302083, 0.302083, 0.302083, 0.609 }, TextColor = { 0, 1., 0.284620, 1 }, CDColor = { 0, 0.385049, 0.645833, 0.495 } }, [EBuffState.Cooling] = { IconColor = { 0.088542, 0.088542, 0.088542, 1 }, TextColor = { 1, 0, 0, 1 }, CDColor = { 0.020833, 0.020833, 0.020833, 0.75 } }, }; function WB_BuffButton:ChangeStateColor(State) self.Image_Icon:SetColorAndOpacity(VectorHelper.ArrToColor(self.BuffStateInfo[State].IconColor)); self.TextBlock_CD:SetColorAndOpacity({ SpecifiedColor = VectorHelper.ArrToColor(self.BuffStateInfo[State].TextColor), ColorUseRule = 0 }); self.Image_CD:SetColorAndOpacity(VectorHelper.ArrToColor(self.BuffStateInfo[State].CDColor)); end function WB_BuffButton:ChangeState(State) self.BuffState = State; self:ChangeStateColor(State); end function WB_BuffButton:OnPlayerUseBuff(InPlayerKey, BuffType, State, InStateInfo) if InPlayerKey ~= LocalPlayerKey then return ; end if BuffType ~= self.BuffType then return ; end self:ChangeState(State); UGCLogSystem.Log("[WB_BuffButton:OnPlayerUseBuff] State = %s", TableHelper.printEnum(EBuffState, State)); if State == EBuffState.None then -- 启动 self:SetBuffNone(BuffType); elseif State == EBuffState.Using then self:SetBuffUsing(BuffType, InStateInfo) else self:SetBuffCooling(BuffType, InStateInfo) end end function WB_BuffButton:GetDynamicMaterial() if self.CDMaterial == nil then self.CDMaterial = self.Image_CD:GetDynamicMaterial(); end return self.CDMaterial; end function WB_BuffButton:SetBuffNone(BuffType) UGCLogSystem.Log("[WB_BuffButton:SetBuffNone] 执行") -- 设置成正常状态 self.CanClick = true; end WB_BuffButton.BuffStartTime = 0; ---@generic T ---@param ef fun(o:T):bool function WB_BuffButton:SetCD(EndTime, StartTime, ef) local Interval = EndTime - UE.GetServerTime(); -- 启动,设置 CD 时间 UGCLogSystem.Log("[WB_BuffButton:SetCD] EndTime = %s, Interval = %f", tostring(EndTime), Interval); local Add = GlobalTickTool:AddTick(self, function(o, dt, st) local t = EndTime - st; local Percent = t / Interval; UGCLogSystem.Log("[WB_BuffButton:SetCD] Percent = %f", Percent); self:GetDynamicMaterial():SetScalarParameterValue("Mask_Percent", 1 - Percent); t = t >= 0 and math.ceil(t) or 0; --UGCLogSystem.Log("[WB_BuffButton:SetCD] t = %s", tostring(t)); self.TextBlock_CD:SetText(tostring(t)); end, nil, ef, EndTime - UE.GetServerTime(), function(o) self:GetDynamicMaterial():SetScalarParameterValue("Mask_Percent", 1.); end); UGCLogSystem.Log("[WB_BuffButton:SetCD] Add = %s", tostring(Add)); end function WB_BuffButton:SetBuffUsing(BuffType, InStateInfo) UGCLogSystem.Log("[WB_BuffButton:SetBuffUsing] 执行") local Continue = BuffConfig[BuffType].Continue; if Continue == 0 then self:SetBuffCooling(BuffType); return ; end self.BuffEndTimes[BuffType] = { StartTime = InStateInfo.StartTime, Continue = BuffConfig[BuffType].Continue, Cooldown = BuffConfig[BuffType].Cooldown, }; UGCLogSystem.Log("[WB_BuffButton:SetBuffUsing] Interval = %f", InStateInfo.EndTime - InStateInfo.StartTime); self:SetCD(InStateInfo.EndTime, InStateInfo.StartTime, function(o) return o.BuffState == EBuffState.Using; end); end function WB_BuffButton:SetBuffCooling(BuffType, InStateInfo) UGCLogSystem.Log("[WB_BuffButton:SetBuffCooling] 执行") local Cooldown = BuffConfig[BuffType].Cooldown; if Cooldown == 0 then self:SetBuffNone(BuffType); return ; end UGCLogSystem.Log("[WB_BuffButton:SetBuffCooling] Interval = %f", InStateInfo.EndTime - InStateInfo.StartTime); self:SetCD(InStateInfo.EndTime, InStateInfo.StartTime, function(o) return o.BuffState == EBuffState.Cooling; end); end -- function WB_BuffButton:Tick(MyGeometry, InDeltaTime) -- end -- function WB_BuffButton:Destruct() -- end return WB_BuffButton;