using UnityEngine; using vnxbqy.UI; using System.Collections.Generic; using UnityEngine.EventSystems; public class STM_BaseAttack : SMB_Base { protected float m_Duration; protected float m_ProcessFrame; protected int m_ProcessIndex; protected float m_MoveDuration; protected float m_MoveEscape; protected AnimationCurve m_MoveCurve; protected Vector3 m_ClickedEndPosition; public int cacheSkillID; protected Skill m_CacheSkill; protected float m_AnimatorSpeed = 1; protected float m_EffectAnimatorSpeed = 1; private bool m_HasHandleDelayLogic = false; protected bool hasHandleDelayLogic { get { return m_HasHandleDelayLogic; } set { m_HasHandleDelayLogic = value; } } protected bool m_NeedMove; protected Vector3 m_EndPosition; #if UNITY_EDITOR protected Vector3 m_EnterPos; #endif protected List m_NpcPosList = new List(); protected List m_CastedEffect = new List(); protected List m_DelayHurtBlood = new List(); private float m_AnimationPauseStartTime; private float m_AnimationPauseLastTime; private bool m_StartPauseAnimator; private bool m_IsLastHitFrame = false; protected SFXController m_StartHeadEffect; private float m_GhostCreateDuration; private float m_GhostLastTime; private float m_GhostCreateInterval; private Color m_GhostColor; private float m_Intensity; private float m_GhostCreateCalculateTime; protected override void OnEnter(GActor owner, Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { base.OnEnter(owner, animator, stateInfo, layerIndex); m_CastedEffect.Clear(); m_Duration = 0; m_ProcessFrame = 0; m_ProcessIndex = 0; m_MoveDuration = 0; m_GhostCreateDuration = 0; m_GhostCreateInterval = 0; m_GhostCreateCalculateTime = 0; m_Intensity = 0; m_DelayHurtBlood.Clear(); m_ClickedEndPosition = Vector3.zero; hasHandleDelayLogic = false; m_EndPosition = owner.Pos; #if UNITY_EDITOR m_EnterPos = m_EndPosition; #endif GActorFight _fight = owner as GActorFight; if (_fight.SkillMgr.CurCastSkill != null) { cacheSkillID = _fight.SkillMgr.CurCastSkill.id; m_CacheSkill = _fight.SkillMgr.Get(cacheSkillID); } if (m_CacheSkill == null) { return; } if (owner.ActorType == GameObjType.gotPlayer) { GActorPlayerBase _player = owner as GActorPlayerBase; if (m_CacheSkill.skillInfo.soFile != null) { if (m_CacheSkill.skillInfo.soFile.ghostEffectID != 0) { InitGhostShadow(m_CacheSkill.skillInfo.soFile.ghostEffectID); } if (m_CacheSkill.skillInfo.soFile.effectOnTargetHead > 0) { if (m_CacheSkill.mainTarget != null) { m_StartHeadEffect = SFXPlayUtility.Instance.PlayEffectAsync(m_CacheSkill.skillInfo.soFile.effectOnTargetHead, m_CacheSkill.mainTarget); } } if (m_CacheSkill.skillInfo.config.AtkType != (int)E_AtkType.FastMove) { m_EffectAnimatorSpeed = m_AnimatorSpeed = animator.speed = owner.ActorInfo.atkSpeed; } } if (m_CacheSkill.skillInfo.soFile != null) { if (m_CacheSkill.skillInfo.soFile.hideWeapon) { _player.ShowOrHideWeapon(false); } } _player.SwitchHeadNameBindNode(true); if (owner.ServerInstID == PlayerDatas.Instance.PlayerId) { GA_Hero.CallOnStateEnter(animator.GetCurrentAnimatorClipInfo(0).Length); if (owner.State == E_ActorState.AutoRun) { owner.StopPathFind(); // 同步停止协议 C0502_tagCPlayerStopMove _0502 = new C0502_tagCPlayerStopMove(); _0502.Dir = 0; _0502.PosX = (ushort)(owner.Pos.x * 2); _0502.PosY = (ushort)(owner.Pos.z * 2); _0502.WorldTick = 0; if(!ArenaManager.IsArenaClientNotMirrorFight) { if (!CrossServerUtility.IsCrossServer()) { GameNetSystem.Instance.SendInfo(_0502); } else { GameNetSystem.Instance.SendToCrossServer(_0502); } } } if (owner.MP_Name1) { HeadUpSkillName.Popup(cacheSkillID, owner.MP_Name1.position, CameraController.Instance.CameraObject); } else { HeadUpSkillName.Popup(cacheSkillID, owner.Root.position, CameraController.Instance.CameraObject); } } if (_player is GA_Player) { (_player as GA_Player).StopMoveToPosition(); } #if UNITY_EDITOR string _content = string.Format("STM_BaseAttack => {0} 的技能: {1} 进入技能状态逻辑", owner.ServerInstID, cacheSkillID); RuntimeLogUtility.AddLog_Green(_content); #endif } if (owner is GA_Player || owner is GA_Hero) { if (owner.State != E_ActorState.Roll) { owner.State = E_ActorState.CastSkill; } } } protected override void OnUpdate(GActor owner, Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { base.OnUpdate(owner, animator, stateInfo, layerIndex); GActorFight _fight = owner as GActorFight; if (GA_Hero.s_MapSwitching) { return; } if (m_CacheSkill == null) { return; } if (m_GhostCreateDuration > 0) { m_GhostCreateDuration -= Time.deltaTime; m_GhostCreateCalculateTime += Time.deltaTime; if (m_GhostCreateCalculateTime > m_GhostCreateInterval) { XRayShadow.Request(_fight.GetSMRenderer(), m_GhostColor, m_Intensity, m_GhostLastTime); m_GhostCreateCalculateTime = 0; } } m_Duration += Time.deltaTime; m_ProcessFrame = (int)(m_Duration * 30 * animator.speed); ProcessFrameEvent(owner, animator, stateInfo); HandleInputMove(); if (m_StartPauseAnimator) { if (Time.time - m_AnimationPauseStartTime > m_AnimationPauseLastTime) { owner.SetAnimatorSpeed(1); m_StartPauseAnimator = false; ChangeCastedEffectAnimatorSpeed(1); } else { owner.SetAnimatorSpeed(0); ChangeCastedEffectAnimatorSpeed(0); return; } } } protected override void OnExit(GActor owner, Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { base.OnExit(owner, animator, stateInfo, layerIndex); OnFininshedFightMove(); GActorFight _fight = owner as GActorFight; if (_fight == null) { #if UNITY_EDITOR Debug.LogErrorFormat("owner: {0} 类型问题: {1}", owner.ServerInstID, owner.GetType()); #endif return; } _fight.SkillMgr.DoingPrepareSkill = false; if (owner.ActorType == GameObjType.gotPlayer) { if (owner is GA_Hero) { GA_Hero.CallOnStateEnd(); } GActorPlayerBase _player = owner as GActorPlayerBase; if (_player != null) { _player.SwitchHeadNameBindNode(false); _player.ShowOrHideWeapon(true); } animator.speed = 1; #if UNITY_EDITOR string _content = string.Format("STM_BaseAttack => {0} 的技能: {1} 退出技能状态逻辑", owner.ServerInstID, cacheSkillID); RuntimeLogUtility.AddLog_Green(_content); #endif } if (_fight.OnSkillCompelete != null && m_CacheSkill != null) { _fight.OnSkillCompelete(m_CacheSkill.id); } ProcessDelayLogic(); if (owner is GA_Player || owner is GA_Hero) { if (owner.State == E_ActorState.CastSkill || (m_CacheSkill != null && m_CacheSkill.id == 190 && owner.State == E_ActorState.Roll)) { owner.State = E_ActorState.Idle; } } if (m_CacheSkill != null) { m_CacheSkill.cacheBuffList.Clear(); m_CacheSkill.SkillCompelete = true; m_CacheSkill = null; } if (m_StartHeadEffect != null) { SFXPlayUtility.Instance.Release(m_StartHeadEffect); m_StartHeadEffect = null; } for (int i = 0; i < m_CastedEffect.Count; ++i) { if (m_CastedEffect[i] == null) { continue; } m_CastedEffect[i].SetAnimatorSpeed(1); if (m_CastedEffect[i].config != null && m_CastedEffect[i].config.stopImmediate == 1) { SFXPlayUtility.Instance.Release(m_CastedEffect[i]); } } m_CastedEffect.Clear(); #if UNITY_EDITOR if (RuntimeLogUtility.s_LogMoveDistance) { float _moveDistance = MathUtility.DistanceSqrtXZ(m_EnterPos, owner.Pos); _moveDistance = Mathf.Sqrt(_moveDistance); if (owner.ServerInstID == PlayerDatas.Instance.PlayerId) { Debug.LogFormat("此次技能位移了: {0} 米", _moveDistance); } } #endif } private void ChangeCastedEffectAnimatorSpeed(float speed) { m_EffectAnimatorSpeed = speed; for (int i = 0; i < m_CastedEffect.Count; ++i) { m_CastedEffect[i].SetAnimatorSpeed(speed); m_CastedEffect[i].SetPaticleSystemSpeed(speed); } } protected void ProcessDelayLogic() { if (hasHandleDelayLogic) { return; } GActorFight _target = null; ulong _hurtTotalValue = 0; float _totalPercent = 0; // 延迟飘血 if (m_DelayHurtBlood.Count > 0) { if (m_CacheSkill == null) { return; } for (int i = 0; i < m_DelayHurtBlood.Count; ++i) { _totalPercent += m_DelayHurtBlood[i]; } m_DelayHurtBlood.Clear(); } AttackHandler.HurtObjs _hurtObj; if (m_CacheSkill != null) { for (int i = 0; i < m_CacheSkill.hurtServerList.Count; ++i) { _hurtObj = m_CacheSkill.hurtServerList[i]; _target = GAMgr.Instance.GetByCID(_hurtObj.clientInstID) as GActorFight; if (_target == null) { continue; } _hurtTotalValue = (ulong)(_hurtObj.HurtHP * _totalPercent); if (_hurtTotalValue != 0) { GAStaticDefine.PopHp(owner, _target, _hurtObj.AttackType, _hurtTotalValue); } if (_target.ActorInfo.serverDie) { _target.Die(owner.ServerInstID, 0, _hurtObj.AttackType); } // 主角血量扣除的补充 if (_target.ServerInstID == PlayerDatas.Instance.PlayerId) { PlayerDatas.Instance.FightRefreshPlayerHp(_target.ActorInfo.SyncServerHp); } else { _target.ActorInfo.ResetHp((long)_target.ActorInfo.SyncServerHp); } } // 延迟死亡 for (int i = 0; i < m_CacheSkill.hurtClientList.Count; ++i) { _target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtClientList[i].clientInstID) as GActorFight; if (_target == null) { continue; } if (_target.ActorInfo.serverDie) { _target.Die(owner.ServerInstID, 0, m_CacheSkill.hurtClientList[i].AttackType); } } for (int i = 0; i < m_CacheSkill.hurtClntFightNpcList.Count; ++i) { _target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtClntFightNpcList[i].clientInstID) as GActorFight; if (_target == null) { continue; } if (_target.ActorInfo.serverDie) { _target.Die(owner.ServerInstID, 0, m_CacheSkill.hurtClntFightNpcList[i].AttackType); } } } hasHandleDelayLogic = true; } private void ProcessFrameEvent(GActor owner, Animator animator, AnimatorStateInfo stateInfo) { if (m_CacheSkill.skillInfo.soFile == null) { return; } for (; m_ProcessIndex < m_CacheSkill.skillInfo.soFile.animationEventList.Count; ++m_ProcessIndex) { if (m_ProcessFrame < m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].index) { break; } switch (m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].frameEventType) { case E_FrameEventType.OnSkillEvent: OnSkillEvent(m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam); break; case E_FrameEventType.OnPlayEffect: int _effectConfigID = m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam; OnPlayerEffect(_effectConfigID); break; case E_FrameEventType.OnSkillComplete: OnSkillComplete(); break; case E_FrameEventType.OnAnimationPause: OnAnimationPause(m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam); break; case E_FrameEventType.OnTimePause: if (owner is GA_Hero) { SnxxzGame.Instance.StartTimePause(m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam * Constants.F_GAMMA); } break; case E_FrameEventType.OnSkillPrepare: break; case E_FrameEventType.OnCreateGhost: int _id = m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam; InitGhostShadow(_id); break; case E_FrameEventType.OnPlayAudio: bool _needPlay = true; if (owner.ActorType == GameObjType.gotPlayer) { if (owner.ServerInstID != PlayerDatas.Instance.PlayerId) { if (m_CacheSkill.skillInfo.config.SkillOfSeries == 1) { _needPlay = false; } } } if (_needPlay) { int _audioID = m_CacheSkill.skillInfo.soFile.animationEventList[m_ProcessIndex].intParam; GActorFight _fighter = owner as GActorFight; if (_fighter != null) { _fighter.PlaySkillAudio(_audioID); } } break; } } } private void OnAnimationPause(int param) { m_AnimationPauseLastTime = param * Constants.F_GAMMA; m_AnimationPauseStartTime = Time.time; m_StartPauseAnimator = true; // Debug.Log("------------------------ 开始顿帧"); } private void OnSkillEvent(int param) { //SnxxzGame.Instance.AddLog("log", string.Format("技能: {0} 已经开始处理帧: {1}的事件", m_CacheSkill.id, m_ProcessFrame)); //Debug.Log(string.Format("技能: {0} 已经开始处理帧: {1} 的事件", m_CacheSkill.id, m_ProcessFrame)); SoSkill.E_AttackType _type; int _id; int _param; SoConfigBase _config = null; m_IsLastHitFrame = true; // 判断是否是最后一个伤害帧 for (int i = m_ProcessIndex + 1; i < m_CacheSkill.skillInfo.soFile.animationEventList.Count; ++i) { if (m_CacheSkill.skillInfo.soFile.animationEventList[i].frameEventType != E_FrameEventType.OnSkillEvent) { continue; } _config = null; _param = m_CacheSkill.skillInfo.soFile.animationEventList[i].intParam; _type = SoSkill.GetAttactType(_param); _id = SoSkill.GetFrameEventId(_param); if (_type == SoSkill.E_AttackType.Sweep) { _config = ScriptableObjectLoader.LoadSoSweepHit(_id); } else if (_type == SoSkill.E_AttackType.FlyObject) { _config = ScriptableObjectLoader.LoadSoFlyObject(_id); } if (_config != null && _config.floodPercent != 0) { m_IsLastHitFrame = false; break; } } _type = SoSkill.GetAttactType(param); _id = SoSkill.GetFrameEventId(param); // Debug.LogFormat("类型: {0}, 数值: {1}", _type, _id); switch (_type) { case SoSkill.E_AttackType.Sweep: SweepProcess(_id); break; case SoSkill.E_AttackType.FlyObject: FlyObjectProcess(_id); break; } } protected virtual void SweepProcess(int id) { SoSweepHit _sweepHit = ScriptableObjectLoader.LoadSoSweepHit(id); if (_sweepHit == null) { Debug.LogErrorFormat("技能{0}的Sweep配置出错, 找不到给定的Id: {1}", cacheSkillID, id); return; } if (!PreFightMission.Instance.IsFinished()) { if (m_CacheSkill.id == 10026) { PreFightMission.Instance.Create8SmallBoss(owner.Pos); } } if (PlayerDatas.Instance.PlayerId == owner.ServerInstID) { if (_sweepHit.cameraSfxId != 0) { SoCameraSFX _cameraSFX = ScriptableObjectLoader.LoadSoCameraSFX(_sweepHit.cameraSfxId); if (_cameraSFX != null) { CameraController.Instance.DoShake(_cameraSFX.direction, _cameraSFX.power, _cameraSFX.interval, _cameraSFX.duration); CameraController.Instance.StartZoom(_cameraSFX.zoomScale, _cameraSFX.zoomTime); } } } if ((owner is GA_NpcFightBoss || owner is GA_NpcClientFightBoss) && m_CacheSkill.id == 10016) { GActorNpcFight _boss = owner as GActorNpcFight; if (_boss.NpcConfig.Sounds != null && _boss.NpcConfig.Sounds.Length > 0) { (owner as GActorNpcFight).PlaySkillAudio(_boss.NpcConfig.Sounds[0]); } } GActorFight _fight = owner as GActorFight; DesiceFightMove(_fight, _sweepHit); GActorFight _target = null; ulong _hurtTotalValue = 0; ulong _realHurtValue = 0; m_NpcPosList.Clear(); float _floodPercent = _sweepHit.floodPercent * Constants.F_DELTA; if (m_CacheSkill.hurtServerList.Count > 0) { for (int i = 0; i < m_CacheSkill.hurtServerList.Count; ++i) { _target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtServerList[i].clientInstID) as GActorFight; if (_target == null) { continue; } if (_target is GA_Pet) { Debug.LogFormat("收到服务端封包, 释放者: {0}, 使用技能: {1} 的伤害宠物类型....SID: {2}, CID: {3}", owner.ServerInstID, m_CacheSkill.id, m_CacheSkill.hurtServerList[i].ObjID, m_CacheSkill.hurtServerList[i].clientInstID); } _hurtTotalValue = (ulong)(m_CacheSkill.hurtServerList[i].HurtHP * _floodPercent); _realHurtValue = (ulong)(m_CacheSkill.hurtServerList[i].RealHurtHP * _floodPercent); // Debug.LogFormat("掉血量: {0}, 真实掉血量: {1}, 此帧掉血: {2}, 此帧真实掉血: {3}", // m_CacheSkill.hurtServerList[i].HurtHP, // m_CacheSkill.hurtServerList[i].RealHurtHP, // _hurtTotalValue, _realHurtValue); AttackHandler.HandlerAttackTarget(_fight, _target, _hurtTotalValue, _realHurtValue, m_CacheSkill.hurtServerList[i].AttackType, m_CacheSkill.id, id, _sweepHit, _target.ActorInfo.serverDie && m_IsLastHitFrame); if (!_target.ActorInfo.serverDie && m_CacheSkill.hurtServerList[i].AttackType != (byte)HurtAttackType.Miss) { AddToNpcPosList(_fight, _target, _sweepHit.bodyControlId, (_target.Pos - owner.Pos).normalized, m_NpcPosList); } } } //#if UNITY_EDITOR // else // { // string _content = string.Format("技能: {0} 第 {1} 帧, 第 {2} 个插帧没有任何服务端攻击对象. ---- {3}", m_CacheSkill.id, m_ProcessFrame, m_ProcessIndex, m_CacheSkill.GetHashCode()); // RuntimeLogUtility.AddLog_Red(_content); // } //#endif if (m_CacheSkill.hurtClientList.Count > 0) { for (int i = 0; i < m_CacheSkill.hurtClientList.Count; ++i) { _target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtClientList[i].clientInstID) as GActorFight; if (_target == null) { continue; } _hurtTotalValue = (ulong)Mathf.Ceil(m_CacheSkill.hurtClientList[i].HurtHP * _floodPercent); _realHurtValue = (ulong)Mathf.Ceil(m_CacheSkill.hurtClientList[i].RealHurtHP * _floodPercent); AttackHandler.HandlerAttackTarget(_fight, _target, _hurtTotalValue, _realHurtValue, m_CacheSkill.hurtClientList[i].AttackType, m_CacheSkill.id, id, _sweepHit, m_IsLastHitFrame && _target.ActorInfo.serverDie); if (!_target.ActorInfo.serverDie && m_CacheSkill.hurtClientList[i].AttackType != (byte)HurtAttackType.Miss) { AddToNpcPosList(_fight, _target, _sweepHit.bodyControlId, (_target.Pos - owner.Pos).normalized, m_NpcPosList); } } } if (m_CacheSkill.hurtClntFightNpcList.Count > 0) { for (int i = 0; i < m_CacheSkill.hurtClntFightNpcList.Count; ++i) { _target = GAMgr.Instance.GetByCID(m_CacheSkill.hurtClntFightNpcList[i].clientInstID) as GActorFight; if (_target == null) { continue; } _hurtTotalValue = (ulong)(m_CacheSkill.hurtClntFightNpcList[i].HurtHP * _floodPercent); _realHurtValue = (ulong)Mathf.Ceil(m_CacheSkill.hurtClntFightNpcList[i].RealHurtHP * _floodPercent); AttackHandler.HandlerAttackTarget(_fight, _target, _hurtTotalValue, _realHurtValue, m_CacheSkill.hurtClntFightNpcList[i].AttackType, m_CacheSkill.id, id, _sweepHit, _target.ActorInfo.serverDie && m_IsLastHitFrame); } } if (m_CacheSkill.hurtServerList.Count == 0) { m_DelayHurtBlood.Add(_floodPercent); } if (m_NpcPosList.Count > 0) { if (!ClientDungeonStageUtility.isClientDungeon && !ClientSceneManager.Instance.IsClientFightMode && !AdventureStage.Instance.IsInAdventureStage #if UNITY_EDITOR && !RuntimeLogUtility.TEST_CLIENT_PVP #endif ) { CB402_tagCMNPCBeatBack _beatBack = new CB402_tagCMNPCBeatBack(); _beatBack.ObjType = (byte)GameObjType.gotNPC; _beatBack.Count = (byte)m_NpcPosList.Count; _beatBack.NPCPosList = new CB402_tagCMNPCBeatBack.tagCMNPCPos[_beatBack.Count]; for (int i = 0; i < _beatBack.Count; ++i) { _beatBack.NPCPosList[i] = new CB402_tagCMNPCBeatBack.tagCMNPCPos { ObjID = (uint)m_NpcPosList[i].objId, PosX = (ushort)(m_NpcPosList[i].posX + GA_Hero.MapOffset.x), PosY = (ushort)(m_NpcPosList[i].posY + GA_Hero.MapOffset.z) }; } if (!CrossServerUtility.IsCrossServer()) { GameNetSystem.Instance.SendInfo(_beatBack); } else { GameNetSystem.Instance.SendToCrossServer(_beatBack); } } } } protected virtual void FlyObjectProcess(int id) { SoFlyObject _config = ScriptableObjectLoader.LoadSoFlyObject(id); if (owner.ServerInstID == PlayerDatas.Instance.PlayerId) { if (_config.cameraSfxId != 0) { SoCameraSFX _cameraSFX = ScriptableObjectLoader.LoadSoCameraSFX(_config.cameraSfxId); if (_cameraSFX != null) { CameraController.Instance.DoShake(_cameraSFX.direction, _cameraSFX.power, _cameraSFX.interval, _cameraSFX.duration); CameraController.Instance.StartZoom(_cameraSFX.zoomScale, _cameraSFX.zoomTime); } } } GActorFight _fight = owner as GActorFight; DesiceFightMove(_fight, _config); FlyObject.InitInfo _initInfo = new FlyObject.InitInfo(); _initInfo.casterServerObjID = owner.ServerInstID; _initInfo.isLastShoot = m_IsLastHitFrame; _initInfo.configId = id; _initInfo.skillId = cacheSkillID; if (_fight.SelectTarget != null) { _initInfo.mainTargetClientInstID = _fight.SelectTarget.ClientInstID; } if (string.IsNullOrEmpty(_config.shootNode) == false) { _initInfo.position = owner.Root.GetChildTransformDeeply(_config.shootNode).position; } else { _initInfo.position = owner.Pos; } _initInfo.forward = owner.Forward; FlyObjectManager.Instance.Create(_initInfo); } protected void DesiceFightMove(GActorFight fightActor, SoConfigBase config) { m_NeedMove = config != null && config.curve != null && config.moveDuration > 0 && fightActor != null && StatusMgr.Instance.CanMove(fightActor.ServerInstID); if (m_NeedMove) { bool _moveThrougthEnable = config.moveThrougthEnable; bool _forceMoveThrougth = config.forceMoveThrougthEnable; if (m_CacheSkill != null && m_CacheSkill.skillInfo != null && m_CacheSkill.skillInfo.config != null && m_CacheSkill.skillInfo.config.Skillactmark != GAStaticDefine.Act_Roll) { if (fightActor.SelectTarget != null && !fightActor.SelectTarget.ActorInfo.serverDie) { if (fightActor.SelectTarget.ActorType == GameObjType.gotNPC) { GActorNpcFight _npc = fightActor.SelectTarget as GActorNpcFight; if (_npc != null) { if (_npc.NpcConfig != null) { m_NeedMove = _npc.NpcConfig.weight != 0 && _moveThrougthEnable; if (!m_NeedMove) { m_NeedMove = _forceMoveThrougth; } } } } else { m_NeedMove = _moveThrougthEnable; } } } } if (m_NeedMove) { m_MoveDuration = config.moveDuration; m_MoveEscape = 0; m_MoveCurve = config.curve; E_SkillCastType _type = (E_SkillCastType)(m_CacheSkill.skillInfo.config.Tag % 10); m_EndPosition = m_CacheSkill.targetPosition; } else { if (m_MoveEscape < m_Duration) { m_NeedMove = true; } else { m_MoveCurve = null; } } } private void HandleInputMove() { GActorFight _fight = owner as GActorFight; if (m_CacheSkill.skillInfo.soFile != null && m_CacheSkill.skillInfo.soFile.acceptInput) { if (owner.ServerInstID == PlayerDatas.Instance.PlayerId) { GA_Hero _hero = PlayerDatas.Instance.hero; if (UserInputHandler.isTouched) { Vector3 _position = owner.Pos; Vector3 _nextPosition = _position + owner.destForward * owner.ActorInfo.moveSpeed * Time.deltaTime; if (GActor.TryGetValidPos(_nextPosition, ref _position)) { owner.Pos = new Vector3(_position.x, owner.Pos.y, _position.z); } } else { if (Input.GetMouseButtonDown(0)) { Camera _mainCamera = CameraController.Instance.CameraObject; bool _valid = true; #if UNITY_EDITOR if (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject()) { _valid = false; } #else int id = Input.GetTouch(0).fingerId; if (EventSystem.current != null &&EventSystem.current.IsPointerOverGameObject(id)) { _valid = false; } #endif RaycastHit _hitInfo; Ray _ray = _mainCamera.ScreenPointToRay(Input.mousePosition); Vector3 _destPosition = owner.Pos; if (!Physics.Raycast(_ray, out _hitInfo, 100, LayerUtility.WalkbleMask)) { _valid = false; } if (!GActor.TryGetValidPos(_hitInfo.point, ref _destPosition)) { _valid = false; } if (_valid) { m_ClickedEndPosition = _destPosition; } } if (m_ClickedEndPosition != Vector3.zero) { Vector3 _direction = (m_ClickedEndPosition - owner.Pos).normalized; owner.Pos += _direction * owner.ActorInfo.moveSpeed * Time.deltaTime; } } float _distance = MathUtility.DistanceSqrtXZ(_hero.PrevPos, _hero.Pos); if (_distance > 0.25f) { _hero.PrevPos = _hero.Pos; UserInputHandler.Send_CB409_tagCMPyMove(0); } } } else { if (m_NeedMove && m_MoveCurve != null) { m_MoveEscape += Time.deltaTime; float _moveSpeed = m_MoveCurve.Evaluate(m_MoveEscape); Vector3 _nextPosition = Vector3.MoveTowards(owner.Pos, m_EndPosition, _moveSpeed * Time.deltaTime); CollisionUtility.NM_RayCast(owner.Pos, _nextPosition, ref _nextPosition); if (GActor.TryGetValidPos(_nextPosition, ref _nextPosition)) { owner.Pos = new Vector3(_nextPosition.x, owner.Pos.y, _nextPosition.z); } if (m_MoveEscape > m_MoveDuration) { OnFininshedFightMove(); } } } } protected virtual void OnPlayerEffect(int id) { int _replaceEffectId = 0; //专精改变特效 if (owner.ServerInstID != PlayerDatas.Instance.PlayerId) { // 隐藏其他玩家的时候也不显示他们的特效 if (!owner.ShowOrHide) { return; } if (SystemSetting.Instance.GetCurrentQualityLevel() == GameQuality.Low) { return; } if (m_CacheSkill.SkillElementID != 0) _replaceEffectId = JobSetupConfig.GetExpertSkillChangeEffectEx(m_CacheSkill.SkillElementID); } else { _replaceEffectId = JobSetupConfig.GetExpertSkillChangeEffect(m_CacheSkill.id); } if (owner is GA_Player && !BattleEffectPlayRule.Instance.CanPlay(owner.ServerInstID)) { return; } // SFXController _controller = SFXPlayUtility.Instance.PlayEffectAsync(id, owner); //专精改变特效 if (_replaceEffectId > 0) { id = _replaceEffectId; } SFXController _controller = null; if (owner.ActorType == GameObjType.gotPlayer) { _controller = SFXPlayUtility.Instance.PlayEffectAsync(id, owner); } else { _controller = SFXPlayUtility.Instance.PlayBattleEffect(id, owner); } if (_controller) { _controller.SetAnimatorSpeed(m_EffectAnimatorSpeed); _controller.SetPaticleSystemSpeed(m_EffectAnimatorSpeed); m_CastedEffect.Add(_controller); } } protected virtual void OnSkillComplete() { #if UNITY_EDITOR string _content = string.Format("STM_BaseAttack => {0} 的技能: {1} 执行至 OnSkillComplete 帧", owner.ServerInstID, cacheSkillID); RuntimeLogUtility.AddLog_Green(_content); #endif ProcessDelayLogic(); if (m_CacheSkill != null) { m_CacheSkill.ClearServerHurtList(); m_CacheSkill.SkillCompelete = true; m_CacheSkill = null; } } private void InitGhostShadow(int id) { SoGhostShadow _ghostShadow = ScriptableObjectLoader.LoadSoGhostShadow(id); m_GhostCreateDuration = _ghostShadow.duration * Constants.F_GAMMA; m_GhostLastTime = _ghostShadow.eachLastTime * Constants.F_GAMMA; m_GhostCreateInterval = _ghostShadow.interval * Constants.F_GAMMA; m_GhostColor = _ghostShadow.color; m_Intensity = _ghostShadow.intensity; } private void OnFininshedFightMove() { if (!m_NeedMove) { return; } m_NeedMove = false; GActorFight _fight = owner as GActorFight; if (_fight == null) { return; } if (ClientDungeonStageUtility.isClientDungeon #if UNITY_EDITOR || RuntimeLogUtility.TEST_CLIENT_PVP #endif ) { return; } if (_fight.ServerInstID == PlayerDatas.Instance.PlayerId) { if (PreFightMission.Instance.IsFinished()) { var _distance = MathUtility.DistanceSqrtXZ(_fight.Pos, _fight.PrevPos); if (_distance > .25f) { //Debug.LogFormat("同步了一次当前的位置, {0} => {1}", new Vector2((int)_fight.prevPos.x * 2, // (int)_fight.prevPos.z * 2), // new Vector2((int)_fight.Pos.x * 2, // (int)_fight.Pos.z * 2)); if (m_CacheSkill != null && (ClientSceneManager.Instance.IsClientFightMode || (m_CacheSkill.skillInfo.config.AtkType != 9 && m_CacheSkill.skillInfo.config.AtkType != 10 && m_CacheSkill.skillInfo.config.AtkType != 34))) { CB406_tagCMFightMove _proto = new CB406_tagCMFightMove { StartX = (ushort)(_fight.PrevPos.x * 2 + GA_Hero.MapOffset.x), StartY = (ushort)(_fight.PrevPos.z * 2 + GA_Hero.MapOffset.z), DestX = (ushort)(_fight.Pos.x * 2 + GA_Hero.MapOffset.x), DestY = (ushort)(_fight.Pos.z * 2 + GA_Hero.MapOffset.z), WorldTick = PlayerDatas.Instance.GetWorldTick() }; GA_Hero.recordServerPos = new Vector3(_proto.DestX, 0, _proto.DestY); if(!ArenaManager.IsArenaClientNotMirrorFight) { if (!CrossServerUtility.IsCrossServer()) { GameNetSystem.Instance.SendInfo(_proto); } else { GameNetSystem.Instance.SendToCrossServer(_proto); } } } } } } _fight.PrevPos = _fight.Pos; } }