public void LocalPlayerWalkToDestination(Vector3 targetPos, Task relateTask = null) { Actor player = Game.GetInstance().GetLocalPlayer(); if (player == null) { return; } targetPos.y = RoleHelp.GetHeightInScene(player.ActorId, targetPos.x, targetPos.z); targetPos = InstanceHelper.ClampInWalkableRange(targetPos, 10); // 判断是否可到达 XNavMeshPath walkMeshPath = new XNavMeshPath(); XNavMesh.CalculatePath(player.transform.position, targetPos, xc.Dungeon.LevelManager.GetInstance().AreaExclude, walkMeshPath); if (walkMeshPath.status != XNavMeshPathStatus.PathComplete) { // 如果通过任务导航寻路,且在新手副本的不可到达区域,则直接飞过去,以免因为配置错误而导致卡死 if (relateTask != null && SceneHelp.Instance.CurSceneID == GameConstHelper.GetUint("GAME_BORN_DUNGEON")) { GameDebug.LogWarning(DBConstText.GetText("MAP_POS_CAN_NOT_REACH") + ",该场景是新手场景,直接瞬移过去"); player.MoveCtrl.SendFly(targetPos); player.SetPosition(targetPos); } else { UINotice.Instance.ShowMessage(DBConstText.GetText("MAP_POS_CAN_NOT_REACH")); } return; } InstanceManager.Instance.IsAutoFighting = false; mPathWalker.WalkTo(targetPos); //player.MoveCtrl.TryWalkTo(targetPos); /* * uint instanceType = InstanceManager.Instance.InstanceType; * * if (instanceType == GameConst.WAR_TYPE_WILD || instanceType == GameConst.WAR_TYPE_HOLE || instanceType == GameConst.WAR_SUBTYPE_WILD_PUB || instanceType == GameConst.WAR_TYPE_MULTI) * { * if(mPathWalker == null) * { * return; * } * * mPathWalker.WalkTo(targetPos); * } * else * { * player.MoveCtrl.TryWalkTo(targetPos); * }*/ TaskNavigationActive(true); IsNavigating = true; }
/// <summary> /// 计算到目标点的路径 /// </summary> void CalcMovePath() { if (mWalkMode == EWalkMode.EWM_Dst)// 只有走到目标点的行走方式才需要寻路 { mDestList.Clear(); walkMeshPath.ClearCorners(); XNavMesh.CalculatePath(mOwnerTrans.position, mDst, LevelManager.GetInstance().AreaExclude, walkMeshPath); if (walkMeshPath.status == XNavMeshPathStatus.PathComplete && walkMeshPath.corners.GetLength(0) >= 2) { // 调整路径的拐弯点 Vector3[] adjuestCorners = walkMeshPath.corners; #if UNITY_EDITOR if (mOwner is LocalPlayer) { for (int j = 1; j < adjuestCorners.Length; ++j) { Debug.DrawLine(adjuestCorners[j - 1], adjuestCorners[j], Color.red, 1.0f * adjuestCorners.Length); } } #endif int len = adjuestCorners.Length; if (len > 3) { adjuestCorners = new Vector3[len]; adjuestCorners[0] = walkMeshPath.corners[0]; for (int i = 1; i < len; ++i) { if (i + 1 >= len) { adjuestCorners[i] = walkMeshPath.corners[i]; break; } Vector3 pre_vec = walkMeshPath.corners[i - 1] - walkMeshPath.corners[i]; pre_vec.y = 0; pre_vec.Normalize(); Vector3 next_vec = walkMeshPath.corners[i + 1] - walkMeshPath.corners[i]; next_vec.y = 0; next_vec.Normalize(); if (pre_vec.sqrMagnitude < minCornerDis || next_vec.sqrMagnitude < minCornerDis) { adjuestCorners[i] = walkMeshPath.corners[i]; continue; } // 先计算调整后的位置(增加MoveImpl.Radius) Vector3 middle_vec = pre_vec + next_vec; var adjuestCorner = walkMeshPath.corners[i] - middle_vec * (0.8f + MoveImpl.Radius * 2); // 在该位置点附近进行采样 XNavMeshHit nearestHit; if (XNavMesh.SamplePosition(adjuestCorner, out nearestHit, 5f, LevelManager.GetInstance().AreaExclude)) { // 如果调整后的位置可行走,则使用新位置,否则使用原始位置 var dis = nearestHit.position - adjuestCorner; if (dis.sqrMagnitude < 0.01f) { adjuestCorners[i] = walkMeshPath.corners[i] - middle_vec * 0.8f; } else { adjuestCorners[i] = walkMeshPath.corners[i]; } } else { adjuestCorners[i] = walkMeshPath.corners[i]; } } } mDst = adjuestCorners[1]; for (int j = 1; j < adjuestCorners.Length; ++j) { mDestList.Add(adjuestCorners[j]); } if (mOwner.IsLocalPlayer) { ClientEventMgr.GetInstance().FireEvent((int)ClientEvent.CE_ACTOR_PATH_POINTS_CHANGED, null); } #if UNITY_EDITOR if (mOwner is LocalPlayer) { for (int j = 1; j < adjuestCorners.Length; ++j) { Debug.DrawLine(adjuestCorners[j - 1], adjuestCorners[j], Color.green, 1f * adjuestCorners.Length); } } #endif } else { // 如果寻路不成功,则设置目标点为初始点 mDst = mOwnerTrans.position; } mWalkToPoint = false; } }