local UISkillJoystick = UIViewClass() local EffectType = LuaConst.EffectType local EventSystem = require('Event/EventSystem') --[[ 数据部分 --]] local MIN_DIR_EFFECT_STRIDE_30FPS = 1 local MIN_DIR_EFFECT_STRIDE = 1 local DIR_EFFECT_ROT_SPEED_RATIO_30FPS = 0.3 local DIR_EFFECT_ROT_SPEED_RATIO = 0.3 local AREA_EFFECT_POS_Y = 0.2 local Vector3_New=Vector3.New local VECTORFAR = Vector3_New(9999, 9999, 0) local MaxRadius = 120 local Vector3Up = Vector3.up local ColorOne = Color.New(1,1,1,1) local ColorRed = Color.New(1,0,0,1) local StartPntX = 0 local StartPntY = 0 local StartPntZ = 0 local CancelAreaRadiusSqr = 7766 --(7744) local Vector3TempDir = Vector3_New(0, 0, 0) --临时变量,无固定含义 local min = math.min local sqrt = math.sqrt local acos = math.acos local cos = math.cos local pi = math.pi local floor = math.floor local sin = math.sin local pow=math.pow local Quaternion=Quaternion local LuaConst=LuaConst local FP=FP local UIUtils=UIUtils local UEType_JOYSTICK_RANGE_STATIC_DIR = LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE_STATIC_RANGE local PLAY_EFFECT_DELAY = 0.15 --初始拖动距离跟MaxRadius的比值小于这个值,不算作有效输入 local torleranceRatio = 0.10 local StartTouchRelativePos = Vector3_New(0, 0, 0) local _tempJoystickDir = FP.newV2(0, 0) local EEffectShapeType = LuaConst.ESkillJoystickShapeType function UISkillJoystick:OnCreated() self.isInTimeline = false self.rawAngle = 361 --世界坐标系下的角度 self.rawX = 0 --世界坐标系下(主要是旋转),目标点相对于主角的位置的x self.rawZ = 0 --世界坐标系下(主要是旋转),目标点相对于主角的位置的z self.rangeEffectLocalPosX = nil --主角模型坐标系下(主要是旋转)的x self.rangeEffectLocalPosZ = nil --主角模型坐标系下(主要是旋转)的z self.thisTrans=self.gameObject.transform self.curEntity = nil --为了方便,保存引用,但是这个用法不规范。 千万不要调用self.curEntity的设置接口,否则会导致不一致 self.target = nil --目标entity,为了方便,保存引用,但是这个用法不规范。 千万不要调用self.target的设置接口,否则会导致不一致 self.hasObstacleTowardsAimPos = false --curEntity到双摇杆焦点位置之间有没有阻挡 self.obstaclePos = nil --如果curEntity到双摇杆焦点位置之间有阻挡,则这个就是最近的阻挡的位置;如果没有阻挡,则为nil self.exceedToleranceDragged = false --玩家的输入跟原点的距离是否超过了生效容限,只有超过一定距离的容限才算是有效输入 self.skillJoyStickData = nil --当技能为非副将技时,这个就是技能的双摇杆数据; 但当技能为副将技时,这个是副将技的通用基础双摇杆数据(副将技有2个双摇杆数据,1个基础的,1个副将技的) self.skillJoyStickControlRange = nil -- 控制技能摇杆的技能摇杆数据 中的摇杆范围值 self.adjutantJoystickData = nil --仅当技能为副将技时才有值,表示策划给这个副将技配的双摇杆,此时 self.skillJoyStickData 依然有值,后者表示的是副将技的通用基础双摇杆数据,两个数据都有用 --以下为变量 self.sprite_Fore_Transform=self.sprite_Fore.transform self.sprite_Back_Transform=self.sprite_Back.transform self.sprite_Direction_Transform=self.sprite_Direction.transform self.cancel_Area_Transform = self.cancel_area.transform self.cancelAreaLocalPosX,self.cancelAreaLocalPosY = self.cancel_root:GetLocalPosition() self.effectStarted = false --是否呼出了双摇杆 self.isEnabled = true --是否可用 end function UISkillJoystick:OnOpened() if BattleDataGetter.IsPVPLevel() then PLAY_EFFECT_DELAY = FP.tonumberV1(DataSheetManager.ConstData:GetDataByID("SKILL_JOYSTICK_DELAY_PVP").FloatValue) else PLAY_EFFECT_DELAY = FP.tonumberV1(DataSheetManager.ConstData:GetDataByID("SKILL_JOYSTICK_DELAY_PVE").FloatValue) end DIR_EFFECT_ROT_SPEED_RATIO_30FPS = FP.tonumberV1(DataSheetManager.ConstData:GetDataByID("DIR_EFFECT_ROT_SPEED_RATIO_30FPS").FloatValue) MIN_DIR_EFFECT_STRIDE_30FPS = FP.tonumberV1(DataSheetManager.ConstData:GetDataByID("MIN_DIR_EFFECT_STRIDE_30FPS").FloatValue) self.Vector3Temp = Vector3_New(0, 0, 0) --临时变量,无固定含义 self:SetIsDragging(false) self:SetIsClick(false) --self.hasStartMove = nil self:RefreshCacheByFPS() self:ControllerSetActive(false); UIUtils.SetImageColor(self.sprite_Back ,ColorOne) UIUtils.SetImageColor(self.sprite_Fore ,ColorOne) self.sprite_Direction_Transform:SetLocalPosition(VECTORFAR.x, VECTORFAR.y, VECTORFAR.z) self.cancel_Area_Transform:SetLocalPosition(VECTORFAR.x, VECTORFAR.y, VECTORFAR.z) --event self:RegisterEvents() end function UISkillJoystick:RefreshCacheByFPS() if SettingAPI.fpsLevel > 0 then MIN_DIR_EFFECT_STRIDE = MIN_DIR_EFFECT_STRIDE_30FPS / 2 DIR_EFFECT_ROT_SPEED_RATIO = DIR_EFFECT_ROT_SPEED_RATIO_30FPS / 2 else MIN_DIR_EFFECT_STRIDE = MIN_DIR_EFFECT_STRIDE_30FPS DIR_EFFECT_ROT_SPEED_RATIO = DIR_EFFECT_ROT_SPEED_RATIO_30FPS end end function UISkillJoystick:RegisterEvents() self:RegistSystemEvent(EventID.TimeLine_Update, self.OnTimeLine) self:RegistSystemEvent(EventID.UIBattle_SkillBtn_Drag,self.OnDrag) self:RegistSystemEvent(EventID.UIBattle_SkillBtn_EndDrag,self.OnEndDrag) self:RegistSystemEvent(EventID.UIBattle_SkillBtn_InitStaticJoy,self.ShowStaticJoySkillRange) self:RegistSystemEvent(EventID.UI_TargetComponent_SetTarget,self.OnSetTarget) self:RegistSystemEvent(EventID.Convey,self.OnConvey) self:RegistSystemEvent(EventID.Player_Dead,self.OnPlayerDead) self:RegistSystemEvent(EventID.Player_Revive,self.OnPlayerRevive) self:RegistSystemEvent(EventID.Player_Revive,self.OnPlayerRevive) self:RegistSystemEvent(EventID.Player_SkillCoolDown,self.OnPlayerSkillCoolDown) self:RegistSystemEvent(EventID.UIBattle_SkillBtn_PointerDown, self.OnPointerDown) self:RegistSystemEvent(EventID.UIBattle_SkillBtn_PointerUp, self.OnPointerUp) self:RegistSystemEvent(EventID.Setting_SwitchLODLevel, self.OnSetQuality) self:RegistSystemEvent(EventID.UIBattle_ChangeAvatar, self.OnChangeAvatar) self:RegistSystemEvent(EventID.UIBattle_SkillJoystickOverrided, self.OnSkillJoystickOverrided) self:RegistSystemEvent(EventID.Player_BanKeyPositions, self.OnBanKeyPositions) self:RegistSystemEvent(EventID.Player_InterruptSkill, self.OnPlayerInterruptSkill) self:RegistSystemEvent(EventID.Player_SkillProgress,self.OnUpdateSkillProgress) -- self:RegistTriggerEvent(self.event_Collider, UIEventTriggerType.Drag) -- self:RegistTriggerEvent(self.event_Collider, UIEventTriggerType.EndDrag) end function UISkillJoystick:OnPlayerDead() self:Stop() end function UISkillJoystick:OnPlayerRevive(entity) if entity:IsPlayerSelf() then self:TryEnableInput() end end function UISkillJoystick:OnConvey(entity) if self.curEntity == entity then self:Interrupt() end end function UISkillJoystick:OnSetTarget(targetComponent) if self.effectStarted then --改变目标时,刷新 if self.curEntity then if targetComponent.entity == self.curEntity then if targetComponent.Target ~= self.target then self.target = targetComponent.Target self:Refresh() end end end end end function UISkillJoystick:OnTimeLine(value) --这里的value指的是是否要激活界面 if value then self.isInTimeline = false self:TryEnableInput() else self.isInTimeline = true self:DisableInput() end end local function GetAngleFromDir(x,z) if x==0 and z==0 then return 0 end local cosValue = z/(sqrt(x^2+z^2)) local angle = (acos(cosValue)*180)/pi if x < 0 then angle = 360 - angle end return angle end function UISkillJoystick:OnLateUpdateFun(deltaTime, timeSinceUpdate) if BattleDataGetter.IsMainPlayerManipulatingEntity(self.curEntity) then if self.curEntity then if self.curEntity.components.buff:CheckHasBuffState(LuaConst.SpecialBuffs.CanSkill) then if self.startEla >= PLAY_EFFECT_DELAY then self:Refresh() else self.startEla = self.startEla + timeSinceUpdate - self.lastTime self.lastTime = timeSinceUpdate if self.startEla >= PLAY_EFFECT_DELAY then self:StartPlayEffect() self:Refresh() end end else self:Interrupt() end end else --如果操作期间切换主将了,就stop。OnChangeCurEntity -> Stop self:OnChangeCurEntity() end end function UISkillJoystick:StartPlayEffect() if self.enableOnStart then self.enableOnStart = false self:TryEnableInput() end self.effectStarted = true if self.curEntity then local expEntity = self.curEntity.ExpEntity expEntity:PlayEffectByType(EffectType.SkillRange) expEntity:SetEffectPosByType(EffectType.SkillRange,0,0,0) local scale = self:GetRangeEffectScale(self.skillJoyStickData) expEntity:SetEffectScaleByType(EffectType.SkillRange,scale,scale,1) if self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR then if self.curDirEffectType then -- expEntity:PlayEffectByType(self.curDirEffectType) -- local scaleX,scaleY,scaleZ = self:GetDirEffectScale(self.skillJoyStickData,self.curDirEffectType) -- expEntity:SetEffectScaleByType(self.curDirEffectType,scaleX,scaleY,scaleZ) self:ShowCurDirEffect(expEntity) expEntity:SetEffectPosByType(self.curDirEffectType, 0, 0, 0) --需要在这里把位置归零,否则缓存池生成的特效会残留上一次的位置信息 end elseif self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE or self.skillJoyStickData.UEType == UEType_JOYSTICK_RANGE_STATIC_DIR then expEntity:PlayEffectByType(self.curAreaEffectType) if self.curAreaEffectType == EEffectShapeType.CIRCLE then local scale = self:GetAreaEffectScale(self.skillJoyStickData) expEntity:SetEffectScaleByType(self.curAreaEffectType,scale,1,scale) elseif self.curAreaEffectType == EEffectShapeType.FANSHAPE then local scaleX,scaleY,scaleZ = self:GetDirEffectScale(self.skillJoyStickData,self.curDirEffectType) expEntity:SetEffectScaleByType(self.curDirEffectType,scaleX,scaleY,scaleZ) else --这是没有实现的情况,随便设置了 local scale = self:GetAreaEffectScale(self.skillJoyStickData) expEntity:SetEffectScaleByType(self.curAreaEffectType,scale,1,scale) end end if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.curEntity.ExpEntity:PlayEffectByType(EffectType.SkillDirArrow) self.curEntity.ExpEntity:PlayEffectByType(EffectType.SkillDirArrowLock) end if self.adjutantJoystickData then if self.curAdjutantDirEffectType then self.curEntity.ExpEntity:PlayEffectByType(self.curAdjutantDirEffectType) elseif self.curAdjutantAreaEffectType then self.curEntity.ExpEntity:PlayEffectByType(self.curAdjutantAreaEffectType) else logging.error(LTAG.ERROR, "HYW : 副将技双摇杆形状配置错误,没有区域特效") end end if self:IsAdjutantJoystickData(self.skillJoyStickData) then self.curEntity.ExpEntity:PlayEffectByType(EffectType.SkillAdjutant) end self:PlayPsEffect(expEntity) end end function UISkillJoystick:SetTarget(target, forceRefresh) local isChanged = false if self.target ~= target or forceRefresh then -- ↓↓↓↓挪到帧同步里面去了,因为策划要求特效要联机同步显示↓↓↓ -- if self.target then -- --清空老目标 -- --self.target.ExpEntity:StopEffectByType(EffectType.BeingSelected) -- if self.skillJoyStickData then -- SystemManager.OnBreakPSEffect(self.target, self.skillJoyStickData.AimEffect) -- end -- end self.target = target --↓↓↓↓挪到帧同步里面去了,因为策划要求特效要联机同步显示↓ -- if target then -- SystemManager.OnReceivePsEffect(target,self.skillJoyStickData.AimEffect) -- end --↑ --仅当UI层预测了target的改变, 或者UI层发现自己的target跟表现层(ExpEntity)的joystickTargetAimEffect不一致时才会设置specialCommand,这样能节省性能。因为ExpEntity调用TargetManager.GetTargetByJoystick是多端同步的。而UI则是单端的 self.specialCommand = LuaConst.SpecialCommandType.JoystickSetTarget isChanged = true end return isChanged end local _tempRelativePos = FP.newV2(0, 0) function UISkillJoystick:SetRawXRawZ(rawX,rawZ) if self.obstaclePos then _tempRelativePos:Reset(self.obstaclePos) _tempRelativePos:Sub(self.curEntity:GetLogicPos()) self.rawX = FP.tonumberV1(_tempRelativePos.x) self.rawZ = FP.tonumberV1(_tempRelativePos.z) else self.rawX = rawX self.rawZ = rawZ end end function UISkillJoystick:GetCurEffectWorldPosition(effectType) local x = 0 local y = 0 local z = 0 if self.curEntity then -- local entityPos = self.curEntity:GetLogicPos() -- x = FP.tonumberV1(entityPos.x) + self.rawX -- z = FP.tonumberV1(entityPos.z) + self.rawZ x,y,z = self.curEntity.ExpEntity:GetWorldPosByType(effectType) end return FP.newV2(x or 0,z or 0) end function UISkillJoystick:IsAdjutantJoystickData(skillJoyStickData) return skillJoyStickData == LuaConst.AdjutantJoystickDataDir or skillJoyStickData == LuaConst.AdjutantJoystickDataRange end function UISkillJoystick:IsBuffSkillJoystickData(skillJoyStickData) return skillJoyStickData.ID and skillJoyStickData.ID < 1000 end --是否是方向型的范围特效 function UISkillJoystick:IsDirAreaEffectType(areaEffectType) return areaEffectType == EffectType.SkillDirFanshape or areaEffectType == EffectType.SkillDirRectWithArrow or areaEffectType == EffectType.SkillDirCircle or areaEffectType == EffectType.SkillDirRect or areaEffectType == EffectType.SkillDirCircleWithArrow end function UISkillJoystick:HasInput() return self.Vector3TempNormalizedX ~= 0 or self.Vector3TempNormalizedZ ~= 0 end --解析输入数据,把输入转换为更好使用的数据, 全部都存在self里,方便脚本内全局使用 --会计算出的数据: -- self.Vector3Temp -- self.Vector3TempNormalizedX、self.Vector3TempNormalizedZ -- self.rawAngle function UISkillJoystick:TransformInputData() --UIUtils.CameraTransformDirectionf返回摄像机变换后的摇杆方向(摇杆的上方映射为摄像机的forward,摇杆左映射为摄像机的left...,下映射为back,右映射为right) local vector3TempX, vector3TempY,vector3TempZ = UIUtils.CameraTransformDirection(Vector3TempDir.x,0,Vector3TempDir.y,nil,nil,nil) self.Vector3Temp:Set(vector3TempX, 0,vector3TempZ) local Vector3TempNormalized = self.Vector3Temp.normalized self.Vector3TempNormalizedX = Vector3TempNormalized.x self.Vector3TempNormalizedZ = Vector3TempNormalized.z if self.exceedToleranceDragged and self:HasInput() then --双摇杆有输入 self.rawAngle = GetAngleFromDir(self.Vector3TempNormalizedX, self.Vector3TempNormalizedZ) else --双摇杆没有输入 if self.effectStarted then --如果呼出了双摇杆,且没有双摇杆输入,策划要求方向保持初始方向 if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then if self.skillAimPos then local dir = self.skillAimPos - self.curEntity:GetLogicPos() --expEntity:SetEffectRotByType(EffectType.SkillDirArrow,angle - entityRotY) self.rawAngle = -FP.tonumberV1(FP.V2.AngleToRight360(dir)) + 90 end else --2022年7月5日 新增闪避双摇杆默认方向规则:当右摇杆呼出但没有输入(按住且不拖动)时,且左摇杆有输入时,以左摇杆的方向为默认闪避方向 if self.skillData and self.skillData.KeyPosition == LuaConst.ESkillKeyPosition.Dodge then self:TrySetRawAngleByVirtualMoveDir() else self.rawAngle = self.startRawAngle end end --↓↓↓↓↓↓↓↓↓↓ 这段代码没有意义,应该是可以删了 -- else -- --如果没有呼出双摇杆 -- if self:HasVirtualMoveDir() then -- if self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR then -- --如果没有呼出双摇杆,且左摇杆有输入,且双摇杆是方向类型的。则以左摇杆的方向为方向 -- self.rawAngle = GetAngleFromDir(FP.tonumberV1(LuaInputManager.FixVirtualMoveDir.x), FP.tonumberV1(LuaInputManager.FixVirtualMoveDir.z)) -- else -- --双摇杆不是方向类型的,则以单位面向为准设置方向 -- self.rawAngle = self:GetDirEffectDefaultRawRot(entityRotY) -- end -- else -- --如果没有呼出双摇杆,且左摇杆没有输入,则以单位面向为准设置方向 -- self.rawAngle = self:GetDirEffectDefaultRawRot(entityRotY) -- end -- ↑↑↑↑↑↑↑↑↑↑↑↑↑↑ end end end function UISkillJoystick:Refresh() if self.curEntity then local expEntity = self.curEntity.ExpEntity if self.curDirEffectType or (self.dragging and self.skillJoyStickData and (self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE or self.skillJoyStickData.UEType == UEType_JOYSTICK_RANGE_STATIC_DIR)) then local entityRotY = expEntity:GetEulerAngleY() self:TransformInputData() local isTargetChanged = false if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.curEntity.ExpEntity:SetEffectScaleByType(EffectType.SkillDirArrow, self.skillJoyStickControlRange * 0.5, 1, 1) if not self:IsAdjutantJoystickData(self.skillJoyStickData) then isTargetChanged = self:RefreshTarget(entityRotY) --else --副将技不需要RefreshTarget,只是用这种视图 end end self.effectDirAngle = self:GetDirEffectAngleByRaw(self.rawAngle,entityRotY,self.curDirEffectType) if self.curDirEffectType then ---------------------------------箭头类型的特效---------------------------------------------- if self.exceedToleranceDragged or not self:HasInput() then --设置箭头特效的旋转 self:RefreshDirEffectRot(expEntity) --expEntity:SetEffectRotByType(self.curDirEffectType,self.effectDirAngle) end local scaleX,scaleY,scaleZ = self:GetDirEffectScale(self.skillJoyStickData,self.curDirEffectType) expEntity:SetEffectScaleByType(self.curDirEffectType,scaleX,scaleY,scaleZ) if self.curDirEffectType == EffectType.SkillDirFanshape then --设置扇形的角度 expEntity:SetEffectProjectorAngleByType(self.curDirEffectType,self:GetFanshapeEffectAngle(self.skillJoyStickData)) elseif self.curDirEffectType == EffectType.SkillDirRect then --expEntity:SetEffectSpriteRendererScaleByType(self.curDirEffectType,self.skillJoyStickData.ShapeParam1,self.skillJoyStickData.ShapeParam2) if scaleX ~= 0 then expEntity:SetEffectProjectorAspectRatio(self.curDirEffectType,self.skillJoyStickData.ShapeParam2 / 2 / scaleX) end if self.skillJoyStickData.ShapeParam3 == 0 then expEntity:SetEffectPosByType(self.curDirEffectType, 0, 0, 0) else if self.expEffectDirAngle then local localPosXWithOffset, localPosYWithOffset, localPosZWithOffset = self:GetEffectPosByAngle(self.expEffectDirAngle - 90, self.skillJoyStickData.ShapeParam3) expEntity:SetEffectPosByType(self.curDirEffectType, -localPosXWithOffset, -2, -localPosZWithOffset) end end elseif self.curDirEffectType == EffectType.SkillDirRectWithArrow then if scaleX ~= 0 then expEntity:SetEffectProjectorAspectRatio(self.curDirEffectType,self.skillJoyStickData.ShapeParam1 / scaleX) end end if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then if self:HasInput() then local localPosX, localPosY, localPosZ, dist = self:GetEffectPosByAngle(self:GetDirEffectAngleByRaw(self.rawAngle, entityRotY, EffectType.SkillDirArrowLock)) self:SetRawXRawZ(self.Vector3TempNormalizedX * dist,self.Vector3TempNormalizedZ * dist) if self.expEffectDirAngle then localPosX, localPosY, localPosZ, dist = self:GetEffectPosByAngle(self:GetSkillDirArrowLockAngleByEffectDirAngle(self.expEffectDirAngle, self.curDirEffectType)) end expEntity:SetEffectPosByType(EffectType.SkillDirArrowLock, localPosX, localPosY, localPosZ) self:RefreshDirArrowRot(expEntity, entityRotY, self.skillJoyStickData.ShouldSnapTarget) if self.skillDirArrowAngle then expEntity:SetEffectRotByType(EffectType.SkillDirArrowLock,self.skillDirArrowAngle) else expEntity:SetEffectRotByType(EffectType.SkillDirArrowLock,-entityRotY) end else self:SetTargetEffectToDefaultPos() -- if self.skillAimPos then -- self:RefreshDirArrowRot(expEntity, entityRotY, self.skillJoyStickData.ShouldSnapTarget) -- else -- expEntity:SetEffectRotByType(EffectType.SkillDirArrow,-90) -- end end end else ------------------------------非箭头类特效(目前就是范围类特效)------------------------------ if self.exceedToleranceDragged or not self:HasInput() then if not self:HasInput() then --没有输入,就设置到默认位置 self:SetAreaEffectToDefaultPos() if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then if self.skillAimPos then self:RefreshDirArrowRot(expEntity, entityRotY, self.skillJoyStickData.ShouldSnapTarget) else expEntity:SetEffectRotByType(EffectType.SkillDirArrow,-90) end end else local dist = 0 self.rangeEffectLocalPosX,self.rangeEffectLocalPosY,self.rangeEffectLocalPosZ,dist = self:GetEffectPosByAngle(self.effectDirAngle) self:SetRawXRawZ(self.Vector3TempNormalizedX * dist,self.Vector3TempNormalizedZ * dist) if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then expEntity:SetEffectPosByType(EffectType.SkillDirArrowLock, self.rangeEffectLocalPosX, self.rangeEffectLocalPosY, self.rangeEffectLocalPosZ) -- local dir -- if self.target then -- dir = self.target:GetLogicPos() - self.curEntity:GetLogicPos() -- else -- dir = FP.newV2(self.rawX,self.rawZ) -- end -- local angle = -FP.tonumberV1(FP.V2.AngleToRight360(dir)) -- expEntity:SetEffectRotByType(EffectType.SkillDirArrow,angle - entityRotY) self:RefreshDirArrowRot(expEntity, entityRotY, self.skillJoyStickData.ShouldSnapTarget) end end local curPos = self.curEntity:GetLogicPos() if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then if self.target and self.skillJoyStickData.ShouldSnapTarget then local targetPos = self.target:GetLogicPos() local posX,posZ = self:TransToLocalPosAndLimitWithinCtrlRange(targetPos) -- self.rawX = FP.tonumberV1(targetPos.x - curPos.x) -- self.rawZ = FP.tonumberV1(targetPos.z - curPos.z) -- self.rawX,self.rawZ = self:LimitPointWithinControlRange(self.rawX,self.rawZ) self:SetRawXRawZ(self:LimitPointWithinControlRange(FP.tonumberV1(targetPos.x - curPos.x),FP.tonumberV1(targetPos.z - curPos.z))) expEntity:SetEffectPosByType(self.curAreaEffectType,posX,0,posZ) self.hasObstacleTowardsAimPos, self.obstaclePos = BattleDataGetter.HasObstacleTowardsPos(curPos,targetPos) else if self:HasInput() then expEntity:SetEffectPosByType( self.curAreaEffectType, self.rangeEffectLocalPosX,self.rangeEffectLocalPosY,self.rangeEffectLocalPosZ) end self.hasObstacleTowardsAimPos, self.obstaclePos = BattleDataGetter.HasObstacleTowardsPos(curPos,self:GetCurEffectWorldPosition(self.curAreaEffectType)) end else expEntity:SetEffectPosByType( self.curAreaEffectType, self.rangeEffectLocalPosX,self.rangeEffectLocalPosY,self.rangeEffectLocalPosZ) self.hasObstacleTowardsAimPos, self.obstaclePos = BattleDataGetter.HasObstacleTowardsPos(curPos,self:GetCurEffectWorldPosition(self.curAreaEffectType)) end self:SetEffectForbidState(self.isInCancelArea or self.hasObstacleTowardsAimPos) if self.curAreaEffectType == EffectType.SkillEffectAreaCircle or self.curAreaEffectType == EffectType.SkillEffectAreaCircle2 then expEntity:SetEffectRotByType(self.curAreaEffectType,-entityRotY) --这句如果移到self:SetAreaEffectToDefaultPos()下面,用左摇杆转向时,AreaEffect可以保持旋转角度,但是在主角转向时,无法保持角度 elseif self.curAreaEffectType == EffectType.SkillDirFanshape then self.effectDirAngle = self:GetDirEffectAngleByRaw(self.rawAngle,entityRotY,self.curAreaEffectType) expEntity:SetEffectRotByType(self.curAreaEffectType,self.effectDirAngle) --设置扇形的角度,角度越大 expEntity:SetEffectProjectorAngleByType(self.curAreaEffectType,self:GetFanshapeEffectAngle(self.skillJoyStickData)) elseif self.curAreaEffectType == EffectType.SkillEffectAreaRect then -- gws local scaleX = self.skillJoyStickData.ShapeParam1 / 2 expEntity:SetEffectScaleByType(self.curAreaEffectType,scaleX,1,1) -- 设置长(即垂直于朝向的方向) if scaleX ~= 0 then expEntity:SetEffectProjectorAspectRatio(self.curAreaEffectType,self.skillJoyStickData.ShapeParam2 / 2 / scaleX) --设置宽(即平行朝向的边) end self.effectDirAngle = self:GetDirEffectAngleByRaw(self.rawAngle,entityRotY,self.curAreaEffectType) expEntity:SetEffectRotByType(self.curAreaEffectType,self.effectDirAngle) -- 设置朝向 else --这里是还没有支持的类型,随便设了 expEntity:SetEffectRotByType(self.curAreaEffectType,-entityRotY) end end end if self.skillJoyStickData.UseSkillOnPress or isTargetChanged then self:SetInput() elseif self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then if self.curEntity and self.target ~= self.curEntity.ExpEntity.joystickTarget then self:SetInput() end end self.oldEntityRotY = entityRotY end if self.adjutantJoystickData then self:RefreshAdjutantJoystick(expEntity) end if self:IsAdjutantJoystickData(self.skillJoyStickData) then if self.expEffectDirAngle then self.rangeEffectLocalPosX, self.rangeEffectLocalPosY, self.rangeEffectLocalPosZ = self:GetEffectPosByAngle(self.expEffectDirAngle, self.skillJoyStickControlRange) if self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR then expEntity:SetEffectPosByType(EffectType.SkillAdjutant, -self.rangeEffectLocalPosX, self.rangeEffectLocalPosY, -self.rangeEffectLocalPosZ) end expEntity:SetEffectRotByType(EffectType.SkillAdjutant, self.expEffectDirAngle + 180) expEntity:SetEffectPosByType(EffectType.SkillDirArrowLock, -self.rangeEffectLocalPosX, self.rangeEffectLocalPosY, -self.rangeEffectLocalPosZ) end end end end function UISkillJoystick:RefreshAdjutantJoystick(expEntity) local entityRotY = expEntity:GetEulerAngleY() local dist if self.expEffectDirAngle then if self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR then self.rangeEffectLocalPosX, self.rangeEffectLocalPosY, self.rangeEffectLocalPosZ, dist = self:GetEffectPosByAngle(self.expEffectDirAngle, self.skillJoyStickControlRange) else self.rangeEffectLocalPosX, self.rangeEffectLocalPosY, self.rangeEffectLocalPosZ, dist = self:GetEffectPosByAngle(self.expEffectDirAngle) self:SetRawXRawZ(self.Vector3TempNormalizedX * dist, self.Vector3TempNormalizedZ * dist) expEntity:SetEffectPosByType(EffectType.SkillAdjutant, -self.rangeEffectLocalPosX, self.rangeEffectLocalPosY, -self.rangeEffectLocalPosZ) end if self.curAdjutantAreaEffectType then if self.curAdjutantAreaEffectType == EffectType.SkillEffectAreaCircle then expEntity:SetEffectPosByType( self.curAdjutantAreaEffectType, -self.rangeEffectLocalPosX, self.rangeEffectLocalPosY, -self.rangeEffectLocalPosZ) else expEntity:SetEffectPosByType( self.curAdjutantAreaEffectType, self.rangeEffectLocalPosX, self.rangeEffectLocalPosY, self.rangeEffectLocalPosZ) end local scale = self:GetAreaEffectScale(self.adjutantJoystickData) expEntity:SetEffectScaleByType(self.curAdjutantAreaEffectType, scale, 1, scale) elseif self.curAdjutantDirEffectType then local scaleX, scaleY, scaleZ = self:GetDirEffectScale(self.adjutantJoystickData, self.curAdjutantDirEffectType) expEntity:SetEffectScaleByType(self.curAdjutantDirEffectType, scaleX, scaleY, scaleZ) local adjutantEffectDirAngle = self.expEffectDirAngle if self.curAdjutantDirEffectType == EffectType.SkillDirCircle then --圆形方向特效需要加偏移,因为原始特效的pivot在圆心。而矩形、扇形的都在图片的一端所以不用偏移 expEntity:SetEffectProjectorOffsetY(self.curAdjutantDirEffectType, -self.adjutantJoystickData.ShapeParam1 - dist) elseif self.curAdjutantDirEffectType == EffectType.SkillDirRect or self.curAdjutantDirEffectType == EffectType.SkillDirRectWithArrow then if self.curAdjutantDirEffectType == EffectType.SkillDirRect then adjutantEffectDirAngle = adjutantEffectDirAngle + 90 elseif self.curAdjutantDirEffectType == EffectType.SkillDirRectWithArrow then adjutantEffectDirAngle = adjutantEffectDirAngle + 180 end --矩形方向特效的旋转需要偏移 if self.adjutantJoystickData.ShapeParam3 == 0 then expEntity:SetEffectPosByType(self.curAdjutantDirEffectType, -self.rangeEffectLocalPosX, -2, -self.rangeEffectLocalPosZ) else local localPosXWithOffset, localPosYWithOffset, localPosZWithOffset = self:GetEffectPosByAngle(self.expEffectDirAngle, self.adjutantJoystickData.ShapeParam3 + self.skillJoyStickControlRange) expEntity:SetEffectPosByType(self.curAdjutantDirEffectType, -localPosXWithOffset, -2, -localPosZWithOffset) end if scaleX ~= 0 then expEntity:SetEffectProjectorAspectRatio(self.curAdjutantDirEffectType, self.adjutantJoystickData.ShapeParam2 / 2 / scaleX) end else logging.error(LTAG.ERROR, "HYW : 不支持的副将双摇杆类型 副将技双摇杆ID :", self.adjutantJoystickData.ID) end expEntity:SetEffectRotByType(self.curAdjutantDirEffectType, adjutantEffectDirAngle) else logging.error(LTAG.ERROR, "HYW : 副将技双摇杆形状配置错误,没有区域特效 @UISkillJoystick:RefreshAdjutantJoystick") end -- else -- logging.error(LTAG.ERROR, "HYW : self.expEffectDirAngle 为nil Error! 请记录操作并上报战斗程序") end end function UISkillJoystick:RefreshTarget(entityRotY) --刷新锁定目标(曹操1技能那种) local isTargetChanged = false local target = BattleDataGetter.GetTargetByJoystick(self.curEntity, self.skillJoyStickData, self:GetCurEffectWorldPosition(EffectType.SkillDirArrowLock), nil, true) isTargetChanged = self:SetTarget(target) if self.skillDirArrowAngle then self.curEntity.ExpEntity:SetEffectRotByType(EffectType.SkillDirArrowLock,self.skillDirArrowAngle) else self.curEntity.ExpEntity:SetEffectRotByType(EffectType.SkillDirArrowLock, -entityRotY) end return isTargetChanged end function UISkillJoystick:RefreshDirArrowRot(expEntity, entityRotY, shouldSnapTarget) local dir if shouldSnapTarget and self.target then dir = self.target:GetLogicPos() - self.curEntity:GetLogicPos() elseif self:HasInput() then dir = FP.newV2(self.rawX,self.rawZ) elseif self.skillAimPos then dir = self.skillAimPos - self.curEntity:GetLogicPos() else dir = FP.newV2(self.rawX,self.rawZ) end if self.expEffectDirAngle then self.skillDirArrowAngle = self:GetSkillDirArrowEffectAngleByEffectDirAngle(self.expEffectDirAngle, self.curDirEffectType) expEntity:SetEffectRotByType(EffectType.SkillDirArrow, self.skillDirArrowAngle) else local angle = -FP.tonumberV1(FP.V2.AngleToRight360(dir)) self.skillDirArrowAngle = angle - entityRotY expEntity:SetEffectRotByType(EffectType.SkillDirArrow, self.skillDirArrowAngle) end end --获取非轴点特效的位置 function UISkillJoystick:GetEffectPosByAngle(angle, distOffset) local worldDist if self:IsAdjutantJoystickData(self.skillJoyStickData) and self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR then -- JOYSTICK_DIR 这种 UEType 的副将技双摇杆要求固定在外围圈上 worldDist = self.areaEffectMaxDist else local touchDist = sqrt(self.Vector3Temp.x*self.Vector3Temp.x+self.Vector3Temp.z*self.Vector3Temp.z) local ratio = min(touchDist / MaxRadius,1) worldDist = ratio * self.areaEffectMaxDist end if distOffset then worldDist = worldDist + distOffset end local rad = angle / 180 * pi local z = cos(rad) local x = sin(rad) return x * worldDist,AREA_EFFECT_POS_Y,z * worldDist,worldDist end --返回箭头类(指向型)特效的角度。(不同特效类型在相同的rawAngle和entityRotY下,角度会不一样) function UISkillJoystick:GetDirEffectAngleByRaw(rawAngle, entityRotY, curDirEffectType) rawAngle = rawAngle - entityRotY if curDirEffectType == nil then -- do nothing elseif curDirEffectType == EffectType.SkillDirArrowLock then -- do nothing elseif curDirEffectType == EffectType.SkillDirRectWithArrow then -- do nothing elseif curDirEffectType == EffectType.SkillDirRect or curDirEffectType == EffectType.SkillEffectAreaRect then rawAngle = rawAngle + 270 else --现在的方向特效除了矩形的,x轴都有90的旋转,所以这里rotY要加180 rawAngle = rawAngle + 180 end if rawAngle >= 360 then rawAngle = rawAngle - 360 end return rawAngle end function UISkillJoystick:GetSkillDirArrowEffectAngleByEffectDirAngle(effectDirAngle, dirEffectType) if dirEffectType == nil then -- do nothing elseif dirEffectType == EffectType.SkillDirArrowLock then -- do nothing elseif dirEffectType == EffectType.SkillDirRectWithArrow then -- do nothing elseif dirEffectType == EffectType.SkillDirRect then -- do nothing else effectDirAngle = effectDirAngle + 90 end if effectDirAngle >= 360 then effectDirAngle = effectDirAngle - 360 end return effectDirAngle end function UISkillJoystick:GetSkillDirArrowLockAngleByEffectDirAngle(effectDirAngle, dirEffectType) return self:GetSkillDirArrowEffectAngleByEffectDirAngle(self.expEffectDirAngle, self.curDirEffectType) + 90 end function UISkillJoystick:GetFanshapeEffectAngle(skillJoyStickData) return skillJoyStickData.ShapeParam2 * 2 end function UISkillJoystick:GetDirEffectScale(skillJoyStickData,dirEffectType) if skillJoyStickData then if dirEffectType == EffectType.SkillDirRectWithArrow then --return skillJoyStickData.ShapeParam1,skillJoyStickData.ShapeParam2,1 return skillJoyStickData.ShapeParam2, 1, 1 elseif dirEffectType == EffectType.SkillDirRect then return skillJoyStickData.ShapeParam1 / 2,1,1 elseif dirEffectType == EffectType.SkillDirCircle then return skillJoyStickData.ShapeParam1,1,skillJoyStickData.ShapeParam1 elseif dirEffectType == EffectType.SkillDirCircleWithArrow then return skillJoyStickData.ShapeParam1,1,skillJoyStickData.ShapeParam1 else local scale = self:GetRangeEffectScale(skillJoyStickData) return scale , 1 , scale end else logging.log(LTAG.HYW,"HYW : self.skillJoyStickData nil Error!") return 1,1,1 end end function UISkillJoystick:OnClosed() self:Stop() end function UISkillJoystick:OnChangeCurEntity() self:Interrupt() end function UISkillJoystick:OnBanKeyPositions(keyList) local curSkillData = self.skillData self:Interrupt() if curSkillData then local curKeyPosition = curSkillData.KeyPosition for i,key in ipairs(keyList) do if key == curKeyPosition then LuaInputManager.SetKeyPosition(0, false) break end end end end function UISkillJoystick:OnPlayerInterruptSkill() self:Interrupt() end function UISkillJoystick:Interrupt() self.rawAngle = 361 self.rawX = 0 self.rawZ = 0 self:Stop() LuaInputManager.SetSkillJoystickInterruptFlag(true) end -- isFromStop : 是否是抬手时的调用 function UISkillJoystick:SetInput(isFromStop) --new↓ 把rawAngle信息存在rawX和rawZ里 if self.skillJoyStickData and self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR then if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then if self.rawX == 0 and self.rawZ == 0 and self.target == nil and self.effectStarted then if self.rawAngle < 361 then local rad = self.rawAngle / 180 * pi -- self.rawX = sin(rad) --这里就是sin,不是cos -- self.rawZ = cos(rad) --这里就是cos,不是sin if self:IsAdjutantJoystickData(self.skillJoyStickData) then self:SetRawXRawZ(sin(rad) * self.skillJoyStickControlRange, cos(rad) * self.skillJoyStickControlRange) else self:SetRawXRawZ(sin(rad),cos(rad)) end end end else if self.rawAngle < 361 then local rad = self.rawAngle / 180 * pi -- self.rawX = sin(rad) --这里就是sin,不是cos -- self.rawZ = cos(rad) --这里就是cos,不是sin self:SetRawXRawZ(sin(rad),cos(rad)) end end end --new↑ if isFromStop then --当抬手时,优先以isInCancelArea为准,优先设置specialCommand为LuaConst.SpecialCommandType.JoystickCancel if self.isInCancelArea then self.specialCommand = LuaConst.SpecialCommandType.JoystickCancel elseif self.specialCommand == LuaConst.SpecialCommandType.JoystickSetTarget then if self.skillData then self.specialCommand = LuaConst.SpecialCommandType.JoystickSetTargetAndUseSkill LuaInputManager.SetKeyPosition(self.skillData.KeyPosition) end end if self.isClick and self.skillJoyStickData.IsClickClearJoyStick then -- 当点击时,需要清理双摇杆的数据 self:SetRawXRawZ(0,0) end else --当非抬手时,优先LuaConst.SpecialCommandType.JoystickSetTarget if self.specialCommand == LuaConst.SpecialCommandType.JoystickSetTarget then if self.skillData then LuaInputManager.SetKeyPosition(self.skillData.KeyPosition) end elseif self.isInCancelArea then self.specialCommand = LuaConst.SpecialCommandType.JoystickCancel end end LuaInputManager.SetSkillJoystickInfo(self.rawX, self.rawZ, self.specialCommand) end function UISkillJoystick:TryBreakKeyPosition() if self.isInCancelArea and self.skillJoyStickData.UseSkillOnPress then LuaInputManager.SetKeyPosition(0, false) end end function UISkillJoystick:Stop() self:SetInput(true) self:TryBreakKeyPosition() self:SetIsClick(false) self:SetIsDragging(false) self.effectStarted = false self.exceedToleranceDragged = false self.canCancel = true self.startEla = 0 self:StopRepeatFunc(self.OnLateUpdateFun) self.sprite_Direction_Transform:SetLocalPosition(VECTORFAR.x, VECTORFAR.y, VECTORFAR.z) self.cancel_Area_Transform:SetLocalPosition(VECTORFAR.x, VECTORFAR.y, VECTORFAR.z) self.sprite_Fore_Transform:SetLocalPosition(VECTORFAR.x, VECTORFAR.y, VECTORFAR.z) self.sprite_Back_Transform:SetLocalPosition(VECTORFAR.x, VECTORFAR.y, VECTORFAR.z) self.hasObstacleTowardsAimPos = false --这个得先调 self:SetIsInCancelArea(false, true) self:ControllerSetActive(false) -- old↓ 没提方法 -- if self.curEntity then -- self.curEntity.ExpEntity:StopEffectByType(EffectType.SkillRange) -- if self.curDirEffectType then -- self.curEntity.ExpEntity:StopEffectByType(self.curDirEffectType) -- end -- if self.curAdjutantAreaEffectType then -- self.curEntity.ExpEntity:StopEffectByType(self.curAdjutantAreaEffectType) -- end -- if self.curAdjutantDirEffectType then -- self.curEntity.ExpEntity:StopEffectByType(self.curAdjutantDirEffectType) -- end -- if self.skillJoyStickData then -- if self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE then -- self.curEntity.ExpEntity:StopEffectByType(self.curAreaEffectType) -- end -- if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then -- self.curEntity.ExpEntity:StopEffectByType(EffectType.SkillDirArrow) -- self.curEntity.ExpEntity:StopEffectByType(EffectType.SkillDirArrowLock) -- end -- end -- if self:IsAdjutantJoystickData(self.skillJoyStickData) then -- self.curEntity.ExpEntity:StopEffectByType(EffectType.SkillAdjutant) -- end -- end -- self.curDirEffectType = nil -- old↑ self:StopEffects() --new 提了个方法 self:SetTarget(nil) --这个要先调 self.skillJoyStickData = nil self.skillJoyStickControlRange = nil -- 控制技能摇杆的技能摇杆数据 中的摇杆范围值 self.skillData = nil self.buffSkillData = nil self.rangeEffectLocalPosX = nil self.rangeEffectLocalPosY = nil self.rangeEffectLocalPosZ = nil self.effectDirAngle = nil self.rawAngle = 361 self.rawX = 0 self.rawZ = 0 self.curEntity = nil self.specialCommand = nil self.skillAimPos = nil self.oldEntityRotY = nil self.obstaclePos = nil self.expEffectDirAngle = nil self.adjutantJoystickData = nil self.adjutantSkillData = nil self.curAdjutantAreaEffectType = nil self.curAdjutantDirEffectType = nil Vector3TempDir:Set(0,0,0) end function UISkillJoystick:StopEffects() if self.curEntity then self.curEntity.ExpEntity:StopEffectByType(EffectType.SkillRange) if self.curDirEffectType then self.curEntity.ExpEntity:StopEffectByType(self.curDirEffectType) end if self.curAdjutantAreaEffectType then self.curEntity.ExpEntity:StopEffectByType(self.curAdjutantAreaEffectType) end if self.curAdjutantDirEffectType then self.curEntity.ExpEntity:StopEffectByType(self.curAdjutantDirEffectType) end if self.skillJoyStickData then if self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE or self.skillJoyStickData.UEType == UEType_JOYSTICK_RANGE_STATIC_DIR then self.curEntity.ExpEntity:StopEffectByType(self.curAreaEffectType) end if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.curEntity.ExpEntity:StopEffectByType(EffectType.SkillDirArrow) self.curEntity.ExpEntity:StopEffectByType(EffectType.SkillDirArrowLock) end end if self:IsAdjutantJoystickData(self.skillJoyStickData) then self.curEntity.ExpEntity:StopEffectByType(EffectType.SkillAdjutant) end self:StopPsEffect(self.curEntity.ExpEntity) end self.curDirEffectType = nil end function UISkillJoystick:GetPositionBasedOnWidth(screenPosition) local vector3TempX,vector3TempY,vector3TempZ = UIUtils.GetPositionBasedOnWidth(self.thisTrans,screenPosition,nil,nil,nil) self.Vector3Temp:Set(vector3TempX, vector3TempY, vector3TempZ) return vector3TempX,vector3TempY,vector3TempZ end function UISkillJoystick:OnChangeSkillWhenDragging(oldSkillJoyStickData, newSkillJoyStickData) if self.curEntity then local expEntity = self.curEntity.ExpEntity if self:IsAdjutantJoystickData(oldSkillJoyStickData) then expEntity:StopEffectByType(EffectType.SkillAdjutant) expEntity:StopEffectByType(EffectType.SkillDirArrow) expEntity:StopEffectByType(EffectType.SkillDirArrowLock) end if self.curDirEffectType then expEntity:StopEffectByType(self.curDirEffectType) end if self.curAreaEffectType then expEntity:StopEffectByType(self.curAreaEffectType) end end end function UISkillJoystick:Dragging(touchPos) if self.dragging then self:SetIsClick(false) local curPosX,curPosY,curPosZ = self:GetPositionBasedOnWidth(touchPos) Vector3TempDir:Set(curPosX - StartPntX, curPosY - StartPntY, curPosZ - StartPntZ) local dist = (Vector3TempDir - StartTouchRelativePos).magnitude self.Vector3Temp = Vector3TempDir.normalized * Mathf.Min(Vector3TempDir.magnitude, MaxRadius) self.sprite_Fore_Transform:SetLocalPosition(self.Vector3Temp.x, self.Vector3Temp.y, self.Vector3Temp.z) local vector3TempX, vector3TempY,vector3TempZ = UIUtils.CameraTransformDirection(Vector3TempDir.x,0,Vector3TempDir.y,nil,nil,nil) self.Vector3Temp:Set(vector3TempX, vector3TempY,vector3TempZ) local Vector3TempNormalized = self.Vector3Temp.normalized self.Vector3TempNormalizedX = Vector3TempNormalized.x self.Vector3TempNormalizedZ = Vector3TempNormalized.z self:UpdateDirectionSprite(Vector3TempDir) local xDist = (StartPntX + self.Vector3Temp.x - self.cancelAreaLocalPosX) local yDist = (StartPntY + self.Vector3Temp.y - self.cancelAreaLocalPosY) local isInCancelArea = xDist * xDist + yDist * yDist < CancelAreaRadiusSqr if self.canCancel then self:SetIsInCancelArea(isInCancelArea) end if self.exceedToleranceDragged or dist > torleranceRatio * MaxRadius then self.exceedToleranceDragged = true end end end function UISkillJoystick:SetIsInCancelArea(isInCancelArea, forceRefresh) if self.isInCancelArea ~= isInCancelArea or forceRefresh then self.isInCancelArea = isInCancelArea self:SetEffectForbidState(self.isInCancelArea or self.hasObstacleTowardsAimPos) LuaInputManager.SetIsInSkillCancelArea(self.isInCancelArea) end if self.isInCancelArea and self.skillJoyStickData and self.skillJoyStickData.InterruptOnCancelArea then if self.skillJoyStickData.UseSkillOnPress then LuaInputManager.SetKeyPosition(0, false) LuaInputManager.ReleaseAttackKey() end self:Interrupt() self:DisableInput() --这里如果不disable,双摇杆又会被呼出 self.enableOnStart = true --在下次开始时 end end local FORE_IMG_FORBID = ConstAssetPathConfig.FORE_IMG_FORBID local FORE_IMG_NORMAL = ConstAssetPathConfig.FORE_IMG_NORMAL local BACK_IMG_FORBID = ConstAssetPathConfig.BACK_IMG_FORBID local BACK_IMG_NORMAL = ConstAssetPathConfig.BACK_IMG_NORMAL local CANCEL_IMG_FORBID = ConstAssetPathConfig.CANCEL_IMG_FORBID local CANCEL_IMG_NORMAL = ConstAssetPathConfig.CANCEL_IMG_NORMAL function UISkillJoystick:SetEffectForbidState(isForbid) local color if isForbid then color=ColorRed else color=ColorOne end -- UIUtils.SetImageColor(self.sprite_Back , color) -- UIUtils.SetImageColor(self.sprite_Fore ,color) -- UIUtils.SetImageColor(self.cancel_area , color) UIUtils.SetImageByAssetBundle(self.sprite_Fore, isForbid and FORE_IMG_FORBID or FORE_IMG_NORMAL) UIUtils.SetImageByAssetBundle(self.sprite_Back, isForbid and BACK_IMG_FORBID or BACK_IMG_NORMAL) UIUtils.SetImageByAssetBundle(self.cancel_area, isForbid and CANCEL_IMG_FORBID or CANCEL_IMG_NORMAL) UIUtils.SetImageColor(self.sprite_Direction , color) if self.curEntity then if self.curDirEffectType then self.curEntity.ExpEntity:SetEffectProjectorInCancel(self.curDirEffectType,isForbid) end if self.skillJoyStickData then if self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE or self.skillJoyStickData.UEType == UEType_JOYSTICK_RANGE_STATIC_DIR then self.curEntity.ExpEntity:SetEffectProjectorInCancel(self.curAreaEffectType,isForbid) end if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.curEntity.ExpEntity:SetEffectProjectorInCancel(EffectType.SkillRange,isForbid) self.curEntity.ExpEntity:SetEffectProjectorInCancel(EffectType.SkillDirArrow,isForbid) self.curEntity.ExpEntity:SetEffectProjectorInCancel(EffectType.SkillDirArrowLock,isForbid) end end self.curEntity.ExpEntity:SetEffectProjectorInCancel(EffectType.SkillRange,isForbid) if self.curAdjutantAreaEffectType then self.curEntity.ExpEntity:SetEffectProjectorInCancel(self.curAdjutantAreaEffectType, isForbid) elseif self.curAdjutantDirEffectType then self.curEntity.ExpEntity:SetEffectProjectorInCancel(self.curAdjutantDirEffectType, isForbid) end end end function UISkillJoystick:UpdateDirectionSprite(dir) self.Vector3Temp:Set(dir.x,dir.y,0) local q = Quaternion.FromToRotation(Vector3Up, self.Vector3Temp):ToEulerAngles() self.sprite_Direction_Transform:SetLocalEulerAngles(q.x,q.y,q.z) self.sprite_Direction_Transform:SetLocalPosition(0,0,0) end function UISkillJoystick:ControllerSetActive(isActive) if (not isActive) then self.sprite_Back_Transform:SetLocalPosition(VECTORFAR.x, VECTORFAR.y, VECTORFAR.z) end end function UISkillJoystick:OnDrag(comp, eventData, skillJoyStickData, skillData) repeat if not self.isEnabled then break end if not skillJoyStickData then break end if self.dragging and self.skillJoyStickData ~= skillJoyStickData and (skillData == nil or self.skillData == nil or skillData.BelongTo ~= self.skillData.BelongTo) then self:OnEndDrag(comp, eventData, self.skillJoyStickData) -- 当正在拖拽时,又拖拽了其他技能,则停止之前的拖拽 else if self.dragging and self.skillData then self:Dragging(eventData.position) return end end self.curEntity = BattleDataGetter.GetMainPlayerManipulatingEntity() if not self.curEntity then break end local oldSkillJoyStickData = self.skillJoyStickData self.skillJoyStickData = skillJoyStickData self.skillJoyStickControlRange = self.curEntity.components.skillBase:GetSkillJoyStickOverrideData(skillJoyStickData.ID, "ControlRange") or skillJoyStickData.ControlRange -- 控制技能摇杆的技能摇杆数据 中的摇杆范围值 if self:IsBuffSkillJoystickData(self.skillJoyStickData) then if skillData then local updateData = self.curEntity.components.buffSkill:GetBuffSkillUpdateByID(skillData.ID) if updateData == nil or updateData.CD > 0 then break end else break end self.buffSkillData = skillData elseif self:IsAdjutantJoystickData(self.skillJoyStickData) then if self.curEntity.components.adjutant.AdjutantCD > 0 then break end else self.skillData = skillData if not BattleDataGetter.CanMainPlayerUseSkill(skillData) then break end end local eventDataPos = eventData.position if (not self.dragging) then --[[if self:HasVirtualMoveDir() then -- 目的:如果首次拖拽时,一定要设置下默认位置self.rawAngle = self.startRawAngle LuaInputManager.SetVirtualMoveDir(0,0) --todo:这样修黄忠bug会导致新的bug,暂时回退 end--]] self:OnStartDrag(eventDataPos,comp,skillJoyStickData) else if oldSkillJoyStickData ~= self.skillJoyStickData then self:OnChangeSkillWhenDragging(oldSkillJoyStickData, self.skillJoyStickData) end self:Dragging(eventDataPos) end until true end function UISkillJoystick:SetIsDragging(value, draggingComp) self.dragging = value EventSystem.Dispatch(EventID.UIBattle_SkillJoystickSetDragging, self.dragging, draggingComp) end function UISkillJoystick:SetIsClick(value) self.isClick = value end function UISkillJoystick:HasVirtualMoveDir() return LuaInputManager.FixVirtualMoveDir.x ~= FP.Const.Zero or LuaInputManager.FixVirtualMoveDir.z ~= FP.Const.Zero end local _tempVirtualMoveDirAngle = FP.newV1(0) function UISkillJoystick:OnStartDrag(eventDataPos,comp,skillJoyStickData) self.lastEventDataPos = eventDataPos self.lastComp = comp if self.enableOnStart then self.enableOnStart = false self:TryEnableInput() end LuaInputManager.SetSkillJoystickInterruptFlag(false) self:SetIsDragging(true, comp) self:SetIsClick(true) self:StartRepeatFunc(self.OnLateUpdateFun, 0, -1, false) self.startEla = 0 self.lastTime = 0 self.skillJoyStickData = skillJoyStickData self.skillJoyStickControlRange = self.curEntity.components.skillBase:GetSkillJoyStickOverrideData(skillJoyStickData.ID, "ControlRange") or skillJoyStickData.ControlRange -- 控制技能摇杆的技能摇杆数据 中的摇杆范围值 if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then if not self:IsAdjutantJoystickData(self.skillJoyStickData) then self:SetTarget(nil,true) --else -- do nothing , 副将技不需要RefreshTarget end end if self:IsAdjutantJoystickData(self.skillJoyStickData) then self.adjutantSkillData = LogicUpdateManager._curEntity.components.adjutant.AdjutantEntity.components.skillBase:GetSkillDataByKeyPosition(LuaConst.ESkillKeyPosition.AdjutantSkillMain) self.adjutantJoystickData = LogicUpdateManager._curEntity.components.adjutant.AdjutantEntity.components.skillBase:GetSkillJoystickData(self.adjutantSkillData.ID) if self.adjutantJoystickData then --↓ 如果是副将技,且UEType是 无轴点类型(LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE) , 那么把副将技的双摇杆的ControlRange设置给基础双摇杆 if self.skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE then --当为副将技时,self.skillJoyStickData 的值是配置在LuaConst里的虚拟数据,可以进行编辑 self.skillJoyStickControlRange = self.adjutantJoystickData.ControlRange end --↑ local shapeType = self.adjutantJoystickData.ShapeType self.curAdjutantDirEffectType = nil self.curAdjutantAreaEffectType = nil if self.adjutantJoystickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR then if shapeType == EEffectShapeType.CIRCLE then self.curAdjutantDirEffectType = EffectType.SkillDirCircle elseif shapeType == EEffectShapeType.RECT_WITH_ARROW then self.curAdjutantDirEffectType = EffectType.SkillDirRectWithArrow elseif shapeType == EEffectShapeType.FANSHAPE then self.curAdjutantDirEffectType = EffectType.SkillDirFanshape elseif shapeType == EEffectShapeType.RECT then self.curAdjutantDirEffectType = EffectType.SkillDirRect elseif shapeType == EEffectShapeType.CIRCLE_WITH_ARROW then self.curAdjutantDirEffectType = EffectType.SkillDirCircleWithArrow else logging.error(LTAG.ERROR, "HYW : adjutantJoystickData.ShapeType bad value! : ", adjutantJoystickData.ShapeType) end elseif self.adjutantJoystickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE then --目前支持2种生效区域特效,扇形和圆形 if shapeType == EEffectShapeType.FANSHAPE then self.curAdjutantAreaEffectType = EffectType.SkillDirFanshape elseif shapeType == EEffectShapeType.CIRCLE then if self.adjutantJoystickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.curAdjutantAreaEffectType = EffectType.SkillEffectAreaCircleSimple else self.curAdjutantAreaEffectType = EffectType.SkillEffectAreaCircle end else logging.error(LTAG.ERROR, "HYW : 目前没有实现ShapeType类型为", shapeType, "的区域特效,self.adjutantJoystickData.ID : ", self.adjutantJoystickData.ID) --默认是圆形 self.curAdjutantAreaEffectType = EffectType.SkillEffectAreaCircle end end --else --正常情况,因为策划说有的副将技不配 --logging.error(LTAG.ERROR, "HYW : 没有配置副将技双摇杆!! 技能ID : ", self.adjutantSkillData.ID) end end self.rangeSqr = self.skillJoyStickControlRange * self.skillJoyStickControlRange if skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE or skillJoyStickData.UEType == UEType_JOYSTICK_RANGE_STATIC_DIR then self.areaEffectMaxDist = self.skillJoyStickControlRange --由触点偏移控制的特效能够远离中心的最大距离 elseif skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR then if skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.areaEffectMaxDist = self.skillJoyStickControlRange else self.areaEffectMaxDist = 0 end end self.areaEffectNoTargetPosX = 0 self.areaEffectNoTargetPosY = 0 self.areaEffectNoTargetPosZ = 0 if self.skillJoyStickData.DefaultCallPos and #self.skillJoyStickData.DefaultCallPos > 2 then self.areaEffectNoTargetPosX = self.skillJoyStickData.DefaultCallPos[1] self.areaEffectNoTargetPosY = self.skillJoyStickData.DefaultCallPos[2] self.areaEffectNoTargetPosZ = self.skillJoyStickData.DefaultCallPos[3] end self.sprite_Back_Transform:SetPosition(comp.transform:GetPosition()) StartPntX,StartPntY,StartPntZ = self.sprite_Back_Transform:GetLocalPosition() local curPosX,curPosY,curPosZ = self:GetPositionBasedOnWidth(eventDataPos) StartTouchRelativePos:Set(curPosX - StartPntX, curPosY - StartPntY, curPosZ - StartPntZ) self.canCancel = true if self.skillData then if self.skillData.AutoNextID == LuaConst.InterruptSkillAutoNextID then self.canCancel = false elseif self.skillData.AutoNextID > 0 then local nextSkillData = self.curEntity:GetSkillData(self.skillData.AutoNextID) if nextSkillData then self.canCancel = nextSkillData.AutoNextID ~= LuaConst.InterruptSkillAutoNextID end end end if self.canCancel then self.sprite_Fore_Transform:SetLocalPosition(0,0,0) self.cancel_Area_Transform:SetLocalPosition(0,0,0) end if self.curEntity then if self.skillData then self.skillAimPos = BattleDataGetter.PredictSkillAimPos(self.curEntity, self.skillData.ID) end local expEntity = self.curEntity.ExpEntity local entityRotY = expEntity:GetEulerAngleY() self.startRawAngle = self:GetDirEffectDefaultRawRot(entityRotY) if not self:HasVirtualMoveDir() then self.rawAngle = self.startRawAngle else if self.skillData and self.skillData.KeyPosition == LuaConst.ESkillKeyPosition.Dodge then --2022年7月5日 新增闪避双摇杆默认方向规则:当右摇杆呼出但没有输入(按住且不拖动)时,且左摇杆有输入时,以左摇杆的方向为默认闪避方向 self:TrySetRawAngleByVirtualMoveDir() end end if skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_DIR or self:IsAdjutantJoystickData(skillJoyStickData) then --如果是副将技,则定死一定需要显示dirEffect local dirEffectType = nil if skillJoyStickData.ShapeType == EEffectShapeType.CIRCLE then dirEffectType = EffectType.SkillDirCircle elseif skillJoyStickData.ShapeType == EEffectShapeType.RECT_WITH_ARROW then dirEffectType = EffectType.SkillDirRectWithArrow elseif skillJoyStickData.ShapeType == EEffectShapeType.FANSHAPE then dirEffectType = EffectType.SkillDirFanshape elseif skillJoyStickData.ShapeType == EEffectShapeType.RECT then dirEffectType = EffectType.SkillDirRect elseif skillJoyStickData.ShapeType == EEffectShapeType.CIRCLE_WITH_ARROW then --钟表盘+时针 dirEffectType = EffectType.SkillDirCircleWithArrow else logging.error(LTAG.ERROR, "HYW : skillJoyStickData.ShapeType bad value! : ", skillJoyStickData.ShapeType) end if dirEffectType then self.curDirEffectType = dirEffectType if PLAY_EFFECT_DELAY <= 0 then self:ShowCurDirEffect(expEntity) end end elseif skillJoyStickData.UEType == LuaConst.ESkillJoystickUEType.JOYSTICK_RANGE or skillJoyStickData.UEType == UEType_JOYSTICK_RANGE_STATIC_DIR then --目前支持2种生效区域特效,扇形和圆形 if skillJoyStickData.ShapeType == EEffectShapeType.FANSHAPE then self.curAreaEffectType = EffectType.SkillDirFanshape elseif skillJoyStickData.ShapeType == EEffectShapeType.CIRCLE then if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.curAreaEffectType = EffectType.SkillEffectAreaCircleSimple else if skillJoyStickData.UEType == UEType_JOYSTICK_RANGE_STATIC_DIR then self.curAreaEffectType = EffectType.SkillEffectAreaCircle2 else self.curAreaEffectType = EffectType.SkillEffectAreaCircle end end elseif skillJoyStickData.ShapeType == EEffectShapeType.RECT then self.curAreaEffectType = EffectType.SkillEffectAreaRect else logging.error(LTAG.ERROR, "HYW : 目前没有实现ShapeType类型为", skillJoyStickData.ShapeType, "的区域特效,SkillJoyStickData.ID : ", skillJoyStickData.ID) --默认是圆形 self.curAreaEffectType = EffectType.SkillEffectAreaCircle end if PLAY_EFFECT_DELAY <= 0 then expEntity:PlayEffectByType(self.curAreaEffectType) end local scale = self:GetAreaEffectScale(skillJoyStickData) expEntity:SetEffectScaleByType(self.curAreaEffectType,scale,1,scale) self:SetAreaEffectToDefaultPos() end if PLAY_EFFECT_DELAY <= 0 then self:StartPlayEffect() end end end function UISkillJoystick:TrySetRawAngleByVirtualMoveDir() if self:HasVirtualMoveDir() then FP.V2.Angle360(LuaInputManager.FixVirtualMoveDir, FP.newV2(0,1), _tempVirtualMoveDirAngle) self.rawAngle = FP.tonumberV1(_tempVirtualMoveDirAngle) else self.rawAngle = self:GetDirEffectDefaultRawRot(self.curEntity.ExpEntity:GetEulerAngleY()) end end function UISkillJoystick:TransToLocalPosAndLimitWithinCtrlRange(worldPos) local posX,posZ = self:TransformToLocalPositionOfEntity(worldPos) return self:LimitPointWithinControlRange(posX,posZ) end function UISkillJoystick:ShowCurDirEffect(expEntity) expEntity:PlayEffectByType(self.curDirEffectType) local scaleX,scaleY,scaleZ = self:GetDirEffectScale(self.skillJoyStickData,self.curDirEffectType) expEntity:SetEffectScaleByType(self.curDirEffectType,scaleX,scaleY,scaleZ) if self.curDirEffectType == EffectType.SkillDirCircle then --圆形方向特效需要加偏移,因为原始特效的pivot在圆心。而矩形、扇形的都在图片的一端所以不用偏移 expEntity:SetEffectProjectorOffsetY(self.curDirEffectType, -self.skillJoyStickData.ShapeParam1) end end local ENTITY_NOT_ROTATE_TOLERANCE = 0 function UISkillJoystick:RefreshDirEffectRot(expEntity) if self.effectDirAngle >= 360 then self.effectDirAngle = self.effectDirAngle - 360 elseif self.effectDirAngle <= 0 then self.effectDirAngle = self.effectDirAngle + 360 end local expEffectAngle if self.exceedToleranceDragged and self.oldEffectDirAngle and (self.oldEntityRotY == nil or math.abs(expEntity:GetEulerAngleY() - self.oldEntityRotY) < ENTITY_NOT_ROTATE_TOLERANCE) then expEffectAngle = self.oldEffectDirAngle local delta = self.effectDirAngle - self.oldEffectDirAngle local sign if delta > 0 and delta < 180 or delta < -180 then sign = 1 else sign = -1 end if delta < -180 then delta = delta + 360 elseif delta > 180 then delta = 360 - delta end local absDelta = math.abs(delta) local stride = absDelta * DIR_EFFECT_ROT_SPEED_RATIO if absDelta > MIN_DIR_EFFECT_STRIDE and stride <= MIN_DIR_EFFECT_STRIDE then stride = MIN_DIR_EFFECT_STRIDE end stride = stride * sign expEffectAngle = self.oldEffectDirAngle + stride else expEffectAngle = self.effectDirAngle end if expEffectAngle >= 360 then expEffectAngle = expEffectAngle - 360 elseif expEffectAngle <= 0 then expEffectAngle = expEffectAngle + 360 end self.expEffectDirAngle = expEffectAngle expEntity:SetEffectRotByType(self.curDirEffectType, expEffectAngle) self.oldEffectDirAngle = expEffectAngle end local temp_noJoyV2 = FP.newV2(0,0) local temp_offsetV2 = FP.newV2(0,0) function UISkillJoystick:SetAreaEffectToDefaultPos() if self.curEntity then if self.skillAimPos then temp_noJoyV2:Reset(self.skillAimPos) -- 最终的世界坐标 -- gws: 如果有默认偏移,则需要计算上偏移位置(朝向:人和skillAimPos的连线) 2023-5-22 if #self.skillJoyStickData.AimPosOffset > 2 then temp_noJoyV2:Sub(self.curEntity:GetLogicPos()) temp_offsetV2:Reset(self.skillJoyStickData.AimPosOffset[1],self.skillJoyStickData.AimPosOffset[3]) if self.skillJoyStickData.AimPosOffset[3] > 0 or temp_offsetV2:SqrMagnitude() < temp_noJoyV2:SqrMagnitude() then -- 若太近则不生效 temp_noJoyV2:Normalize() FP.V2.GetOffsetToForward(temp_noJoyV2, temp_offsetV2 ,temp_noJoyV2) temp_noJoyV2:Add(self.skillAimPos) -- 最终的世界坐标 end end local posX,posZ = self:TransToLocalPosAndLimitWithinCtrlRange(temp_noJoyV2) self.curEntity.ExpEntity:SetEffectPosByType(self.curAreaEffectType,posX,0,posZ) if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.curEntity.ExpEntity:SetEffectPosByType(EffectType.SkillDirArrowLock,posX,0,posZ) end local rawX, rawZ = FP.tonumberV2(temp_noJoyV2:Sub(self.curEntity:GetLogicPos())) self:SetRawXRawZ(self:LimitPointWithinControlRange(rawX, rawZ)) else if self.obstaclePos and self.rawX == 0 and self.rawZ == 0 then self:SetRawXRawZ()--啥也不用传,因为self.obstaclePos有值 end if self.areaEffectNoTargetPosX then self.curEntity.ExpEntity:SetEffectPosByType(self.curAreaEffectType,self.areaEffectNoTargetPosX,AREA_EFFECT_POS_Y,self.areaEffectNoTargetPosZ) if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.curEntity.ExpEntity:SetEffectPosByType(EffectType.SkillDirArrowLock,self.areaEffectNoTargetPosX,AREA_EFFECT_POS_Y,self.areaEffectNoTargetPosZ) end -- gws: 2023-5-16 黄忠墙 AimPosType 是 MissileWithOffset的要去掉特性:默认的位置用call表 。而是用DefaultCallPos if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.MissileWithOffset or self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.MissileEndPosWithDefaultPos then -- 2032-8-8 典韦的1技能的默认位置 local curPos = self.curEntity:GetLogicPos() local fx, fz = FP.tonumberV2(self.curEntity:GetLogicRotateDir()) local ox, oz = self.areaEffectNoTargetPosX,self.areaEffectNoTargetPosZ local rx = fz * ox + fx * oz local rz = -fx * ox + fz * oz temp_noJoyV2:Reset(rx,rz):Add(curPos) self.hasObstacleTowardsAimPos, self.obstaclePos = BattleDataGetter.HasObstacleTowardsPos(curPos,temp_noJoyV2) self:SetRawXRawZ(rx, rz) end end end end end function UISkillJoystick:SetTargetEffectToDefaultPos() if self.curEntity then if self.skillJoyStickData.AimPosType == LuaConst.ESkillJoystickAimPosType.Target then self.skillDirArrowAngle = self.expEffectDirAngle and self:GetSkillDirArrowEffectAngleByEffectDirAngle(self.expEffectDirAngle, self.curDirEffectType) or -90 self.curEntity.ExpEntity:SetEffectRotByType(EffectType.SkillDirArrow, self.skillDirArrowAngle) if self.skillAimPos then local posX,posZ = self:TransToLocalPosAndLimitWithinCtrlRange(self.skillAimPos) self.curEntity.ExpEntity:SetEffectPosByType(EffectType.SkillDirArrowLock, posX, 0, posZ) self:SetRawXRawZ(self:LimitPointWithinControlRange(FP.tonumberV1(self.skillAimPos.x - self.curEntity:GetLogicPos().x),FP.tonumberV1(self.skillAimPos.z - self.curEntity:GetLogicPos().z))) else if self.obstaclePos and self.rawX == 0 and self.rawZ == 0 then self:SetRawXRawZ()--啥也不用传,因为self.obstaclePos有值 end if self.areaEffectNoTargetPosX then self.curEntity.ExpEntity:SetEffectPosByType(LuaConst.EffectType.SkillDirArrowLock, self.areaEffectNoTargetPosX,AREA_EFFECT_POS_Y, self.areaEffectNoTargetPosZ) end end end end end --把坐标限制在ControlRange里面 function UISkillJoystick:LimitPointWithinControlRange(posX,posZ) local xSqr = posX * posX local zSqr = posZ * posZ if xSqr + zSqr > 0 then if xSqr + zSqr > self.rangeSqr then local tempPosX = pow( xSqr / (xSqr + zSqr),0.5) * self.skillJoyStickControlRange posX = posX > 0 and tempPosX or -tempPosX local tempPosZ = pow( zSqr / (xSqr + zSqr),0.5) * self.skillJoyStickControlRange posZ = posZ > 0 and tempPosZ or -tempPosZ end end return posX,posZ end --返回pos相对于主角的localPosition function UISkillJoystick:TransformToLocalPositionOfEntity(pos) if self.curEntity and pos then local targetX = pos.x local targetZ = pos.z local entityPosX,entityPosY,entityPosZ = self.curEntity.ExpEntity:GetPosition() local xDelta = FP.tonumberV1(targetX - entityPosX) local zDelta = FP.tonumberV1(targetZ - entityPosZ) local angle = GetAngleFromDir(xDelta,zDelta) local entityRotY = self.curEntity.ExpEntity:GetEulerAngleY() angle = self:GetDirEffectAngleByRaw(angle, entityRotY, EffectType.SkillDirArrowLock) local dist = sqrt(xDelta* xDelta+ zDelta * zDelta) local rad = angle / 180 * pi local poxX = sin(rad) * dist local posZ = cos(rad) * dist return poxX,posZ else return 0,0 end end --返回的是世界坐标系下的旋转 function UISkillJoystick:GetDirEffectDefaultRawRot(entityRotY) local defaultRawAngle = entityRotY local selfLogicPos = self.curEntity:GetLogicPos() if self.skillAimPos then local dir = self.skillAimPos - selfLogicPos local dirX = FP.tonumberV1(dir.x) local dirZ = FP.tonumberV1(dir.z) defaultRawAngle = GetAngleFromDir(dirX,dirZ) else defaultRawAngle = entityRotY end return defaultRawAngle end function UISkillJoystick:GetRangeEffectScale(skillJoyStickData) if skillJoyStickData.IsShowControlRange then return self.skillJoyStickControlRange -- * 1.03 --美术资源稍微有点小,扩大1.03倍刚刚好 else return 0 --为了省事,隐藏外圈直接用scale返回0实现 end end function UISkillJoystick:GetAreaEffectScale(skillJoyStickData) return skillJoyStickData.ShapeParam1 -- * 1.06 --美术资源稍微有点小,扩大1.03倍刚刚好 end function UISkillJoystick:OnEndDrag(comp, eventData, skillJoyStickData) if self.skillJoyStickData and self.skillJoyStickData ~= skillJoyStickData then if skillJoyStickData == nil or skillJoyStickData.ID == nil then -- 副将技能的双摇杆这个ID值为空 return -- 按下的摇杆和松开的摇杆不是同一个技能的摇杆,不处理 end local isFind, skillData = DataSheetManager.SkillData:TryGetDataByID(self.skillJoyStickData.ID) if isFind and (skillData.BelongTo ~= skillJoyStickData.ID) then -- 防止连续技能点击时第二段的摇杆不消失 return -- 按下的摇杆和松开的摇杆不是同一个技能的摇杆,不处理 end end self:Stop() end function UISkillJoystick:OnPointerDown(comp, eventData, skillData) self:TryEnableInput() end function UISkillJoystick:OnPointerUp(comp, eventData, skillJoyStickData, skillData) if skillJoyStickData then --local belongToSkillJoystickData = DataSheetManager.SkillJoyStickData:GetDataByID(skillData.BelongTo) if skillData then local belongToSkillJoystickData = BattleDataGetter.GetMainEntitySkillJoystickData(skillData.BelongTo) if belongToSkillJoystickData and belongToSkillJoystickData.InterruptOnCancelArea then self:TryEnableInput() end end end end function UISkillJoystick:DisableInput() self.isEnabled = false self:Stop() end function UISkillJoystick:TryEnableInput() if not self.isInTimeline then self.isEnabled = true end end function UISkillJoystick:OnPlayerSkillCoolDown(keyPos, cdTime) if self.skillData then local belongToSkill = self.curEntity:GetSkillData(self.skillData.BelongTo) if self.skillData.KeyPosition == keyPos or (belongToSkill and belongToSkill.KeyPosition == keyPos) then if cdTime and FP.tonumberV1(cdTime) > 0 then self:Interrupt() end end end end function UISkillJoystick:OnSetQuality() self:RefreshCacheByFPS() end function UISkillJoystick:OnChangeAvatar() self:Stop() end function UISkillJoystick:OnUpdateSkillProgress(keyPos, cdTime, skillData) if self.dragging and skillData then if self.skillData and skillData.ID ~= self.skillData.ID and skillData.BelongTo == self.skillData.BelongTo then self.oldStartEla = self.startEla self:StopEffects() self:OnStartDrag(self.lastEventDataPos, self.lastComp, BattleDataGetter.GetMainEntitySkillJoystickData(skillData.ID)) self:StartPlayEffect() self.startEla = self.oldStartEla end end end function UISkillJoystick:OnSkillJoystickOverrided(replacedID, replacedByID) if self.dragging then self.oldStartEla = self.startEla self:StopEffects() self:OnStartDrag(self.lastEventDataPos, self.lastComp, BattleDataGetter.GetMainEntitySkillJoystickData(replacedByID)) self:StartPlayEffect() self.startEla = self.oldStartEla end end function UISkillJoystick:PlayPsEffect(expEntity) if not string.isNilOrEmpty(self.skillJoyStickData.PsEffectPath) then expEntity:PlayPsEffect(self.skillJoyStickData.PsEffectPath) end end function UISkillJoystick:StopPsEffect(expEntity) if not string.isNilOrEmpty(self.skillJoyStickData.PsEffectPath) then expEntity:BreakPsEffect(self.skillJoyStickData.PsEffectPath) end end function UISkillJoystick:ShowStaticJoySkillRange(skillJoyStickData, skillData) local curEntity = BattleDataGetter.GetMainPlayerManipulatingEntity() if skillJoyStickData == nil then if curEntity then UIManager.CloseView(Const_UI_Lua.UIEnum.UIStaticSkillJoystick) end else if curEntity then UIManager.OpenView(Const_UI_Lua.UIEnum.UIStaticSkillJoystick, {skillJoyStickData = skillJoyStickData, skillData = skillData}) end -- 修复显示常驻技能双摇杆时,左侧方向摇杆各种状态不清空,导致摇杆错误。方向摇杆改为控制技能时需要清理移动相关的缓存。 -- 以下两行代码的作用就是关闭再打开该界面,目的是重置状态,直接调用界面的CloseView和OpenView可以打到一样的效果。 -- 这么写完全是投机取巧,利用了event事件的在执行时新注册新EventCallback也会被执行到的特性。修复这bug的其他方案测试过了,不理想 EventSystem.Dispatch(EventID.UI_HomeMain_ChangeDontMergeView, Const_UI_Lua.UIEnum.UIVirtualController, false) EventSystem.Dispatch(EventID.UI_HomeMain_ChangeDontMergeView, Const_UI_Lua.UIEnum.UIVirtualController, true) end end return UISkillJoystick