---@class BP_DigitalTrapManager_C:AActor ---@field Cable3 UCableComponent ---@field Cable2 UCableComponent ---@field Cable1 UCableComponent ---@field Cable UCableComponent ---@field AllCable USceneComponent ---@field StaticMesh6 UStaticMeshComponent ---@field StaticMesh5 UStaticMeshComponent ---@field StaticMesh4 UStaticMeshComponent ---@field StaticMesh3 UStaticMeshComponent ---@field StaticMesh2 UStaticMeshComponent ---@field StaticMesh UStaticMeshComponent ---@field StaticMesh1 UStaticMeshComponent ---@field Cube UStaticMeshComponent ---@field Scene USceneComponent ---@field ChildActor7 UChildActorComponent ---@field ChildActor6 UChildActorComponent ---@field ChildActor5 UChildActorComponent ---@field ChildActor4 UChildActorComponent ---@field ChildActor3 UChildActorComponent ---@field ChildActor2 UChildActorComponent ---@field ChildActor1 UChildActorComponent ---@field ChildActor UChildActorComponent ---@field BP_DigitalTrap UChildActorComponent ---@field DefaultSceneRoot USceneComponent ---@field InitDigitalMin int32 ---@field InitDigitalMax int32 ---@field ResetTrapRoundNum int32 ---@field TrapTimeIntervalCurve UCurveFloat --Edit Below-- local BP_DigitalTrapManager = { AllChildTrap = {}; AllDigital = {}; TrapID = 0; NumberZeroingID= {}; -- {TrapID = TrapActor} TrapMap = {}; -- 玩法持续时间 TrapGameTime = -1; -- 玩法开始时间 StartTime = 0.; bIsPlaying = false; LastExeAllTrapTime = 0.; -- 初始化随机数字 InitNums = {9,9,8,7,6,5,4,3,4}; }; function BP_DigitalTrapManager:ReceiveBeginPlay() self.SuperClass.ReceiveBeginPlay(self); self.AllChildTrap = self:GetAllChildActors({}, false) if UGCGameSystem.IsServer() then self:InitTrap() end end function BP_DigitalTrapManager:InitTrap() self.TrapGameTime = MiniGameConfig.MiniGameInfo[MiniGameConfig.MiniGameType.DigitalTrap].MaxGameTime self.AllDigital = {} table.Shuffle(self.InitNums) for i, TrapActor in pairs(self.AllChildTrap) do local NewDigital = self.InitNums[i] local TrapID = self:GetTrapNewID() TrapActor:SetTargetDigital(NewDigital) TrapActor:SetTrapID(TrapID) TrapActor:BindPlayerOverlap(self.TrapOverlapPlayer, self) self.TrapMap[TrapID] = TrapActor end end function BP_DigitalTrapManager:StartPlay() if self.bIsPlaying == false then self.bIsPlaying = true self.StartTime = UGCSystemLibrary.GetGameTime() self.LastExeAllTrapTime = self.StartTime local UpdateClientDigitalTraps = {} for i, TrapActor in pairs(self.AllChildTrap) do UpdateClientDigitalTraps[TrapActor:GetTrapID()] = TrapActor:GetTargetDigital() end self:ClientUpdateTrapsDigital(UpdateClientDigitalTraps) end end function BP_DigitalTrapManager:StopTrapGame() self.bIsPlaying = false end function BP_DigitalTrapManager:GetTrapNewID() self.TrapID = self.TrapID + 1 return self.TrapID end --- 获取一个新的数字 function BP_DigitalTrapManager:GetNewDigital() return math.random(self.InitDigitalMin, self.InitDigitalMax) end --- 玩家重叠到陷阱时触发的回调,使陷阱数字减一 function BP_DigitalTrapManager:TrapOverlapPlayer(InTrapActor) if self.bIsPlaying then if InTrapActor:GetTargetDigital() > 0 then InTrapActor:MinusOne() local TargetDigital = InTrapActor:GetTargetDigital() if TargetDigital <= 0 then self:TrapDigitalIsZero({InTrapActor:GetTrapID()}) else UGCSendRPCSystem.ActorRPCNotify(nil, InTrapActor, "ClientSetDigital", TargetDigital) end end end end --- 陷阱至0时客户端和服务器关闭碰撞 function BP_DigitalTrapManager:TrapDigitalIsZero(TrapIDs) if TrapIDs == nil or #TrapIDs <= 0 then return end if UGCGameSystem.IsServer() then UGCSendRPCSystem.ActorRPCNotify(nil, self, "TrapDigitalIsZero", TrapIDs) -- 设置重置间隔轮数 for i, TrapID in pairs(TrapIDs) do self.NumberZeroingID[TrapID] = self.ResetTrapRoundNum end end for i, TrapID in pairs(TrapIDs) do if self.TrapMap[TrapID] then if UGCGameSystem.IsServer() then self.TrapMap[TrapID]:SetTargetDigital(0) else self.TrapMap[TrapID]:ClientSetDigital(0) end end end SoundSystem.PlaySound(SoundSystem.ESound.TrapOpen) UGCEventSystem.SetTimer(self, function() for i, TrapID in pairs(TrapIDs) do if self.TrapMap[TrapID] and UE.IsValid(self.TrapMap[TrapID]) then self.TrapMap[TrapID]:SetTrapCollision(false) else UGCLogSystem.LogError("[BP_DigitalTrapManager_SetOverlapZeroingTrapNonCollision] TrapID:%s is nil", tostring(TrapID)) end end end, 0.1) end --- 客户端更新数字 function BP_DigitalTrapManager:ClientUpdateTrapsDigital(TrapsDigital) if UGCGameSystem.IsServer() and table.getCount(TrapsDigital) > 0 then UGCSendRPCSystem.ActorRPCNotify(nil, self, "ClientUpdateTrapsDigital", TrapsDigital) return end SoundSystem.PlaySound(SoundSystem.ESound.Clock) local TrapIDs = table.getKeys(TrapsDigital) for i, TrapID in pairs(TrapIDs) do if self.TrapMap[TrapID] then self.TrapMap[TrapID]:ClientSetDigital(TrapsDigital[TrapID]) self.TrapMap[TrapID]:SetTrapCollision(true) end end end --- 更新归零的数字 function BP_DigitalTrapManager:UpdateNumberZeroingID() local ResetTrapIDs = {} local Res = {} local TrapIDs = table.getKeys(self.NumberZeroingID) for _, TrapID in pairs(TrapIDs) do local NumRound = self.NumberZeroingID[TrapID] if NumRound - 1 <= 0 then self.NumberZeroingID[TrapID] = nil ResetTrapIDs[#ResetTrapIDs + 1] = TrapID else self.NumberZeroingID[TrapID] = NumRound - 1 end end for i, TrapID in pairs(ResetTrapIDs) do if self.TrapMap[TrapID] then local NewDigital = self:GetNewDigital() self.TrapMap[TrapID]:SetTargetDigital(NewDigital) self.TrapMap[TrapID]:SetTrapCollision(true) Res[self.TrapMap[TrapID]:GetTrapID()] = NewDigital end end return Res end function BP_DigitalTrapManager:ExeAllTrapMinusOne() local UpdateClientDigitalTraps = {} local ZeroingTrapIDs = {} for i, TrapActor in pairs(self.AllChildTrap) do if TrapActor:GetTargetDigital() > 0 then TrapActor:MinusOne() if TrapActor:GetTargetDigital() > 0 then UpdateClientDigitalTraps[TrapActor:GetTrapID()] = TrapActor:GetTargetDigital() else ZeroingTrapIDs[#ZeroingTrapIDs + 1] = TrapActor:GetTrapID() end end end local ResetTrapDigital = self:UpdateNumberZeroingID() for TrapID, Digital in pairs(ResetTrapDigital) do UpdateClientDigitalTraps[TrapID] = Digital end self:TrapDigitalIsZero(ZeroingTrapIDs) self:ClientUpdateTrapsDigital(UpdateClientDigitalTraps) end function BP_DigitalTrapManager:ReceiveTick(DeltaTime) self.SuperClass.ReceiveTick(self, DeltaTime); if UGCGameSystem.IsServer() then if self.bIsPlaying then local NowTime = UGCSystemLibrary.GetGameTime() local PlayTime = NowTime - self.StartTime if PlayTime > self.TrapGameTime then self:StopTrapGame() return else local ExeAllTrapTime = self.TrapTimeIntervalCurve:GetFloatValue(PlayTime / self.TrapGameTime) if NowTime - self.LastExeAllTrapTime >= ExeAllTrapTime then self:ExeAllTrapMinusOne() self.LastExeAllTrapTime = NowTime end end end end end --[[ function BP_DigitalTrapManager:ReceiveEndPlay() self.SuperClass.ReceiveEndPlay(self); end --]] function BP_DigitalTrapManager:GetReplicatedProperties() return "TrapMap" end --[[ function BP_DigitalTrapManager:GetAvailableServerRPCs() return end --]] return BP_DigitalTrapManager;