--移动组件 local ExpDriveSystem = {} local private = { _expBeDrivenDic = {} ,-- 记录那些entity被驾驶了(节约计算量) lastUpdateFrame = -1, selectEffEntityDic = {} ,-- (主视角)统计谁身上有了被选中特效 ,key = EntityID ,value = true ;key = EntityID为了不用处理entity消失的管理 ; } local EventSystem = require('Event/EventSystem') local tonumberV2=FP.tonumberV2 local Predict_Effect = ConstAssetPathConfig.Predict_Effect -- 资源关卡特殊的 local Predict_Effect_Resource = ConstAssetPathConfig.Predict_Effect_Resource local Predict_Count = 20 --上车后,需显示可被瞄准的特效 local PreTarget_Effect = ConstAssetPathConfig.RelativeEffect.Func_PreTarget_Relative --上车后 ,瞄准后 ,目标的头等特效 local Target_Effect = ConstAssetPathConfig.RelativeEffect.Func_Target_Relative --Tick function ExpDriveSystem.OnUpdate(deltaTime) for k, v in pairs(private._expBeDrivenDic) do private.SetAimPosPosition(v,v.Entity,deltaTime) end end function ExpDriveSystem.Clear() for k, v in pairs(private._expBeDrivenDic) do private._expBeDrivenDic[k] = nil end table.clear(private.selectEffEntityDic) private.lastUpdateFrame = -1 DrawLineManager.OffCar() -- 尝试清理瞄准特效 end -- 车出生 function ExpDriveSystem.OnBorn(expEntity) end --车culling变为visual function ExpDriveSystem.OnConvertRenderVisual(expEntity) local expDriveComp = expEntity.components.drive if expDriveComp then expDriveComp:RefreshCameraLocalEulerX() end end --expEntity 上车 function ExpDriveSystem.OnDriveEntity(expEntity) local beDrivedEntity = expEntity.Entity.components.drive.DriveEntity local expDriveComp = beDrivedEntity.ExpEntity.components.drive local layer = expEntity.components.model.Layer local driveComp = beDrivedEntity.components.drive local posZ = 100 if driveComp.AimPosZ then posZ= FP.tonumberV1(driveComp.AimPosZ) end -- 处理特殊UI if beDrivedEntity.ExpEntity.RedCircle then UIUtils.SetActive(beDrivedEntity.ExpEntity.RedCircle,true) local redCircleTrans = beDrivedEntity.ExpEntity.RedCircle.transform redCircleTrans:SetLocalPosition(0,0,posZ) local redCircle_PosX,redCircle_PosY,redCircle_PosZ = redCircleTrans:GetPosition() local high = AuxUtil.GetHigh(redCircle_PosX,redCircle_PosY,redCircle_PosZ) redCircleTrans:SetPosition(redCircle_PosX,high,redCircle_PosZ) expDriveComp.LastExpAimPosX = redCircle_PosX expDriveComp.LastExpAimPosZ = redCircle_PosZ expDriveComp.LastExpAimPosY = high AuxUtil.SetLayerInChildren(redCircleTrans, layer) private.SetParabolaLinesParam(beDrivedEntity, layer) DrawLineManager.DrawPredictParabolLine(redCircle_PosX,high,redCircle_PosZ) end expDriveComp:SetExpAimPosZ(posZ) private._expBeDrivenDic[beDrivedEntity.EntityID] = beDrivedEntity.ExpEntity private.ShowIndicatorEffect(beDrivedEntity) end --expEntity 下车 function ExpDriveSystem.OnOffDriveEntity(expEntity,beDrivedEntity) if beDrivedEntity.ExpEntity.RedCircle then UIUtils.SetActive(beDrivedEntity.ExpEntity.RedCircle,false) DrawLineManager.OffCar() end private._expBeDrivenDic[beDrivedEntity.EntityID] = nil private.StopIndicatorEffect(beDrivedEntity) private.StopSelectEffect(expEntity, beDrivedEntity) end -- 左右旋转不用走这个函数,自动的跟随逻辑移动了 function private.SetAimPosPosition(expEntity, beDrivedEntity, deltaTime) local driveComp = beDrivedEntity.components.drive if not driveComp.DriveData then return end local moveComp = beDrivedEntity.components.move local expDriveComp = beDrivedEntity.ExpEntity.components.drive local disSpeed = driveComp.realDisSpeed or ( driveComp.DriveData.DisSpeed * FP.Math.Abs(moveComp.WantRotateDir.z) ) -- todo:优化 local logicAimPosZ = FP.tonumberV1(driveComp.AimPosZ) local expAimPosZ = expDriveComp.ExpAimLocalPosZ local lerpMax = logicAimPosZ - expAimPosZ local oneStep = deltaTime * FP.tonumberV1(disSpeed) if math.abs(lerpMax) >= oneStep then if lerpMax > 0 then expAimPosZ = expAimPosZ + oneStep else expAimPosZ = expAimPosZ - oneStep end expDriveComp:SetExpAimPosZ(expAimPosZ) if beDrivedEntity.ExpEntity.RedCircle then local redCircleTrans = expEntity.RedCircle.transform redCircleTrans:SetLocalPosition(0,0,expAimPosZ) --设置高度 local redCircle_PosX,redCircle_PosY,redCircle_PosZ = redCircleTrans:GetPosition() local high = AuxUtil.GetHigh(redCircle_PosX,expDriveComp.LastExpAimPosY,redCircle_PosZ) redCircleTrans:SetPosition(redCircle_PosX,high,redCircle_PosZ) DrawLineManager.DrawPredictParabolLine(redCircle_PosX,high,redCircle_PosZ) expDriveComp.LastExpAimPosX = redCircle_PosX expDriveComp.LastExpAimPosZ = redCircle_PosZ expDriveComp.LastExpAimPosY = high end else -- 没有远近的进度,检查下是否左右的移动 if beDrivedEntity.ExpEntity.RedCircle then local redCircleTrans = expEntity.RedCircle.transform local redCircle_PosX,high,redCircle_PosZ = redCircleTrans:GetPosition() if expDriveComp.LastExpAimPosX ~= redCircle_PosX or expDriveComp.LastExpAimPosZ ~= redCircle_PosZ then local high = AuxUtil.GetHigh(redCircle_PosX,expDriveComp.LastExpAimPosY,redCircle_PosZ) redCircleTrans:SetPosition(redCircle_PosX,high,redCircle_PosZ) DrawLineManager.DrawPredictParabolLine(redCircle_PosX,high,redCircle_PosZ) expDriveComp.LastExpAimPosX = redCircle_PosX expDriveComp.LastExpAimPosZ = redCircle_PosZ expDriveComp.LastExpAimPosY = high end end end if beDrivedEntity.ExpEntity.RedCircle then private.TryShowSelectEffect(beDrivedEntity , expDriveComp.LastExpAimPosX ,expDriveComp.LastExpAimPosZ) end end function ExpDriveSystem.OnAttackEnter(expEntity) local driveData = expEntity.Entity.components.drive:GetDriveData() if driveData then if driveData.IsAttackHideExtraUI then if expEntity.RedCircle then UIUtils.SetActive(expEntity.RedCircle,false) DrawLineManager.SetPredictActive(false) end EventSystem.Dispatch(EventID.UIBattle_Drive_Collimator,false) end end end function ExpDriveSystem.OnMissileCancle(expMissile) if expMissile.Missile then local attacker = expMissile.Missile.Attacker if attacker then local expEntity = attacker.ExpEntity local driveData = expEntity.Entity.components.drive:GetDriveData() if driveData then if driveData.IsAttackHideExtraUI then if expEntity.RedCircle then UIUtils.SetActive(expEntity.RedCircle,true) DrawLineManager.SetPredictActive(true) end EventSystem.Dispatch(EventID.UIBattle_Drive_Collimator,true) end end end end end --这是抛物线参数 function private.SetParabolaLinesParam(carEntity, layer) local driveComp = carEntity.components.drive local predictCallID = driveComp:GetDriveData().PredictCallID local callData = DataSheetManager.CallBulletData:GetDataByID(predictCallID)--不需要通过entity获取skillData,因为这是载具 local offset = callData.Transform_Table[1].FireOffset local missileData = DataSheetManager.MissileData:GetDataByID(callData.BulletID)--不需要通过entity获取mISSILEData,因为这是载具 if missileData.MoveType ~= LuaConst.MissileMoveType.Parabola then return end local effectPath = nil if LevelManager.CheckCurLevelType(LuaConst.LevelType.Resource) then effectPath = Predict_Effect_Resource else effectPath = Predict_Effect end DrawLineManager.SetParabolaLineInitData(offset[1], offset[2], offset[3], missileData.ParabolaHight, carEntity.ExpEntity.RenderEntity.Transform, effectPath, Predict_Count, layer) end -- 显示特定feature的敌人特效指示特效 function private.ShowIndicatorEffect(carEntity) local driveData = carEntity.components.drive:GetDriveData() if not driveData then return end local featureIDList = driveData.IndicatorFeatureID if #featureIDList == 0 then-- 优化 ,如果没有需求显示特效,则终止 return end local enemyList2d = TargetManager.Get2DEnemyList(carEntity) for i,entityList in ipairs(enemyList2d) do for j, entityTemp in ipairs(entityList) do local temp_feature = entityTemp:GetFeatureID() local canShow = false for _,featureID in ipairs(featureIDList) do if featureID == temp_feature then canShow = true break; end end if canShow then SystemManager.ShowPSEffect(entityTemp, PreTarget_Effect) end end end end -- 隐藏特定feature的敌人 指示特效 function private.StopIndicatorEffect(carEntity) local driveData = carEntity.components.drive:GetDriveData() if not driveData then return end local featureIDList = driveData.IndicatorFeatureID if #featureIDList == 0 then-- 优化 ,如果没有需求显示特效,则无需执行 return end local enemyList2d = TargetManager.Get2DEnemyList(carEntity) for i,entityList in ipairs(enemyList2d) do for j, entityTemp in ipairs(entityList) do local temp_feature = entityTemp:GetFeatureID() local canShow = false for _,featureID in ipairs(featureIDList) do if featureID == temp_feature then canShow = true break; end end if canShow then SystemManager.StopPSEffect(entityTemp, PreTarget_Effect) end end end end --尝试显示选中特效 function private.TryShowSelectEffect(carEntity ,aimx , aimz) local driver = carEntity.components.drive:GetDriver() if driver ~= LogicUpdateManager._curEntity then return end if private.lastUpdateFrame == LogicUpdateManager._clientHandleFrame then -- 表现帧比逻辑帧多执行,为了更高效些 return end private.lastUpdateFrame = LogicUpdateManager._clientHandleFrame private.ShowSelectEffect(carEntity , aimx , aimz) end function private.IsInRedCircle(aimx , aimz , logicPos ,radius) local lx ,lz = tonumberV2(logicPos) if math.abs(aimx - lx) > radius or math.abs(aimz - lz) > radius then --为了更高效些 ,当成矩形写了,以后若要更精确 ,可改为圆 return false end return true end -- 显示和 隐藏 特定feature的敌人选中特效 function private.ShowSelectEffect(carEntity ,aimx , aimz) local driveData = carEntity.components.drive:GetDriveData() local radius = driveData.AimRadius local featureIDList = driveData.SelectFeatureID if #featureIDList == 0 then-- 优化 ,如果没有需求显示特效,则终止 return end local enemyList2d = TargetManager.Get2DEnemyList(carEntity) for i,entityList in ipairs(enemyList2d) do for j, entityTemp in ipairs(entityList) do if private.selectEffEntityDic[entityTemp.EntityID] then if not private.IsInRedCircle(aimx , aimz , entityTemp:GetLogicPos() ,radius) then -- 出圈了 SystemManager.StopPSEffect(entityTemp, Target_Effect) private.selectEffEntityDic[entityTemp.EntityID] = nil end else local temp_feature = entityTemp:GetFeatureID() local find = false for _,featureID in ipairs(featureIDList) do if featureID == temp_feature then find = true break; end end if find then -- 进圈了 if private.IsInRedCircle(aimx , aimz , entityTemp:GetLogicPos() ,radius) then SystemManager.ShowPSEffect(entityTemp, Target_Effect) private.selectEffEntityDic[entityTemp.EntityID] = true end end end end end end function private.StopSelectEffect(expDriverEntity,carEntity) local driver = expDriverEntity.Entity if driver ~= LogicUpdateManager._curEntity then return end for entityID , v in pairs(private.selectEffEntityDic) do local entity = LogicUpdateManager._entityDic[entityID] if entity then SystemManager.StopPSEffect(entity, Target_Effect) private.selectEffEntityDic[entity.EntityID] = nil end end end return ExpDriveSystem