private void PathToTarget(UserInfo user, AiPathData data, Vector3 pathTargetPos, long deltaTime) { UserAiStateInfo info = user.GetAiStateInfo(); if (null != data) { data.UpdateTime += deltaTime; ScriptRuntime.Vector3 srcPos = user.GetMovementStateInfo().GetPosition3D(); float dir = user.GetMovementStateInfo().GetMoveDir(); bool findObstacle = false; bool havePathPoint = data.HavePathPoint; if (havePathPoint)//沿路点列表移动的逻辑 { Vector3 targetPos = data.CurPathPoint; if (!data.IsReached(srcPos))//向指定路点移动(避让移动过程) { user.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); if (!Geometry.IsSameDouble(angle, user.GetMovementStateInfo().GetMoveDir())) { user.GetMovementStateInfo().SetFaceDir(angle); user.GetMovementStateInfo().SetMoveDir(angle); user.GetMovementStateInfo().IsMoving = true; NotifyUserMove(user); } } else//改变路点或结束沿路点移动 { data.UseNextPathPoint(); if (data.HavePathPoint) { targetPos = data.CurPathPoint; user.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); user.GetMovementStateInfo().SetFaceDir(angle); user.GetMovementStateInfo().SetMoveDir(angle); user.GetMovementStateInfo().IsMoving = true; NotifyUserMove(user); } else { data.Clear(); } } } if (!havePathPoint || findObstacle)//获得路点过程(寻路) { data.Clear(); Vector3 targetPos = pathTargetPos; if (Geometry.DistanceSquare(srcPos, targetPos) > 400) { targetPos = user.SpatialSystem.CalcNearstReachablePoint(srcPos, targetPos, 20); } bool canGo = true; /* * if (!user.SpatialSystem.GetCellMapView(user.AvoidanceRadius).CanPass(targetPos)) { * if (!AiLogicUtility.GetWalkablePosition(user.SpatialSystem.GetCellMapView(user.AvoidanceRadius), targetPos, srcPos, ref targetPos)) * canGo = false; * }*/ if (canGo) { List <Vector3> posList = null; if (user.SpatialSystem.CanPass(user.SpaceObject, targetPos)) { posList = new List <Vector3>(); posList.Add(srcPos); posList.Add(targetPos); } else { long stTime = TimeUtility.GetElapsedTimeUs(); posList = user.SpatialSystem.FindPath(srcPos, targetPos, user.AvoidanceRadius); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 1000) { //LogSystem.Warn("pvp FindPath consume {0} us,user:{1} from:{2} to:{3} radius:{4} pos:{5}", calcTime, user.GetId(), srcPos.ToString(), targetPos.ToString(), user.AvoidanceRadius, user.GetMovementStateInfo().GetPosition3D().ToString()); } } if (posList.Count >= 2) { data.SetPathPoints(posList[0], posList, 1); targetPos = data.CurPathPoint; user.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); user.GetMovementStateInfo().SetFaceDir(angle); user.GetMovementStateInfo().SetMoveDir(angle); user.GetMovementStateInfo().IsMoving = true; NotifyUserMove(user); } else { user.GetMovementStateInfo().IsMoving = false; NotifyUserMove(user); } } else { user.GetMovementStateInfo().IsMoving = false; NotifyUserMove(user); } } } }
public static void PathToTargetWithoutObstacle(NpcInfo npc, AiPathData data, Vector3 pathTargetPos, long deltaTime, bool faceIsMoveFir, AbstractNpcStateLogic logic) { NpcAiStateInfo info = npc.GetAiStateInfo(); Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); if (null != data) { data.Clear(); data.UpdateTime += deltaTime; Vector3 targetPos = pathTargetPos; List <Vector3> posList = null; bool canPass = npc.SpatialSystem.CanPass(npc.SpaceObject, targetPos); if (canPass) { posList = new List <Vector3>(); posList.Add(srcPos); posList.Add(targetPos); } else { long stTime = TimeUtility.GetElapsedTimeUs(); posList = npc.SpatialSystem.FindPath(srcPos, targetPos, npc.AvoidanceRadius); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 10000) { LogSystem.Warn("*** pve FindPath consume {0} us,npc:{1} from:{2} to:{3} radius:{4} pos:{5}", calcTime, npc.GetId(), srcPos.ToString(), targetPos.ToString(), npc.AvoidanceRadius, npc.GetMovementStateInfo().GetPosition3D().ToString()); } } if (posList.Count >= 2) { data.SetPathPoints(posList[0], posList, 1); } else { npc.GetMovementStateInfo().IsMoving = false; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } bool havePathPoint = data.HavePathPoint; if (havePathPoint)//沿路点列表移动的逻辑 { targetPos = data.CurPathPoint; if (!data.IsReached(srcPos))//向指定路点移动(避让移动过程) { float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); Vector3 prefVelocity = (float)npc.GetActualProperty().MoveSpeed *new Vector3((float)Math.Sin(angle), 0, (float)Math.Cos(angle)); Vector3 v = new Vector3(targetPos.X - srcPos.X, 0, targetPos.Z - srcPos.Z); v.Normalize(); Vector3 velocity = npc.SpaceObject.GetVelocity(); float speedSquare = (float)npc.GetActualProperty().MoveSpeed *(float)npc.GetActualProperty().MoveSpeed; long stTime = TimeUtility.GetElapsedTimeUs(); Vector3 newVelocity = npc.SpatialSystem.ComputeVelocity(npc.SpaceObject, v, (float)deltaTime / 1000, (float)npc.GetActualProperty().MoveSpeed, (float)npc.GetRadius(), data.IsUsingAvoidanceVelocity); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 10000) { LogSystem.Warn("*** pve ComputeVelocity consume {0} us,npc:{1} velocity:{2} newVelocity:{3} deltaTime:{4} speed:{5} pos:{6}", calcTime, npc.GetId(), velocity.ToString(), newVelocity.ToString(), deltaTime, npc.GetActualProperty().MoveSpeed, npc.GetMovementStateInfo().GetPosition3D().ToString()); } if (data.UpdateTime > 500) { data.UpdateTime = 0; float newAngle = Geometry.GetYAngle(new Vector2(0, 0), new Vector2(newVelocity.X, newVelocity.Z)); npc.GetMovementStateInfo().SetMoveDir(newAngle); if (faceIsMoveFir) { logic.NotifyNpcFace(npc, newAngle); } newVelocity.Normalize(); npc.GetMovementStateInfo().TargetPosition = srcPos + newVelocity * Geometry.Distance(srcPos, targetPos); npc.GetMovementStateInfo().IsMoving = true; logic.NotifyNpcMove(npc); } else { data.UpdateTime += deltaTime; } } else//改变路点或结束沿路点移动 { data.UseNextPathPoint(); if (data.HavePathPoint) { targetPos = data.CurPathPoint; npc.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().SetMoveDir(angle); if (faceIsMoveFir) { logic.NotifyNpcFace(npc, angle); } npc.GetMovementStateInfo().IsMoving = true; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else { npc.GetMovementStateInfo().IsMoving = false; data.Clear(); } } } } }
public static void PathToTarget(NpcInfo npc, AiPathData data, Vector3 pathTargetPos, long deltaTime, bool faceIsMoveFir, AbstractNpcStateLogic logic) { NpcAiStateInfo info = npc.GetAiStateInfo(); if (null != data) { data.UpdateTime += deltaTime; ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float dir = npc.GetMovementStateInfo().GetMoveDir(); bool findObstacle = false; bool havePathPoint = data.HavePathPoint; if (havePathPoint)//沿路点列表移动的逻辑 { Vector3 targetPos = data.CurPathPoint; if (!data.IsReached(srcPos))//向指定路点移动(避让移动过程) { float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); Vector3 prefVelocity = (float)npc.GetActualProperty().MoveSpeed *new Vector3((float)Math.Sin(angle), 0, (float)Math.Cos(angle)); Vector3 v = new Vector3(targetPos.X - srcPos.X, 0, targetPos.Z - srcPos.Z); v.Normalize(); Vector3 velocity = npc.SpaceObject.GetVelocity(); float speedSquare = (float)npc.GetActualProperty().MoveSpeed *(float)npc.GetActualProperty().MoveSpeed; long stTime = TimeUtility.GetElapsedTimeUs(); Vector3 newVelocity = npc.SpatialSystem.ComputeVelocity(npc.SpaceObject, v, (float)deltaTime / 1000, (float)npc.GetActualProperty().MoveSpeed, (float)npc.GetRadius(), data.IsUsingAvoidanceVelocity); findObstacle = !AiLogicUtility.IsWalkable(npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius), srcPos, newVelocity); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 10000) { LogSystem.Warn("*** pve ComputeVelocity consume {0} us,npc:{1} velocity:{2} newVelocity:{3} deltaTime:{4} speed:{5} pos:{6}", calcTime, npc.GetId(), velocity.ToString(), newVelocity.ToString(), deltaTime, npc.GetActualProperty().MoveSpeed, npc.GetMovementStateInfo().GetPosition3D().ToString()); } if (Geometry.DistanceSquare(newVelocity, new Vector3()) <= speedSquare * 0.25f)//避让计算的移动速度变小(说明没有更好的保持原速的选择,停止) { npc.GetMovementStateInfo().IsMoving = false; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else if (findObstacle)//当前移动方向遇到阻挡,停止移动,触发寻路 { npc.GetMovementStateInfo().IsMoving = false; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else if (data.UpdateTime > 1000)//避让速度改变每秒一次(表现上更像人类一些) { data.UpdateTime = 0; float newAngle = Geometry.GetYAngle(new Vector2(0, 0), new Vector2(newVelocity.X, newVelocity.Z)); npc.GetMovementStateInfo().SetMoveDir(newAngle); if (faceIsMoveFir) { npc.GetMovementStateInfo().SetFaceDir(newAngle); } newVelocity.Normalize(); npc.GetMovementStateInfo().TargetPosition = srcPos + newVelocity * Geometry.Distance(srcPos, targetPos); npc.GetMovementStateInfo().IsMoving = true; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = true; } else if (Geometry.DistanceSquare(velocity, newVelocity) > 9.0f) //没有到速度改变周期,但避让方向需要大幅调整 { if (Geometry.Dot(newVelocity, prefVelocity) > 0) //如果是调整为与目标方向一致,则进行调整 { float newAngle = Geometry.GetYAngle(new Vector2(0, 0), new Vector2(newVelocity.X, newVelocity.Z)); npc.GetMovementStateInfo().SetMoveDir(newAngle); if (faceIsMoveFir) { npc.GetMovementStateInfo().SetFaceDir(newAngle); } newVelocity.Normalize(); npc.GetMovementStateInfo().TargetPosition = srcPos + newVelocity * Geometry.Distance(srcPos, targetPos); npc.GetMovementStateInfo().IsMoving = true; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = true; } else//如果调整为远离目标方向,则停止 { npc.GetMovementStateInfo().IsMoving = false; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } else if (!npc.GetMovementStateInfo().IsMoving&& velocity.LengthSquared() > speedSquare * 0.25f)//正常移动过程,继续移动 { velocity.Normalize(); npc.GetMovementStateInfo().TargetPosition = srcPos + velocity * Geometry.Distance(srcPos, targetPos); npc.GetMovementStateInfo().IsMoving = true; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } else//改变路点或结束沿路点移动 { data.UseNextPathPoint(); if (data.HavePathPoint) { targetPos = data.CurPathPoint; npc.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().SetMoveDir(angle); if (faceIsMoveFir) { npc.GetMovementStateInfo().SetFaceDir(angle); } npc.GetMovementStateInfo().IsMoving = true; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else { data.Clear(); } } } if (!havePathPoint || findObstacle)//获得路点过程(寻路) { data.Clear(); Vector3 targetPos = pathTargetPos; bool canGo = true; if (!npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius).CanPass(targetPos)) { if (!AiLogicUtility.GetWalkablePosition(npc.SpatialSystem.GetCellMapView(npc.AvoidanceRadius), targetPos, srcPos, ref targetPos)) { canGo = false; } } if (canGo) { List <Vector3> posList = null; bool canPass = npc.SpatialSystem.CanPass(npc.SpaceObject, targetPos); if (canPass) { posList = new List <Vector3>(); posList.Add(srcPos); posList.Add(targetPos); } else { long stTime = TimeUtility.GetElapsedTimeUs(); posList = npc.SpatialSystem.FindPath(srcPos, targetPos, npc.AvoidanceRadius); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 10000) { LogSystem.Warn("*** pve FindPath consume {0} us,npc:{1} from:{2} to:{3} radius:{4} pos:{5}", calcTime, npc.GetId(), srcPos.ToString(), targetPos.ToString(), npc.AvoidanceRadius, npc.GetMovementStateInfo().GetPosition3D().ToString()); } } if (posList.Count >= 2) { data.SetPathPoints(posList[0], posList, 1); targetPos = data.CurPathPoint; npc.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().SetMoveDir(angle); if (faceIsMoveFir) { npc.GetMovementStateInfo().SetFaceDir(angle); } npc.GetMovementStateInfo().IsMoving = true; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else { npc.GetMovementStateInfo().IsMoving = false; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } else { npc.GetMovementStateInfo().IsMoving = false; logic.NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } } }
private void PathToTargetWithoutObstacle(NpcInfo npc, AiPathData data, Vector3 pathTargetPos, long deltaTime) { NpcAiStateInfo info = npc.GetAiStateInfo(); if (null != data) { data.UpdateTime += deltaTime; ScriptRuntime.Vector3 srcPos = npc.GetMovementStateInfo().GetPosition3D(); float dir = npc.GetMovementStateInfo().GetMoveDir(); bool findObstacle = false; bool havePathPoint = data.HavePathPoint; if (havePathPoint)//沿路点列表移动的逻辑 { Vector3 targetPos = data.CurPathPoint; if (!data.IsReached(srcPos))//向指定路点移动(避让移动过程) { float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); Vector3 prefVelocity = (float)npc.GetActualProperty().MoveSpeed *new Vector3((float)Math.Sin(angle), 0, (float)Math.Cos(angle)); Vector3 v = new Vector3(targetPos.X - srcPos.X, 0, targetPos.Z - srcPos.Z); v.Normalize(); Vector3 velocity = npc.SpaceObject.GetVelocity(); float speedSquare = (float)npc.GetActualProperty().MoveSpeed *(float)npc.GetActualProperty().MoveSpeed; long stTime = TimeUtility.GetElapsedTimeUs(); Vector3 newVelocity = npc.SpatialSystem.ComputeVelocity(npc.SpaceObject, v, (float)deltaTime / 1000, (float)npc.GetActualProperty().MoveSpeed, (float)npc.GetRadius(), data.IsUsingAvoidanceVelocity); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 10000) { LogSystem.Warn("*** pvp ComputeVelocity consume {0} us,npc:{1} velocity:{2} newVelocity:{3} deltaTime:{4} speed:{5} pos:{6}", calcTime, npc.GetId(), velocity.ToString(), newVelocity.ToString(), deltaTime, npc.GetActualProperty().MoveSpeed, npc.GetMovementStateInfo().GetPosition3D().ToString()); for (LinkedListNode <UserInfo> node = npc.UserManager.Users.FirstValue; null != node; node = node.Next) { UserInfo userInfo = node.Value; if (null != userInfo) { LogSystem.Warn("===>User:{0} Pos:{1}", userInfo.GetId(), userInfo.GetMovementStateInfo().GetPosition3D().ToString()); } } for (LinkedListNode <NpcInfo> node = npc.NpcManager.Npcs.FirstValue; null != node; node = node.Next) { NpcInfo npcInfo = node.Value; if (null != npcInfo) { LogSystem.Warn("===>Npc:{0} Pos:{1}", npcInfo.GetId(), npcInfo.GetMovementStateInfo().GetPosition3D().ToString()); } } } if (findObstacle)//当前移动方向遇到阻挡,停止移动,触发寻路 { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else if (!npc.GetMovementStateInfo().IsMoving&& velocity.LengthSquared() > speedSquare * 0.25f)//正常移动过程,继续移动 { velocity.Normalize(); npc.GetMovementStateInfo().TargetPosition = srcPos + velocity * Geometry.Distance(srcPos, targetPos); npc.GetMovementStateInfo().IsMoving = true; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } else//改变路点或结束沿路点移动 { data.UseNextPathPoint(); if (data.HavePathPoint) { targetPos = data.CurPathPoint; npc.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().SetFaceDir(angle); npc.GetMovementStateInfo().SetMoveDir(angle); npc.GetMovementStateInfo().IsMoving = true; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else { data.Clear(); } } } if (!havePathPoint || findObstacle)//获得路点过程(寻路) { data.Clear(); Vector3 targetPos = pathTargetPos; bool canGo = true; if (canGo) { List <Vector3> posList = null; bool canPass = npc.SpatialSystem.CanPass(npc.SpaceObject, targetPos); if (canPass) { posList = new List <Vector3>(); posList.Add(srcPos); posList.Add(targetPos); } else { long stTime = TimeUtility.GetElapsedTimeUs(); posList = npc.SpatialSystem.FindPath(srcPos, targetPos, npc.AvoidanceRadius); long endTime = TimeUtility.GetElapsedTimeUs(); long calcTime = endTime - stTime; if (calcTime > 10000) { LogSystem.Warn("*** pvp FindPath consume {0} us,npc:{1} from:{2} to:{3} radius:{4} pos:{5}", calcTime, npc.GetId(), srcPos.ToString(), targetPos.ToString(), npc.AvoidanceRadius, npc.GetMovementStateInfo().GetPosition3D().ToString()); } } if (posList.Count >= 2) { data.SetPathPoints(posList[0], posList, 1); targetPos = data.CurPathPoint; npc.GetMovementStateInfo().TargetPosition = targetPos; float angle = Geometry.GetYAngle(new Vector2(srcPos.X, srcPos.Z), new Vector2(targetPos.X, targetPos.Z)); npc.GetMovementStateInfo().SetFaceDir(angle); npc.GetMovementStateInfo().SetMoveDir(angle); npc.GetMovementStateInfo().IsMoving = true; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } else { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } else { npc.GetMovementStateInfo().IsMoving = false; NotifyNpcMove(npc); data.IsUsingAvoidanceVelocity = false; } } } }