---@class BP_MoveBase_C:AActor ---@field Box UBoxComponent ---@field StaticMesh UStaticMeshComponent ---@field DefaultSceneRoot USceneComponent ---@field Script FString ---@field MoveLength int32 --Edit Below-- require('Script.Global.Tool.TableTool') ---@type BP_MoveBase_C local BP_MoveBase = {}; ---@type bool 是否移动 BP_MoveBase.IsMove = false; BP_MoveBase.StartMoveTime = nil; BP_MoveBase.CachedIsMove = false; BP_MoveBase.CachedStartMoveTime = nil; ---@type MoveItemScriptBase BP_MoveBase.ScriptItem = nil; BP_MoveBase.ScriptParams = nil; BP_MoveBase.PreScript = "Script.Blueprint.SceneObj.Move.Script."; --- 继承用 function BP_MoveBase:new(...) local Params = {...}; if table.isEmpty(Params) then Params = nil; end return setmetatable({ IsMove = false, StartMoveTime = nil, CachedIsMove = false; CachedStartMoveTime = nil; ScriptItem = nil; ScriptParams = Params; }, { __index = self, __metatable = self, }); end --function BP_MoveBase:ReceiveBeginPlay() -- self.SuperClass.ReceiveBeginPlay(self); -- self:LuaInit(); --end function BP_MoveBase:LuaInit(...) UGCEventSystem.AddListener(EventTypes.ClientAlready, self.OnClientAlready, self) self:PreInit(); self:InitMove(...); self:PostInit(); end function BP_MoveBase:PreInit() end function BP_MoveBase:InitMove(...) UGCLogSystem.Log("[BP_MoveBase:InitMove] 执行") if string.len(self.Script) ~= 0 then self.Script = self.PreScript .. self.Script; local Item = require(self.Script); local Len = self.MoveLength > 0 and self.MoveLength or 1000; self.ScriptItem = setmetatable({ MoveLength = Len; Owner = self, }, { __index = Item; __metatable = Item; __tostring = function(t) return tostring(t.MoveLength); end }); if self.ScriptItem ~= nil then local Params = {...}; if table.isEmpty(Params) then self.ScriptParams = Params; end table.func(self.ScriptItem, self.ScriptItem['Init'], table.unpackTable(self.ScriptParams)); if self.ScriptItem['GetStaticMeshString'] ~= nil then local MeshStr, Transform = self.ScriptItem['GetStaticMeshString'](self.ScriptItem) if MeshStr ~= nil then UE.AsyncLoadObject(MeshStr, function(TargetObject) self.StaticMesh:SetStaticMesh(TargetObject); end) if Transform ~= nil then self.StaticMesh:K2_SetRelativeLocation(Transform.Translation); self.StaticMesh:K2_SetRelativeRotation(KismetMathLibrary.Quat_Rotator(Transform.Rotation)); self.StaticMesh:SetRelativeScale3D(Transform.Scale3D); end end end end end -- 通过这种方式注册,之后就不需要调用 Tick 了 if self.ScriptItem then GlobalTickTool:AddTick(self, self.MoveTick, 0, function(o, dt, ServerTime) return true; end) end end function BP_MoveBase:PostInit() end --- 服务器和客户端同时执行 function BP_MoveBase:StartMove(EnableMove, InTime) if IsServer then UGCLogSystem.Log("[BP_MoveBase:StartMove] 设置是否移动:%s", tostring(EnableMove)) self.IsMove = EnableMove; self.StartMoveTime = EnableMove and UE.GetServerTime() or nil; self.CachedIsMove = EnableMove; self.CachedStartMoveTime = self.StartMoveTime; UnrealNetwork.CallUnrealRPC_Multicast(self, "StartMove", self.IsMove, self.CachedStartMoveTime); DOREPONCE(self, "IsMove") DOREPONCE(self, "StartMoveTime") else UGCLogSystem.Log("[BP_MoveBase:StartMove] 设置是否移动:%s,StartMoveTime = %f", tostring(EnableMove), InTime) self.CachedIsMove = EnableMove; self.CachedStartMoveTime = InTime; end end function BP_MoveBase:OnRep_IsMove() self.CachedIsMove = self.IsMove; end function BP_MoveBase:OnRep_StartMoveTime() self.CachedStartMoveTime = self.StartMoveTime; UGCLogSystem.Log("[BP_MoveBase:OnRep_StartMoveTime] StartMoveTime = %s", tostring(self.StartMoveTime)); end --[[ function BP_MoveBase:ReceiveEndPlay() self.SuperClass.ReceiveEndPlay(self); end --]] function BP_MoveBase:GetReplicatedProperties() return { "IsMove", "Lazy" } , { "StartMoveTime", "Lazy" } end --[[ function BP_MoveBase:GetAvailableServerRPCs() return end --]] function BP_MoveBase:MoveTick(InDeltaTime, ServerTime) if not (self.CachedIsMove or self.IsMove) then return end if self.CachedStartMoveTime == nil or ServerTime == nil then return end local DeltaTime = ServerTime - self.CachedStartMoveTime; local Loc = table.func(self.ScriptItem, "Move", self, DeltaTime, InDeltaTime) if Loc then self:K2_SetActorLocation(Loc); end local Rot = table.func(self.ScriptItem, "Rotate", self, DeltaTime, InDeltaTime) if Rot then self:K2_SetActorLocation(Loc); end end function BP_MoveBase:GetIsMove() return self.CachedIsMove; end function BP_MoveBase:OnClientAlready() if IsServer then UGCLogSystem.Log("[BP_MoveBase:OnClientAlready] 执行") self:StartMove(true); end end return BP_MoveBase;