public bool IsConnected(Vector3 startPos, Vector3 endPos) { //float ratio0 = 0; float ratio1 = 0; bool bHit0 = false; bool bHit1 = false; RaycastHit hitInfo; Vector3 dir = endPos - startPos; float length = dir.magnitude; dir.Normalize(); if (length > 0.1f && CUnityUtil.RayCastWithRadius(0, startPos, dir, out hitInfo, length, CUnityUtil.LayerMaskBlockable)) { //ratio0 = hitInfo.distance / length; bHit0 = true; } if (NavMeshManager.Instance.IsInited && !NavMeshManager.Instance.IsConnected(startPos, endPos, ref ratio1)) { bHit1 = true; } return(!bHit0 && !bHit1); }
//找到寻路点上第一个和目标点连通的点 public bool FindFirstConnectedPoint(Vector3 startPos, Vector3 endPos, Vector3 polyPickExt, float stepSize, out Vector3 selectPoint) { selectPoint = endPos; if (IsConnected(startPos, endPos)) { selectPoint = startPos; return(true); } if (!NavMeshManager.Instance.IsInited) { return(false); } float[] tempAllPoints = NavMeshManager.TempAllPoints; int outVertNum = 0; Vector3 targetPos = endPos; if (!NavMeshManager.Instance.GetWayPointsAtCurrentMap(startPos, targetPos, polyPickExt, stepSize, 0.1f, tempAllPoints, out outVertNum) || outVertNum <= 0) { return(false); } for (int i = 0; i < outVertNum; ++i) { var vec = new Vector3(tempAllPoints[i * 3], tempAllPoints[i * 3 + 1], tempAllPoints[i * 3 + 2]); vec.y = CUnityUtil.GetMapHeight(vec); //看是否被阻挡 RaycastHit hitInfo; Vector3 dir = endPos - startPos; float length = dir.magnitude; if (length > 0.1f) { dir.Normalize(); if (CUnityUtil.RayCastWithRadius(0, startPos, dir, out hitInfo, length, CUnityUtil.LayerMaskBlockable)) { break; } } if (NavMeshManager.Instance.IsInited && NavMeshManager.Instance.IsConnected(vec, endPos)) { selectPoint = vec; return(true); } } return(false); }
public bool IsCollideWithBlockable(Vector3 startPos, Vector3 endPos) { RaycastHit hitInfo; Vector3 dir = endPos - startPos; float length = dir.sqrMagnitude; if (length > 0.01f) { dir.Normalize(); if (CUnityUtil.RayCastWithRadius(0, startPos, dir, out hitInfo, length, CUnityUtil.LayerMaskBlockable)) { return(true); } } return(false); }
//从startPos到endPos, 是否连通,包括obstacle和navmesh public bool IsConnected(Vector3 startPos, Vector3 endPos, out Vector3 hitPos) { hitPos = startPos; RaycastHit hitInfo; Vector3 dir = endPos - startPos; float length = dir.magnitude; dir.Normalize(); float ratio0 = 0; if (length > 0.1f) { if (CUnityUtil.RayCastWithRadius(0, startPos, dir, out hitInfo, length, CUnityUtil.LayerMaskBlockable)) { ratio0 = hitInfo.distance / length; hitPos = startPos + (endPos - startPos) * ratio0; hitPos.y = CUnityUtil.GetMapHeight(hitPos); return(false); } } float ratio1 = 0; if (NavMeshManager.Instance.IsInited && !NavMeshManager.Instance.IsConnected(startPos, endPos, ref ratio1)) { if (ratio1 < ratio0) { hitPos = startPos + (endPos - startPos) * ratio1; hitPos.y = CUnityUtil.GetMapHeight(hitPos); } return(false); } return(true); }
public override bool Tick(float dt) { Joystick joystick = Joystick.Instance; if (joystick == null) { return(true); } _MoveDir = joystick.MoveDir; bool bValidDir = Util.IsValidDir(ref _MoveDir); if (!bValidDir) { return(false); } TickAdjustDir(_MoveDir); var curDir = _Owner.forward; Vector3 pos = _Owner.position; pos.y += 0.6f; #region 碰撞检测 RaycastHit hitInfo; if (CUnityUtil.RayCastWithRadius(0, pos, curDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskMovementObstacle)) { SyncMoveStampWhenNoProgress(); return(false); } if (CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, pos, curDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC)) { // 修正运动方向 Vector3 adjustDir; { Vector3 hitNormal = hitInfo.normal; var v = Vector3.Cross(hitNormal, curDir); adjustDir = Vector3.Cross(v, hitNormal); adjustDir.y = 0; adjustDir.Normalize(); } //TickAdjustDir(adjustDir); // 朝调整方向trace,如果还有boxcollider则不再寻找新的方向 if (CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, pos, adjustDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC)) { SyncMoveStampWhenNoProgress(); return(false); } pos = _Owner.position + _MoveSpeed * dt * adjustDir; if (!IsValidPositionStrict(pos)) { SyncMoveStampWhenNoProgress(); return(false); } pos.y = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY; _Owner.position = pos; SyncMoveStampWhenProgress(); return(false); } #endregion float fTestDist = NavMeshManager.TRACE_EXTEND_DISTANCE; if (_MoveSpeed * dt > fTestDist) //需要测试一个比较近的距离 { Vector3 vTemp = _Owner.position + fTestDist * curDir; if (!NavMeshManager.Instance.IsValidPositionStrict(vTemp, false, 0.3f)) { SyncMoveStampWhenNoProgress(); return(false); } } { Vector3 vNearest = pos; pos = _Owner.position + _MoveSpeed * dt * curDir; pos.y = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY; if (NavMeshManager.Instance.GetNearestValidPosition(pos, ref vNearest)) { //取目标点和最近navmesh点的插值,这样可以沿移动方向在navmesh周边滑动 Vector3 vDelta = pos - vNearest; vDelta.y = 0; float fLen = vDelta.magnitude; if (fLen < 0.01f) { pos = vNearest; } else { float fv = Math.Min(fLen, NavMeshManager.TRACE_EXTEND_DISTANCE); //最大超出navmesh边界0.2 但也不能被服务器拉回 NavMeshManager.IsValidPosition vDelta.Normalize(); pos = vNearest + vDelta * fv; } } else { SyncMoveStampWhenNoProgress(); return(false); } } if (NavMeshManager.Instance.IsValidPositionStrict(pos, false, NavMeshManager.TRACE_EXTEND_DISTANCE)) //摇杆必须为navmesh有效点,否则会被服务器拉回 { pos.y = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY; if (!CUnityUtil.IsHeightAccept(pos, _Owner.position)) //高度不合法 { SyncMoveStampWhenNoProgress(); return(false); } _Owner.position = pos; SyncMoveStampWhenProgress(); } else { SyncMoveStampWhenNoProgress(); } return(false); }
private bool TickHostPlayer3(float dt) { Vector3 curPos = _Owner.position; curPos.y += 0.6f; var distLeft = Util.DistanceH(curPos, _TargetPos); //到达检查, 如果offset为0,则停在target位置,否则停在当前位置 if (_DestOffset > 0.0f) { if (distLeft <= _DestOffset) { _DestOffset = 0.0f; RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward); return(true); } } else if (distLeft < NEAREST_DIST) { Vector3 vPos = _TargetPos; vPos.y = CUnityUtil.GetMapHeight(vPos) + _ObjectComponent.OffsetY; _Owner.position = vPos; _DestOffset = 0.0f; RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward); return(true); } Vector3 dir = (_TargetPos - curPos); dir.y = 0; _MoveDir = dir.normalized; var nextPos = Vector3.zero; #region 碰撞检测 RaycastHit hitInfo; //检查obstacle碰撞,中断 if (CUnityUtil.RayCastWithRadius(0, curPos, _MoveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskMovementObstacle)) { RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir); return(true); } if (CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, curPos, _MoveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC)) { Vector3 ahead = _Owner.position + _Owner.forward * 1.5f; Vector3 avoidanceForce = ahead - hitInfo.collider.transform.position; avoidanceForce = avoidanceForce.normalized * MAX_AVOID_FORCE; Vector3 steering = (_MoveDir * _MoveSpeed + avoidanceForce).normalized; nextPos = _Owner.position + _MoveSpeed * dt * steering; nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY; if (!IsValidPositionStrict(nextPos)) { RealOnFinish(BEHAVIOR_RETCODE.Blocked, steering); return(true); } steering.y = 0; if (!Util.IsValidDir(ref steering)) { steering = _Owner.forward; } _Owner.position = nextPos; if (IsDirChanged) { TickAdjustDir(steering); } SyncMoveStamp(dir, false, true, _TargetPos); return(false); } #endregion #region 步长是否超过剩余距离 //判断这次移动的距离是否超过剩余距离,停止 float fDistMove = _MoveSpeed * dt; if (fDistMove >= distLeft) { Vector3 vPos = _TargetPos; vPos.y = CUnityUtil.GetMapHeight(vPos) + _ObjectComponent.OffsetY; _Owner.position = vPos; RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward); return(true); } #endregion nextPos = curPos + _MoveSpeed * dt * _MoveDir; #region NextStepPos NavMesh有效性检查 Vector3 nextValidPos = Vector3.zero; if (NavMeshManager.Instance.GetNearestValidPosition(nextPos, ref nextValidPos, 1.0f)) { Vector3 vDelta = nextPos - nextValidPos; vDelta.y = 0; float fLen = vDelta.magnitude; if (fLen < 0.01f) //navmesh寻路点 { nextPos = nextValidPos; } else { float fv = Math.Min(fLen, NavMeshManager.TRACE_EXTEND_DISTANCE); //最大可以跨出navmesh范围 vDelta.Normalize(); nextPos = nextValidPos + vDelta * fv; } nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY; Vector3 v = nextPos - curPos; v.y = 0; if (v.sqrMagnitude <= 0.0004f && _MoveSpeed * dt > 0.02f) //停止不动且和building碰撞, block { ++_BlockOccurCount; if (_BlockOccurCount > 3) { _BlockOccurCount = 0; _Owner.position = nextPos; RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir); return(true); } } else { _BlockOccurCount = 0; } } else { nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY; _BlockOccurCount = 0; RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir); return(true); } #endregion _Owner.position = nextPos; if (IsDirChanged) { TickAdjustDir(_MoveDir); } //避免频繁发送 SyncMoveStamp(_MoveDir, false, false, _TargetPos); return(false); }
private bool TickNavigation(float dt) { Vector3 curPos = _Owner.position; //offset判断, 如果offset为0,则停在target位置,否则停在当前位置 float distSqr = Util.SquareDistanceH(curPos, _TargetPos); if (_DestOffset > Util.FloatZero && distSqr <= _DestOffset * _DestOffset) { _DestOffset = 0.0f; RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward); return(true); } if (distSqr < NEAREST_DIST * NEAREST_DIST) { Vector3 vPos = _TargetPos; vPos.y = CUnityUtil.GetMapHeight(vPos) + _ObjectComponent.OffsetY; _Owner.position = vPos; _DestOffset = 0.0f; RealOnFinish(BEHAVIOR_RETCODE.Success, _Owner.forward); return(true); } // 吸附中,需要重新计算路线 if (_ObjectComponent.HasBehavior(BehaviorType.Adsorb)) { if (!CalcHostPathFindingInfo()) { _DestOffset = 0.0f; RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir); return(true); } } Vector3 vNextPos; var step = _MoveSpeed * dt; int iPath = 0; var bArrive = CHostPathFindingInfo.Instance.GetNextNavPosition(step, ref curPos, ref iPath, out vNextPos); vNextPos.y = CUnityUtil.GetMapHeight(vNextPos) + _ObjectComponent.OffsetY; var facedir = vNextPos - curPos; facedir.y = 0; if (!Util.IsValidDir(ref facedir)) { facedir = _Owner.forward; } //寻路到达判断 if (bArrive) { _Owner.position = vNextPos; _DestOffset = 0.0f; RealOnFinish(BEHAVIOR_RETCODE.Success, facedir); return(true); } _MoveDir = facedir; curPos.y += 0.6f; RaycastHit hitInfo; #region Obstacle碰撞检测 //检查obstacle碰撞,中断 if (CUnityUtil.RayCastWithRadius(0, curPos, _MoveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskMovementObstacle)) { _DestOffset = 0.0f; RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir); return(true); } #endregion if (IgnoreCollisionDetect) //忽略碰撞 { _Owner.position = vNextPos; if (IsDirChanged) { TickAdjustDir(_MoveDir); } SyncMoveStamp(_MoveDir, false, false, vNextPos); return(false); } else { bool bLastCollide = _IsCollidedWithObjects; #region NPC碰撞检测 _IsCollidedWithObjects = CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, curPos, _MoveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC); if (_IsCollidedWithObjects) { float dist = Util.SquareDistanceH(curPos, _NavCalcStartPosition); if (dist < 1.0f) { ++_CollideTryCount; } else { _CollideTryCount = 0; } if (_CollideTryCount >= 1) { _IsCollidedWithObjects = false; _CollideTryCount = 0; } } #endregion if (_IsCollidedWithObjects) { Vector3 ahead = _Owner.position + _Owner.forward * 1.5f; ahead.y = 0; Vector3 avoidanceForce = ahead - hitInfo.collider.transform.position; avoidanceForce.y = 0; avoidanceForce = avoidanceForce.normalized * MAX_AVOID_FORCE; Vector3 steering = (_MoveDir * _MoveSpeed + avoidanceForce).normalized; vNextPos = _Owner.position + _MoveSpeed * Math.Max(0.03f, dt) * steering; if (!IsValidPositionStrict(vNextPos)) //尝试不成功则恢复,否则会卡住 { vNextPos = _Owner.position; } else { vNextPos.y = CUnityUtil.GetMapHeight(vNextPos) + _ObjectComponent.OffsetY; } _Owner.position = vNextPos; if (IsDirChanged) { TickAdjustDir(steering); } SyncMoveStamp(steering, false, true, _TargetPos); return(false); } else { if (bLastCollide) //由碰撞变为不碰撞 { if (!CalcHostPathFindingInfo()) //以当前点继续寻路 { _DestOffset = 0.0f; RealOnFinish(BEHAVIOR_RETCODE.Blocked, _MoveDir); return(true); } return(false); } } _Owner.position = vNextPos; if (IsDirChanged) { TickAdjustDir(_MoveDir); } SyncMoveStamp(_MoveDir, false, false, _TargetPos); return(false); } }
bool TickHostPlayer3(float dt) { if (_TargetTrans == null) { RealOnFinish(BEHAVIOR_RETCODE.Failed, _Owner.forward); return(true); } Vector3 curPos = _Owner.position; Vector3 targetPos = _TargetTrans.position; float distanceSqr = Util.SquareDistanceH(curPos, targetPos); Vector3 dir = (targetPos - curPos); dir.y = 0; Vector3 moveDir = dir.normalized; if (distanceSqr < _MaxDistanceSqr && distanceSqr > _MinDistanceSqr) { if (!_IsLoop) { RealOnFinish(BEHAVIOR_RETCODE.Success, moveDir); return(true); } else { return(false); } } curPos.y += 0.6f; RaycastHit hitInfo; Vector3 nextPos; //检查obstacle碰撞,中断 if (CUnityUtil.RayCastWithRadius(0, curPos, moveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskMovementObstacle)) { RealOnFinish(BEHAVIOR_RETCODE.Blocked, moveDir); return(true); } if (CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, curPos, moveDir, out hitInfo, CUnityUtil.TraceForwardDistance, CUnityUtil.LayerMaskNPC)) { Vector3 ahead = _Owner.position + _Owner.forward * 1.5f; Vector3 avoidanceForce = ahead - hitInfo.collider.transform.position; avoidanceForce = avoidanceForce.normalized * MAX_AVOID_FORCE; Vector3 steering = (moveDir * _MoveSpeed + avoidanceForce).normalized; nextPos = _Owner.position + _MoveSpeed * dt * steering; if (!IsValidPositionStrict(nextPos)) { RealOnFinish(BEHAVIOR_RETCODE.Blocked, steering); return(true); } dir = steering; dir.y = 0; Vector3 vNormalDir; if (!Util.IsValidDir(ref dir)) { dir = _Owner.forward; } nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY; _Owner.position = nextPos; SyncMoveStamp(dir, false, true, targetPos); return(false); } //判断这次移动的距离是否超过剩余距离,停止 float fDistMove = _MoveSpeed * dt; if (fDistMove * fDistMove >= distanceSqr) { targetPos.y = CUnityUtil.GetMapHeight(targetPos) + _ObjectComponent.OffsetY; _Owner.position = targetPos; var facedir = targetPos - curPos; facedir.y = 0; if (!Util.IsValidDir(ref facedir)) { facedir = _Owner.forward; } RealOnFinish(BEHAVIOR_RETCODE.Success, facedir); return(true); } nextPos = curPos + _MoveSpeed * dt * moveDir; nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY; Vector3 nearestPos = new Vector3(); if (NavMeshManager.Instance.GetNearestValidPosition(nextPos, ref nearestPos, 1.0f)) { Vector3 vDelta = nextPos - nearestPos; vDelta.y = 0; float fLen = vDelta.magnitude; if (fLen < 0.01f) //navmesh寻路点 { nextPos = nearestPos; } else { float fv = Math.Min(fLen, NavMeshManager.TRACE_EXTEND_DISTANCE); //最大可以跨出navmesh范围 vDelta.Normalize(); nextPos = nearestPos + vDelta * fv; } Vector3 v = nextPos - curPos; v.y = 0; if (v.sqrMagnitude <= 0.0004f && _MoveSpeed * dt > 0.02f) //停止不动且和building碰撞, block { ++_BlockCount; if (_BlockCount > 3) { _BlockCount = 0; RealOnFinish(BEHAVIOR_RETCODE.Blocked, moveDir); return(true); } } else { _BlockCount = 0; } } else { _BlockCount = 0; RealOnFinish(BEHAVIOR_RETCODE.Blocked, moveDir); return(true); } nextPos.y = CUnityUtil.GetMapHeight(nextPos) + _ObjectComponent.OffsetY; _Owner.position = nextPos; TickAdjustDir(moveDir); SyncMoveStamp(moveDir, false, false, targetPos); return(false); }
public override bool Tick(float dt) { if (_FinishedTime <= Time.time) { //Debug.LogFormat("Dash End {0} @{1}", _Owner.position, Time.time); RealOnFinish(BEHAVIOR_RETCODE.Success, _Direction); return(true); } // 如果是主角,客户端计算,通知服务器;非主角,完全听服务器的 if (_OwnerType == ObjectBehaviour.OBJ_TYPE.HOSTPLAYER) { #region 摇杆控制方向 if (_CanChangeDir) { Joystick joystick = Joystick.Instance; if (joystick != null && !joystick.MoveDir.IsZero()) { var destDir = joystick.MoveDir; var resetDir = _LerpDestDir.IsZero(); if (!resetDir) { var angle0 = Vector3.Angle(_LerpDestDir, destDir); if (Vector3.Dot(Vector3.up, Vector3.Cross(_LerpDestDir, destDir)) < 0) { angle0 = 180 - angle0; } resetDir = angle0 > 10; } if (resetDir) { _LerpDestDir = destDir; } } var newDir = Vector3.Slerp(_Direction, _LerpDestDir, RotationLerpFactor); _Direction = newDir.normalized; _Owner.forward = _Direction; if (_BlockedEnemyId == 0 && (Time.time - LastSyncTimestamp > 0.1f)) { var maxDis = _Speed * (_FinishedTime - Time.time); var dis = Util.GetMaxValidDistance(_Owner.position, _Direction, maxDis); _Destination = _Owner.position + _Direction * dis; // 需要重新同步 _ObjectComponent.SyncHostDashInfo(_Owner.position, _Direction, _Destination); LastSyncTimestamp = Time.time; } } #endregion Vector3 castpos = _Owner.position; castpos.y += 0.6f; //拔高0.6米进行前方向trace RaycastHit hitInfo; var raycastStep = _Speed * dt; if (raycastStep < 1) { raycastStep = 1; } #region 检查Building和obstacle碰撞 if (CUnityUtil.RayCastWithRadius(0, castpos, _Direction, out hitInfo, raycastStep, CUnityUtil.LayerMaskMovementObstacle)) { if (_CanChangeDir) { return(false); } else { RealOnFinish(BEHAVIOR_RETCODE.Blocked, _Direction); //主角需要通知服务器停住位置 _ObjectComponent.SyncHostDashCollideInfo(0, false); return(true); } } #endregion var collideWithEntity = CUnityUtil.RayCastWithRadius(Main.HostPlayerRadius, castpos, _Direction, out hitInfo, raycastStep, CUnityUtil.LayerMaskEntity); #region Entity碰撞 if (collideWithEntity) { var collideObj = hitInfo.collider.gameObject.GetComponentInParent <ObjectBehaviour>(); if (collideObj != null) { var collideObjId = collideObj.ID32Bit; if (_CanPierce) { // 技能移动不穿越大型怪物 范导新需求 added by zhouhenan // 20190112 - 增加穿透目标前提,解决穿到怪物肚子中的问题 added by lijian if (_ObjectComponent.OnCollidingHuge(collideObjId)) { RealOnFinish(BEHAVIOR_RETCODE.Blocked, _Direction); _ObjectComponent.SyncHostDashCollideInfo(0, false); return(true); } } else { var collideEntityType = ObjectBehaviour.CollideEntityType.All; if (_OnlyCollideWithSkillTarget) { collideEntityType = ObjectBehaviour.CollideEntityType.OnlyTarget; } else if (_CanChangeDir) { collideEntityType = ObjectBehaviour.CollideEntityType.Enemy; } if (_DashContinue) { // 被同一只怪挡住,原地冲 if (_BlockedEnemyId > 0 && _BlockedEnemyId == collideObjId) { return(false); } // 确认是否被目标挡住 如果被挡,需要同步服务器 if (_ObjectComponent.OnCollideWithOther(collideObjId, collideEntityType)) { _BlockedEnemyId = collideObjId; _ObjectComponent.SyncHostDashCollideInfo(collideObjId, false); return(false); } else if (_BlockedEnemyId > 0) { var maxDis = (_FinishedTime - Time.time) * _Speed; var dis = Util.GetMaxValidDistance(_Owner.position, _Direction, maxDis); var dst = _Owner.position + dis * _Direction; _Destination = dst; _ObjectComponent.SyncHostDashCollideInfo(_BlockedEnemyId, true); _BlockedEnemyId = 0; } } else { if (_ObjectComponent.OnCollideWithOther(collideObjId, collideEntityType)) { _ObjectComponent.SyncHostDashCollideInfo(collideObjId, false); RealOnFinish(BEHAVIOR_RETCODE.Blocked, _Direction); return(true); } } } } } #endregion else { if (_BlockedEnemyId > 0) { var maxDis = (_FinishedTime - Time.time) * _Speed; var dis = Util.GetMaxValidDistance(_Owner.position, _Direction, maxDis); var dst = _Owner.position + dis * _Direction; _Destination = dst; _ObjectComponent.SyncHostDashCollideInfo(_BlockedEnemyId, true); _BlockedEnemyId = 0; } } } var pos = _Owner.position + (_Speed * _Direction * dt); pos.y = CUnityUtil.GetMapHeight(pos) + _ObjectComponent.OffsetY; if (_OwnerType == ObjectBehaviour.OBJ_TYPE.HOSTPLAYER) { if (!IsValidPositionStrict(pos) || !CUnityUtil.IsHeightAccept(pos, _Owner.position)) { if (_CanChangeDir) { return(false); } else { RealOnFinish(BEHAVIOR_RETCODE.Blocked, _Direction); //主角需要通知服务器停住位置 _ObjectComponent.SyncHostDashCollideInfo(0, true); return(true); } } } _Owner.position = pos; return(false); }