--旋转 local RotateSystem = {} local private = {} local FP=FP local _angleV1 = FP.newV1(0) local LuaConst=LuaConst local math_floor=math.floor local math_ceil=math.ceil local tonumberV1=FP.tonumberV1 local FP_Const_Zero=FP.Const.Zero local SKILLTYPE_ENEGY = LuaConst.SkillType.Enegy local _v1Temp = FP.newV1(0) local _v1Temp2 = FP.newV1(0) local _v1TempK = FP.newV1(0) local temp_angle = FP.newV1(0) local tempV2 = FP.newV2(0,0) local hurtDirctionType = { Bullet_Center = 0, Bullet_Face = 1, Character_Center = 2, --Character_Face = 3, Bullet_Face_Sector = 4, KeepLast = 5, BackToAttackerOrigin = 6, -- 背向子弹发射者的OriginEntity的位置 } --[[ 传送 --]] function RotateSystem.OnConvey(entity, forward) entity:SetLogicRotateDir(forward):Normalize() entity.components.move.LastLogicRotateDir:Reset(entity:GetLogicRotateDir()) end --[[ 变身 --]] function RotateSystem.OnSwitchHero(fromEntity, toEntity, dontBackground) if not dontBackground then private.SetRotateDir(toEntity.components.move, fromEntity.components.move.LogicRotateDir) end end function RotateSystem.BackToBornPoint(entity) local bornItemID = entity._logicInitData.BornItemID local itemData = LevelItemManager.GetItemDataByID(bornItemID) private.SetRotateDir(entity.components.move, itemData.ItemDir) end --[[ 复活 --]] function RotateSystem.OnRevive(entity,isInBornPoint) if isInBornPoint then local bornItemID = entity._logicInitData.BornItemID local itemData = LevelItemManager.GetItemDataByID(bornItemID) private.SetRotateDir(entity.components.move, itemData.ItemDir) end entity.components.move.LockExpRotate = false end --[[ Tick --]] function RotateSystem.OnLogicUpdate(entity) local buffComponent = entity.components.buff if not buffComponent.CurrentBuffStates:Get(LuaConst.SpecialBuffs.CanRotate) then return end local moveComponent = entity.components.move --控制技能释放过程中的朝向 --private.SetDirWhenAttack(entity) local changeImmediately = private.TrySetDirWhenAnim(entity) --尝试改变朝向 if entity:CheckHasBuffState(LuaConst.SpecialBuffs.HorseUpdateSelfAnim) then -- 骑着马且马受到摇杆的控制 private.OnHorseUpdate(moveComponent,entity) else private.TryToSetRotateDir(moveComponent, changeImmediately ,entity) end end function RotateSystem.OnLogicUpdate_NPC(entity) local comp_Move = entity.components.move --尝试改变朝向 private.TryToSetRotateDir(comp_Move, false ,entity) end --[[ 进入攻击 --]] function RotateSystem.OnAttackEnter(entity) -- 被驾驶的entity,释放技能的时候不要再自动转向了 local driveComp = entity.components.drive if driveComp and driveComp.BeDrived and driveComp:GetDriveData() then return end local skillBaseComponent = entity.components.skillBase if not entity.components.buff.CurrentBuffStates:Get(LuaConst.SpecialBuffs.CanRotate) then if skillBaseComponent.CurSkillJoystickData == nil or skillBaseComponent.CurSkillJoystickData.AimPosType ~= LuaConst.ESkillJoystickAimPosType.Target then --如果技能有双摇杆配置 return end end local moveComponent = entity.components.move local skillData = skillBaseComponent.CurSkillData local target = entity.components.target.Target local hasSkillJoystickSetDir = false -- if skillBaseComponent.CurSkillJoystickData then --如果技能有双摇杆配置 --这里约定如果大于360度,属于无效设置,就不会生效 --old↓ SkillJoystickDirAngle优化掉,减少传输数据量 -- if skillBaseComponent.SkillJoystickDirAngle and skillBaseComponent.SkillJoystickDirAngle <= FP.Const.Degree360 then --有技能摇杆输入(双摇杆中右边的摇杆) -- local rad = skillBaseComponent.SkillJoystickDirAngle / FP.Const.Degree180 * FP.Const.PI -- moveComponent.WantRotateDir.x:Reset(FP.Math.Sin(rad) ) -- moveComponent.WantRotateDir.z:Reset(FP.Math.Cos(rad) ) -- end --old↑ if skillBaseComponent.SkillJoystickOffsetX ~= FP.Const.Zero or skillBaseComponent.SkillJoystickOffsetZ ~= FP.Const.Zero then local joystickAimX = moveComponent.LogicPos.x + skillBaseComponent.SkillJoystickOffsetX local joystickAimZ = moveComponent.LogicPos.z + skillBaseComponent.SkillJoystickOffsetZ local joyPos = FP.newV2(joystickAimX, joystickAimZ) local targetPos = joyPos local AimPosType = skillBaseComponent.CurSkillJoystickData.AimPosType if AimPosType == LuaConst.ESkillJoystickAimPosType.Animation then SystemManager.OnSetSkillAimPos(entity, targetPos) elseif AimPosType == LuaConst.ESkillJoystickAimPosType.Target then if target then targetPos = target:GetLogicPos() --注意这里不能clone,因为策划要求位置实时变化(这写法有点黑科技) SystemManager.OnSetSkillAimPos(entity, targetPos) else SystemManager.OnSetSkillAimPos(entity, targetPos) end elseif AimPosType == LuaConst.ESkillJoystickAimPosType.MissileAndAnimation then --SystemManager.SetSkillMissilePos(entity, targetPos) SystemManager.OnSetSkillAimPos(entity, targetPos) end SystemManager.SetSkillJoystickPos(entity,targetPos) local wantRotateDir = targetPos - moveComponent.LogicPos wantRotateDir:Normalize() moveComponent:SetWantRotateDir(wantRotateDir) hasSkillJoystickSetDir = true elseif entity.components.autoFight:IsAutoFight() or entity.isRetinue then local aiBase = entity.components.aiBase if aiBase.AISkillJoystickPos and aiBase.AISkillJoystickPos ~= FP.Const.Vector2_Zero then SystemManager.SetSkillJoystickPos(entity, aiBase.AISkillJoystickPos) end end end -- 需要在技能开始时 ,改变朝向 if not skillData.DontRotateWhenStart and not skillBaseComponent:GetAutoNextSkillHoldToward() then local driveComp = entity.components.drive if entity._logicInitData.IsPlayer or (driveComp and driveComp.BeDrived and (not driveComp:GetDriveData())) then --玩家(或者玩家驾驶的载具的操作模式是一般性战斗操作如阿修罗) target = entity.components.target.Target if skillBaseComponent.CurSkillJoystickData and hasSkillJoystickSetDir then --如果技能有双摇杆配置,且双摇杆设置了方向,就do nothing else if moveComponent.WantMoveDir ~= FP.Const.Vector2_Zero then --有摇杆输入 if not private.SetPlayerAttackDir(target, skillData, skillBaseComponent, moveComponent ,entity) then --不满足攻击转向的规则 --TODO 马的处理 end if skillData.IsMoveByHandle then private.TryToSetRotateDir(moveComponent, false,entity) return end else --无摇杆输入 private.SetPlayerAttackDir(target, skillData, skillBaseComponent, moveComponent ,entity) end end else --非玩家 if skillBaseComponent.AimPos ~= nil then -- 技能释放有固定朝向点 private.SetAttackDir(skillBaseComponent.AimPos,target, skillData, skillBaseComponent, moveComponent ,entity) elseif target then -- --若有目标,转向目标--否则,朝向不变 private.SetAttackDir( nil,target, skillData, skillBaseComponent, moveComponent ,entity) end end --尝试改变朝向 private.TryToSetRotateDir(moveComponent, true, entity) end entity.components.anim:SetCurAnimStartDir() end --[[ 被子弹攻击加上受伤buff时 --]] function RotateSystem.OnAddMissileHitBuff(entity,buffid,missile) if missile == nil then return end local beHitNotRotate = entity.components.buff:GetBuffUpdateData(LuaConst.SpecialBuffs.BeHitNotRotate) if beHitNotRotate then return end local moveComponent = entity.components.move if entity._logicInitData.CharacterType == LuaConst.CharacterType.Monster then if buffid == LuaConst.SpecialBuffs.InHitDown or buffid == LuaConst.SpecialBuffs.InHitUp or buffid == LuaConst.SpecialBuffs.InHitFlyPlayer or buffid == LuaConst.SpecialBuffs.InHitFlyMonster or buffid == LuaConst.SpecialBuffs.InFlyFlyingMonster or buffid == LuaConst.SpecialBuffs.InHitPush then moveComponent.LockExpRotate = true end end local type = missile.MissileData.HurtDirctionType --↓策划要的特需:怪没死,就不能被推散 (手雷爆炸也不行) --if entity:IsAlive() then -- type = hurtDirctionType.Bullet_Face --end --↑特需 if type == hurtDirctionType.Bullet_Center then tempV2:Reset(missile.Pos):Sub(moveComponent.LogicPos):Normalize() moveComponent:SetWantRotateDir(tempV2) elseif type == hurtDirctionType.Bullet_Face then moveComponent:SetWantRotateDir(-missile.MoveDir) elseif type == hurtDirctionType.Character_Center then tempV2:Reset(missile.Attacker.components.move.LogicPos):Sub(moveComponent.LogicPos):Normalize() moveComponent:SetWantRotateDir(tempV2) elseif type == hurtDirctionType.Bullet_Face_Sector then local angle = LogicRandom.GetRangeValue(entity, -missile.MissileData.HurtDirectionAngle, missile.MissileData.HurtDirectionAngle ,28) moveComponent:SetWantRotateDir(FP.V2.GetOffsetToAngle(angle, moveComponent.LogicRotateDir)) elseif type == hurtDirctionType.KeepLast then moveComponent:SetWantRotateDir(moveComponent.LogicRotateDir) elseif type == hurtDirctionType.BackToAttackerOrigin then tempV2:Reset(moveComponent.LogicPos):Sub(missile.Attacker:GetOriginEntity().components.move.LogicPos):Normalize() moveComponent:SetWantRotateDir(tempV2) end private.TryToSetRotateDir(moveComponent, true, entity) entity.components.anim:SetCurAnimStartDir() end --[[ entity 有动作时,判断朝向 --]] local tempAngle = FP.newV1(0) local temp_passedFrame = FP.newV1(0) local temp_lastPassedFrame = FP.newV1(0) local temp_lastLeftTime = FP.newV1(0) local temp_cutExrTime = FP.newV1(0) local temp_durationTime = FP.newV1(0) function private.TrySetDirWhenAnim(entity) local changeImmediately = false local comp_Anim = entity.components.anim if comp_Anim.CurMoveMode == LuaConst.MoveMode.ByMoveManual then return changeImmediately end local moveComponent = entity.components.move --if moveComponent.WantRotateDir ~= FP.Const.Vector2_Zero then -- return changeImmediately --end -- 优先判断 :是否技能实时朝向目标 local curSkillData = entity.components.skillBase.CurSkillData local statePassTime = entity.components.anim.StatePassTime local target = entity.components.target.Target if curSkillData and target and (curSkillData.FaceAim and statePassTime >= curSkillData.FaceAimStart and statePassTime < curSkillData.FaceAimEnd or (curSkillData.Type == SKILLTYPE_ENEGY and entity.components.autoFight:IsAuto())) then tempV2:Reset(target.components.move.LogicPos):Sub(moveComponent.LogicPos) FP.V2.Normalize(tempV2) if curSkillData.FaceOffsetAngle ~= FP.Const.Zero then tempV2:Reset(FP.V2.GetOffsetToAngle(curSkillData.FaceOffsetAngle, tempV2)) end moveComponent:SetWantRotateDir(tempV2) --如果处于FaceAim时间段,这里返回false,然后在TryToSetRotateDir的最下面会真正让单位旋转 return changeImmediately else -- 存在动作旋转,则开始转 if not comp_Anim.CurAnimMoveData or (not comp_Anim.CurAnimMoveData.AngleArray)then return changeImmediately end changeImmediately = true -- 以下代码基本照抄movesystem的 temp_passedFrame:Reset(comp_Anim.StatePassTime):Div(LuaConst.TimeSpanMs) temp_lastPassedFrame:Reset(comp_Anim.StateLastPassTime):Div(LuaConst.TimeSpanMs) local frameCount = comp_Anim.CurAnimDataCount local angleList = comp_Anim.CurAnimMoveData.AngleArray local moveDataIndex = 0 local angle = temp_angle:Reset() local lastFrameIndex = math_ceil(tonumberV1(temp_lastPassedFrame)) local currFrameIndex = math_floor(tonumberV1(temp_passedFrame)) if currFrameIndex >= lastFrameIndex then -- 增加前余数据 temp_lastLeftTime:Reset(lastFrameIndex):Sub(temp_lastPassedFrame) -- 需要添加的上次帧剩余 if temp_lastLeftTime > FP_Const_Zero then moveDataIndex = lastFrameIndex tempAngle:Reset(angleList[moveDataIndex]):Mul(temp_lastLeftTime) angle:Add(tempAngle) end -- 增加后余数据 temp_cutExrTime:Reset(temp_passedFrame):Sub(currFrameIndex) -- 需要添加的当前帧多余 if temp_cutExrTime > FP_Const_Zero then moveDataIndex = currFrameIndex + 1 tempAngle:Reset(angleList[moveDataIndex]):Mul(temp_cutExrTime) angle:Add(tempAngle) end -- 增加中间数据 if currFrameIndex > frameCount then currFrameIndex = frameCount end for i = lastFrameIndex + 1 , currFrameIndex do moveDataIndex = i angle:Add(angleList[moveDataIndex]) --print(" N > > > 帧:," ,moveDataIndex , " 当前帧角度:",angle[1] ) end end --如果 currFrameIndex < lastFrameIndex 说明时间缩放小于1 ,且此时 没有跨帧(如果满足这条件,上面的计算都不会有旋转量的) if lastFrameIndex > currFrameIndex then temp_durationTime:Reset(temp_passedFrame):Sub(temp_lastPassedFrame) moveDataIndex = lastFrameIndex tempAngle:Reset(angleList[moveDataIndex]):Mul(temp_durationTime) angle:Add(tempAngle) end -- 旋转不用考虑穿墙,所以可以统计后设置总的角度变化 angle:Mul(comp_Anim.AnimRotatePercent) moveComponent:SetWantRotateDir(FP.V2.GetOffsetToAngle(angle, moveComponent.LogicRotateDir)) end return changeImmediately end --[[ 控制技能释放过程中的朝向 --]] function private.SetDirWhenAttack(entity) local moveComponent = entity.components.move if moveComponent.WantRotateDir ~= FP.Const.Vector2_Zero then return end local curSkillData = entity.components.skillBase.CurSkillData local statePassTime = entity.components.anim.StatePassTime local target = entity.components.target.Target if curSkillData and curSkillData.FaceAim and statePassTime >= curSkillData.FaceAimStart and statePassTime < curSkillData.FaceAimEnd and target then tempV2:Reset(target.components.move.LogicPos):Sub(moveComponent.LogicPos):Normalize() moveComponent:SetWantRotateDir(tempV2) end end --[[ 设置玩家攻击时的朝向 --]] function private.SetPlayerAttackDir(target, skillData, skillBaseComponent, moveComponent,entity) if skillBaseComponent.MSAimPos and (skillData.MSRecordAimType == LuaConst.EMSRecordAimType.LAST_SLAVE_POS or skillData.MSRecordAimType == LuaConst.EMSRecordAimType.POS_TRACE_ENTITY) then private.SetAttackDir(skillBaseComponent.MSAimPos, nil, skillData, skillBaseComponent, moveComponent ,entity) return true else --若有目标,且技能配置的目标选择范围大于0,转向目标 --否则,朝向不变 if target --存在目标 and skillData and skillData.ChooseRadius > FP.Const.Zero then --技能释放距离大于0 private.SetAttackDir(nil,target, skillData, skillBaseComponent, moveComponent ,entity) return true end return false end end --[[ 设置攻击时的朝向 --]] local _tempStartPos = FP.newV2(0,0) function private.SetAttackDir(aimPos,target, skillData, skillBaseComponent, moveComponent ,entity) tempV2:Reset(aimPos or target.components.move.posAsAttackTarget):Sub(moveComponent.posAsAttackTarget):Normalize() --if not entity.components.skillBase:IsAutoNextSkill(skillData.ID) then moveComponent:SetWantRotateDir(tempV2) --end end local temp_speedV1 = FP.newV1(0) function private.TryToSetRotateDir(moveComponent, changeImmediately, entity) if moveComponent.WantRotateDir == FP.Const.Vector2_Zero then return end local driveComp = entity.components.drive if driveComp and driveComp.BeDrived and driveComp:GetDriveData() then if driveComp.IsFirstPerspective then private.SetDriveRotateDir( moveComponent ,entity) return else -- 第三人称驾驶车 ,如果在后30度 ,需要倒车-摇杆的反方向 [X则需要停止转动 ,向后移动X] local cosA = FP.V2.Dot(moveComponent.WantRotateDir,moveComponent.LogicRotateDir) if cosA < LuaConst.BackCarAngleCos then moveComponent.WantRotateDir:Negative() end end end if moveComponent.WantRotateDir == moveComponent.LogicRotateDir then return end if changeImmediately then --立即旋转 private.SetRotateDir(moveComponent, moveComponent.WantRotateDir) return end local timeScale = entity.components.timeScale:GetCurTimeScale() temp_speedV1:Reset(entity.components.attr:GetAttrValue(LuaConst.AttrType.angvel)):Mul(moveComponent.MoveAngleSpeedPercent) --local realAngleSpeed = entity.components.attr:GetAttrValue(LuaConst.AttrType.angvel) * moveComponent.MoveAngleSpeedPercent if temp_speedV1 == FP.Const.Zero then -- 0 代表不能旋转 return end if temp_speedV1 == FP.Const.NegOne then-- -1 代表立刻旋转 private.SetRotateDir(moveComponent, moveComponent.WantRotateDir) return end if temp_speedV1 > FP.Const.Zero and moveComponent.WantRotateDir ~= moveComponent.LogicRotateDir then local angle = FP.V2.Angle(moveComponent.LogicRotateDir, moveComponent.WantRotateDir) temp_speedV1:Mul(timeScale) if angle > temp_speedV1 then angle = temp_speedV1 if not FP.V2.IsRotateClockwise(moveComponent.LogicRotateDir, moveComponent.WantRotateDir) then angle = angle:Negative() end local dir = FP.V2.GetOffsetToAngle(angle, moveComponent.LogicRotateDir) private.SetRotateDir(moveComponent, dir) else private.SetRotateDir(moveComponent, moveComponent.WantRotateDir) end --有技能的话 ,要用摇杆实时控制技能朝向 local skillcomp = entity.components.skillBase if skillcomp and skillcomp.CurSkillData then entity.components.anim:SetCurAnimStartDir() end end end -- 驾驶的是不动车时 function private.SetDriveRotateDir( moveComponent ,entity) local x = moveComponent.WantRotateDir.x _angleV1:Reset(entity.components.attr:GetAttrValue(LuaConst.AttrType.angvel)):Mul(moveComponent.MoveAngleSpeedPercent) if _angleV1 <= FP.Const.Zero then return end _angleV1:Mul(LuaConst.LogicFrameRate) local realAngleSpeed = _angleV1 local halfControlRate = moveComponent.IsHalfDir and 0.6 or 1 --需要计算出特殊的驾驶车辆(有准星的载具)的合成速度 local driveComp = entity.components.drive if driveComp.DriveData.ExtraUIType == LuaConst.DriveExtraUIType.UIAim then realAngleSpeed = private.GetVehicleAngleSpeed(driveComp, _angleV1 , moveComponent.WantRotateDir.z ,moveComponent.WantRotateDir.x) driveComp:SetAngleSpeedRate(halfControlRate) else realAngleSpeed:Mul(FP.Math.Abs(x)) end realAngleSpeed:Mul(LuaConst.TimeSpan) realAngleSpeed:Mul(halfControlRate) if realAngleSpeed > FP.Const.Zero then local angle = (x > FP.Const.Zero) and realAngleSpeed or (realAngleSpeed:Negative()) local dir = FP.V2.GetOffsetToAngle(angle, moveComponent.LogicRotateDir) if FP.V2.Angle(dir, driveComp.OriginForward) < driveComp:GetDriveData().AngleMax then private.SetRotateDir(moveComponent, dir) end end end -- 设置带有准星的载具的特殊速度 function private.GetVehicleAngleSpeed(driveComp, a , sin ,cos ) --todo:优化 local b = driveComp.AngleSpeedX if cos == FP.Const.Zero then -- 只有垂直移动时 driveComp:SetAngleSpeed(b) return FP.Const.Zero end -- k = sin / cos --local x = FP.Math.Sqrt( (a * a * b * b) / ( b*b + a * a * k * k ) ) --local y = k * x _v1TempK:Reset(sin):Div(cos) -- k = sin / cos _v1Temp:Reset(a):Mul(a):Mul(_v1TempK):Mul(_v1TempK) _v1Temp2:Reset(b):Mul(b) _v1Temp:Add(_v1Temp2) _v1Temp2:Reset(a):Mul(a):Mul(b):Mul(b):Div(_v1Temp) --求出的就是x*x local x = FP.Math.Sqrt(_v1Temp2) _v1TempK:Mul(x) -- 求出的就是y driveComp:SetAngleSpeed(FP.Math.Abs(_v1TempK)) return x end --[[ 设置朝向 --]] function private.SetRotateDir(moveComponent, dir) moveComponent.LastLogicRotateDir:Reset(moveComponent.LogicRotateDir) tempV2:Reset(dir):Normalize() moveComponent:SetLogicRotateDir(tempV2) end --[[ 骑马的时候,摇杆的变化,要实时响应 --]] local angleChangeLimit = FP.newV1(0.105) -- 要想变化必须大于6度才行 0.105 = sin(6) local angleChangeLimit_N = FP.newV1(-0.105) -- 要想变化必须大于6度才行 0.105 = sin(6)) local BackAngelCos_Speed = FP.newV1(-0.5) -- 速度在摇杆大于120度时变减速 local BackAngelCos_Angle = FP.Const.Zero -- 角速度在 摇杆向后时角速度变大 local MinSpeed = FP.newV1(0.3) function private.OnHorseUpdate(moveComponent,entity) local attrComp = entity.components.attr local spd_a = attrComp:GetAttrValue(LuaConst.AttrType.ridespdacc) -- 向前方向的加速度(直线加速度) local wantDir = moveComponent.WantMoveDir local curForward = moveComponent.LogicRotateDir local cos = FP.V2.Dot(wantDir,curForward) -- 速度 local sin = FP.V2.Cross(curForward,wantDir) -- 角速度 --if wantDir ~= FP.Const.Vector2_Zero then -- 摇杆有变化 if wantDir ~= FP.Const.Vector2_Zero then if cos > BackAngelCos_Speed then -- 夹角在90度内 ,则加速 ,否则就减速 temp_speedV1:Reset(spd_a):Mul(LuaConst.TimeSpan) moveComponent.RideSpeedRate:Add(temp_speedV1) local rideMaxSpeed = attrComp:GetAttrValue(LuaConst.AttrType.ridegear) -- 当前可发挥的马的最大速度比例 if moveComponent.RideSpeedRate > rideMaxSpeed then moveComponent.RideSpeedRate:Reset(rideMaxSpeed) end else if moveComponent.RideSpeedRate < MinSpeed then temp_speedV1:Reset(spd_a):Mul(LuaConst.TimeSpan) moveComponent.RideSpeedRate:Add(temp_speedV1) else local spd_decelerate = attrComp:GetAttrValue(LuaConst.AttrType.ridespddec) -- 刹车速度 - 减速(直线加速度) temp_speedV1:Reset(spd_decelerate):Mul(LuaConst.TimeSpan) moveComponent.RideSpeedRate:Sub(temp_speedV1) end end else if moveComponent.RideSpeedRate ~= FP.Const.Zero then local spd_decelerate = attrComp:GetAttrValue(LuaConst.AttrType.ridespddec) -- 刹车速度 - 减速(直线加速度) temp_speedV1:Reset(spd_decelerate):Mul(LuaConst.TimeSpan) moveComponent.RideSpeedRate:Sub(temp_speedV1) if moveComponent.RideSpeedRate <= FP.Const.Zero then moveComponent.RideSpeedRate:Reset() end end end --如果自动寻路 ,角速度不变 local comp_AutoFight = entity.components.autoFight if comp_AutoFight.IsAutoFindPath then private.TryToSetRotateDir(moveComponent, false, entity) ExpSystemManager.TryUpdateHorseAnim(entity, moveComponent.RideSpeedRate, moveComponent.HorseExpAngle, wantDir) return end -- 马的摆头(应该向摇杆看齐) 如发现马耳朵微抖,是表现朝向导致的 --moveComponent.HorseExpAngle:Reset(sin) if wantDir ~= FP.Const.Vector2_Zero or FP.Math.Abs(sin) >= angleChangeLimit then -- 摇杆有变化 local angleExpSpeed = attrComp:GetAttrValue(LuaConst.AttrType.rideheadacc) -- 马头的变化速度 temp_speedV1:Reset(angleExpSpeed):Mul(LuaConst.TimeSpan) if moveComponent.HorseExpAngle < sin then moveComponent.HorseExpAngle:Add(temp_speedV1) if moveComponent.HorseExpAngle > sin then moveComponent.HorseExpAngle:Reset(sin) end elseif moveComponent.HorseExpAngle > sin then moveComponent.HorseExpAngle:Sub(temp_speedV1) if moveComponent.HorseExpAngle < sin then moveComponent.HorseExpAngle:Reset(sin) end end else local angleExpSpeed_S = attrComp:GetAttrValue(LuaConst.AttrType.rideheaddec) -- 马头的变化速度 - 回正速度 temp_speedV1:Reset(angleExpSpeed_S):Mul(LuaConst.TimeSpan) if moveComponent.HorseExpAngle < FP.Const.Zero then moveComponent.HorseExpAngle:Add(temp_speedV1) if moveComponent.HorseExpAngle > FP.Const.Zero then moveComponent.HorseExpAngle:Reset() end elseif moveComponent.HorseExpAngle > FP.Const.Zero then moveComponent.HorseExpAngle:Sub(temp_speedV1) if moveComponent.HorseExpAngle < FP.Const.Zero then moveComponent.HorseExpAngle:Reset() end end end -- 逻辑旋转 local spd_aa = attrComp:GetAttrValue(LuaConst.AttrType.rideangacc) -- 角加速度 -- 加速 local needChangeLogicDir = true if sin < angleChangeLimit_N then -- 遥感向左转动 ,角速度应为负 --print("1111 val:" ,moveComponent.HorseExpAngle[1] ,",sin =" ,sin[1]) temp_speedV1:Reset(spd_aa):Mul(LuaConst.TimeSpan) moveComponent.RideAngleSpeedRate:Sub(temp_speedV1) if moveComponent.RideAngleSpeedRate > FP.Const.Zero then moveComponent.RideAngleSpeedRate:Reset() else if moveComponent.RideAngleSpeedRate < FP.Const.NegOne then moveComponent.RideAngleSpeedRate:Reset(-1) end end elseif sin > angleChangeLimit then -- 遥感向右转动 ,角速度为正 --print("2222 val:" ,moveComponent.HorseExpAngle[1] ,",sin =" ,sin[1]) temp_speedV1:Reset(spd_aa):Mul(LuaConst.TimeSpan) moveComponent.RideAngleSpeedRate:Add(temp_speedV1) if moveComponent.RideAngleSpeedRate < FP.Const.Zero then moveComponent.RideAngleSpeedRate:Reset() else if moveComponent.RideAngleSpeedRate > FP.Const.One then moveComponent.RideAngleSpeedRate:Reset(1) end end else -- 遥感回中 --print("3333 val:" ,moveComponent.HorseExpAngle[1] ,",sin =" ,sin[1]) if cos < FP.Const.Zero then -- 向后拉遥感 temp_speedV1:Reset(spd_aa):Mul(LuaConst.TimeSpan) if moveComponent.RideAngleSpeedRate > FP.Const.Zero then moveComponent.RideAngleSpeedRate:Add(temp_speedV1) else moveComponent.RideAngleSpeedRate:Sub(temp_speedV1) end else if moveComponent.RideAngleSpeedRate > FP.Const.Zero then temp_speedV1:Reset(spd_aa):Mul(LuaConst.TimeSpan) moveComponent.RideAngleSpeedRate:Sub(temp_speedV1) if moveComponent.RideAngleSpeedRate < FP.Const.Zero then moveComponent.RideAngleSpeedRate:Reset(0) end elseif moveComponent.RideAngleSpeedRate < FP.Const.Zero then temp_speedV1:Reset(spd_aa):Mul(LuaConst.TimeSpan) moveComponent.RideAngleSpeedRate:Add(temp_speedV1) if moveComponent.RideAngleSpeedRate > FP.Const.Zero then moveComponent.RideAngleSpeedRate:Reset(0) end end needChangeLogicDir = false end end -- 逻辑转向 if needChangeLogicDir then local timeScale = entity.components.timeScale:GetCurTimeScale() local maxAngleSpeed = attrComp:GetAttrValue(LuaConst.AttrType.rideangvel) local rate = 1 if cos < BackAngelCos_Angle then rate = 2 end temp_speedV1:Reset(maxAngleSpeed):Mul(moveComponent.RideAngleSpeedRate):Mul(timeScale):Mul(LuaConst.TimeSpan):Mul(rate) -- 变化角度不能大于wantDir ,否则来回旋转 local curWantAngle = FP.V2.Angle(wantDir, curForward) if FP.Math.Abs(temp_speedV1) >= FP.Math.Abs(curWantAngle) then -- 转过了 private.SetRotateDir(moveComponent, wantDir) else local dir = FP.V2.GetOffsetToAngle(temp_speedV1, moveComponent.LogicRotateDir) private.SetRotateDir(moveComponent, dir) end end --为什么在下面写,因为省CPU,该判断的都判断完了 ,没必要对不骑马的再遍历了 ExpSystemManager.TryUpdateHorseAnim(entity, moveComponent.RideSpeedRate, moveComponent.HorseExpAngle, wantDir) end return RotateSystem