// Use this for initialization void Start() { time = 0; transform.localScale = Vector3Util.Vector3(0, 0, 0); }
/// <summary> /// True if the two points are near each other. (Less accurate check.) /// </summary> /// <param name="u">Point u.</param> /// <param name="v">Point v.</param> /// <returns>True if the two points are near each other. </returns> public bool IsNear(Vector3 u, Vector3 v) { return(Vector3Util.IsInRange(u, v, data.radiusNear, data.heightTolerence)); }
/// <summary> /// Manages the crowd agent target, replanning the long distance path if needed. /// </summary> /// <returns>False on critical failure.</returns> private bool HandleNormalPlanning(bool hasNewGoal) { // Re-targetting will only occur if there is a new goal or getting close to an // intermediate target. if (hasNewGoal || !mGoalInRange && agent.IsNear(agent.data.desiredPosition.point, mTarget.point)) { // First try to set the target without replanning. if (!SetLocalTarget()) { // This can happen when approaching the target from // outside the planned path, which can happen when // the crowd manager takes a different path. // (Or a new goal was set.) if (agent.PlanPath(agent.data.desiredPosition, agent.data.plannerGoal) <= 0) { // Critical failure. Debug.LogError(string.Format( "{0}: Path replan failed. Position: {1}, Goal: {2}" , agent.transform.name , agent.data.desiredPosition.ToString() , agent.data.plannerGoal.ToString())); return(false); } // Next call should not not fail since the path is known to be good. return(SetLocalTarget()); } } else if (mGoalInRange) { /* * Need to monitor to see if the goal has been reached. This can be tricky. * The optimal 'at' and 'near' range ranges are usually too restrictive and too * large respectively. So a fixed value, based on experience, is used instead. * (OK to make this value configurable.) * * Assumption: Other parts of the code detect if a re-evaluation of position * is needed. */ if (mAtGoalState == StateNormal) { if (Vector3Util.IsInRange(agent.data.desiredPosition.point , agent.data.plannerGoal.point , 0.12f, agent.data.heightTolerence)) { // Remove from the crowd and add back, exactly at the goal with a zero max // speed. Basically, puts a static obstacle into the crowd. mAtGoalState = StateInRange; agent.RemoveFromCrowd(); CrowdAgentParams config = agent.crowdConfig; config.maxSpeed = 0; agent.crowdAgent = agent.navGroup.crowd.AddAgent(agent.data.plannerGoal.point, config); agent.data.flags &= ~NavFlag.CrowdConfigUpdated; // Debug.Log("Transition to 'at goal' task."); } } } return(true); }
//判断两个点是否相近,调用底层来做的 public bool IsNear(Vector3 PointA, Vector3 pointB) { return(Vector3Util.IsInRange(PointA, pointB, radiusNear, heightTolerence)); }
//只要没有结束就会一直更新 //这些更新是在NavManager里的更新方法进行统一更新的 public override bool Update() { try { //检测位置和目标变化,并约束到导航网格 bool newPos = (theAgent.flags & NavFlag.HasNewPosition) != 0; bool newGoal = (theAgent.flags & NavFlag.HasNewGoal) != 0; NavmeshPoint pt; if (newPos) { //和critterai的dll交互,然后调到recast的dll //获得当前的navmesh上面的点位置 pt = theAgent.GetPointSearch(theAgent.position); //如果点无效就报个错 if (pt.polyRef == 0) { // Debug.LogWarning(string.Format("{0}: Could not constrain position to navigation mesh. Ignoring: {1}", // theAgent.transform.name, pt.ToString())); newPos = false; } else { theAgent.desiredPosition = pt; } } if (newGoal) { //和critterai的dll交互,然后调到recast的dll //获得当前的navmesh上面的点位置 pt = theAgent.GetPointSearch(theAgent.goal); if (pt.polyRef == 0) { // Ignore new goal. // Debug.LogWarning(string.Format("{0}: Could not constrain goal to navigation mesh. Ignoring: {1}" // , theAgent.transform.name, pt.ToString())); newGoal = false; } else { theAgent.plannerGoal = pt; } } theAgent.flags &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal); if (newGoal || newPos) { //重新制定移动计划 if (!HandlePlanning(newPos, newGoal)) { return(false); } } //是否需要进行移动的判定 if (theAgent.IsAtDestination()) { //在目标就不用移动了 mSpeed = 0; theAgent.desiredPosition = theAgent.plannerGoal; theAgent.desiredVelocity = Vector3.zero; theAgent.desiredSpeedSq = 0; return(true); } //在这里调整速度(这理由可以非常任性地修改的空间) float maxDelta = theAgent.crowdConfig.maxAcceleration * 0.02f; //float desiredSpeed = theAgent.crowdConfig.maxSpeed; float desiredSpeed = theAgent.moveSpeed; if (Vector3Util.GetDistance2D(theAgent.desiredPosition.point, theAgent.plannerGoal.point) < theAgent.crowdConfig.radius * 3) { //如果已经很贴近目标,就做了个减速,这个还是根据具体需求来搞吧 //这个效果目前还不用,感觉略显魔性 desiredSpeed = Mathf.Max(mSpeed - maxDelta, desiredSpeed * 0.2f); } else { //正常飚速度 desiredSpeed = Mathf.Min(mSpeed + maxDelta, desiredSpeed); } //运行到这里,终于,开始真正正正的移动了 //每个间隔几次,来一次优化 if (--mOptimizationTimer < 1) { theAgent.corridor.OptimizePathTopology(true); mOptimizationTimer = OptimizationFrequency; } //desiredSpeed *= 10;//用于测试速度 Vector3 movePos = Vector3.MoveTowards(theAgent.desiredPosition.point, theAgent.corridor.Corners.verts[0], desiredSpeed * NavManager.threadUpdateTimer); //运行底层的move进行移动(这句话是无比关键的关键) theAgent.corridor.MovePosition(movePos); //获取移动之后的位置 movePos = theAgent.corridor.Position.point; //更新agent的数组记录 theAgent.desiredVelocity = (movePos - theAgent.desiredPosition.point).normalized * desiredSpeed; theAgent.desiredSpeedSq = desiredSpeed * desiredSpeed; theAgent.desiredPosition = theAgent.corridor.Position; mSpeed = desiredSpeed; return(true); } catch (Exception X) { Debug.Log("Error:" + X.ToString()); return(false); } }
/** * 返回true则表示完成 */ public bool Do(int action) { if (action == 100) { //隐藏光环 ring.SetActive(false); return(true); } else if (action == 101) { //显示光环 ring.SetActive(true); return(true); } else if (action == 1) { //从地底出现 IncorporealOn(); float speed = 1; Vector3 targetPosition; if (player.isDead) { float x = player.transform.rotation.z > 0 ? 2f : -2f; targetPosition = player.transform.position + new Vector3(x, -0.5f, 1.5f); } else { targetPosition = player.transform.position + new Vector3(0, 0.5f, -1.5f); } // Debug.Log("transform.position=" + transform.position + "targetPosition=" + targetPosition); transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * speed); if (Vector3Util.compareVector3(transform.position, targetPosition, 0.05f)) { return(true); } } else if (action == 3) { //钻入地底消失 IncorporealOn(); float speed = 1; Vector3 targetPosition = new Vector3(transform.position.x, player.transform.position.y - 2f, transform.position.z); transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime * speed); if (Vector3Util.compareVector3(transform.position, targetPosition, 0.05f)) { return(true); } } else if (action == 10) { //前往某地点 IncorporealOff(); float speed = 2; Vector3 targetPosition = getClosetMemoryBug().transform.position; // Debug.Log((targetPosition - transform.position).normalized); transform.Translate((targetPosition - transform.position).normalized * speed * Time.deltaTime); if (Vector3Util.compareVector3(transform.position, targetPosition, 10f)) { return(true); } } return(false); }
void OpenTheGatesOfHell(Player player, string cmd, string[] input) { if (!player.HasPermission("admin") && !player.HasPermission("mod")) { PrintToChat(player, "You have no permission to open the gates of Hell!"); return; } string z = "villager"; string w = "werewolf"; if (input.IsNullOrEmpty()) { CreatureAmount = GetConfig("AMOUNT of creatures to spawn", 5); PrintToChat(player, "you have not set an argument for the number of spawned creatures, using default value of " + CreatureAmount.ToString()); } else { CreatureAmount = int.Parse(string.Concat(input)); } if (CreatureAmount > 20) { CreatureAmount = 20; PrintToChat(player, "You cannot spawn more than 20 Villagers per Player with GatesOfHell (Server Lag)!"); } if (Werewolves && Zombies) { timer.Repeat(3f, (CreatureAmount / 2), () => { foreach (Player connectedplayer in Server.AllPlayersExcept(Server.GetPlayerFromString("Server"))) { Vector3 RandomPosition = Vector3Util.Randomize(connectedplayer.Entity.Position, -100, 100); Vector3 RandomToSurfacePosition = new Vector3(RandomPosition.x, TerrainAPIBase.GetTerrainHeightAt(RandomPosition), RandomPosition.z); SpawnSingleCreatureAroundEveryPlayer(RandomToSurfacePosition, connectedplayer, z); } }); timer.Repeat(3f, (CreatureAmount / 2), () => { foreach (Player connectedplayer in Server.AllPlayersExcept(Server.GetPlayerFromString("Server"))) { Vector3 RandomPosition = Vector3Util.Randomize(connectedplayer.Entity.Position, -100, 100); Vector3 RandomToSurfacePosition = new Vector3(RandomPosition.x, TerrainAPIBase.GetTerrainHeightAt(RandomPosition), RandomPosition.z); SpawnSingleCreatureAroundEveryPlayer(RandomToSurfacePosition, connectedplayer, w); } }); } else if (Zombies) { timer.Repeat(3f, (CreatureAmount), () => { foreach (Player connectedplayer in Server.AllPlayersExcept(Server.GetPlayerFromString("Server"))) { Vector3 RandomPosition = Vector3Util.Randomize(connectedplayer.Entity.Position, -100, 100); Vector3 RandomToSurfacePosition = new Vector3(RandomPosition.x, TerrainAPIBase.GetTerrainHeightAt(RandomPosition), RandomPosition.z); SpawnSingleCreatureAroundEveryPlayer(RandomToSurfacePosition, connectedplayer, z); } }); } else if (Werewolves) { timer.Repeat(3f, (CreatureAmount / 2), () => { foreach (Player connectedplayer in Server.AllPlayersExcept(Server.GetPlayerFromString("Server"))) { Vector3 RandomPosition = Vector3Util.Randomize(connectedplayer.Entity.Position, -100, 100); Vector3 RandomToSurfacePosition = new Vector3(RandomPosition.x, TerrainAPIBase.GetTerrainHeightAt(RandomPosition), RandomPosition.z); SpawnSingleCreatureAroundEveryPlayer(RandomToSurfacePosition, connectedplayer, w); } }); } else if (!Werewolves && !Zombies) { PrintToChat(player, "You need to activate at least one creature in the configfile to spawn it! reload the plugin afterwards."); return; } }
public void set(List <Vector3> list) { Vector3Util.calcRegion(list, out min_, out max_); }
void FixedUpdate() { if (!Vector3Util.IsAlmostEquals(transform.position, afterMovePosition)) { stop(); return; } CorvoPathFinder pf = GetComponent <CorvoPathFinder>(); if (destinationActive) { if (pf) { if (pf.havePath()) { checkReachedNode(); } if (Time.time > pathRefreshTime) { updatePath(); } if (mustMove) { if (pf.havePath()) { Vector3 _dir = (pf.getDestination() - transform.position).normalized; if (updateRotation != rotationType.dontRotate) { Vector3 _dir2D; if (updateRotation == rotationType.rotateAll) //rotate all { _dir2D = (pf.getDestination() - transform.position).normalized; } else //don't update z axis { _dir2D = ((pf.getDestination() - Vector3.up * pf.getDestination().y) - (transform.position - Vector3.up * transform.position.y)).normalized; } transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(_dir2D), Time.deltaTime * rotationSpeed); } if (Vector3.Distance(transform.position, pf.getDestination()) < Time.deltaTime * moveSpeed) { transform.position = pf.getDestination(); } else { transform.position = Vector3.MoveTowards(transform.position, pf.getDestination(), Time.deltaTime * moveSpeed); } UpdateafterMovePosition(); } } } else { Debug.LogError("No PathFinder Assigned! please assign component CorvopathFinder to this object.", gameObject); } } }
void OpenTheGatesOfHell(Player player, string cmd, string[] input) { if (!player.HasPermission("admin") && !player.HasPermission("mod")) { PrintToChat(player, string.Format(GetMessage("NoAdmin", player.Id.ToString()))); return; } string z = "villager"; string w = "werewolf"; if (input.IsNullOrEmpty()) { CreatureAmount = GetConfig("AMOUNT of creatures to spawn", 5); PrintToChat(player, string.Format(GetMessage("NoArgument", player.Id.ToString())), CreatureAmount.ToString()); } else { CreatureAmount = int.Parse(string.Concat(input)); } if (CreatureAmount > 20) { CreatureAmount = 20; PrintToChat(player, string.Format(GetMessage("TooMany", player.Id.ToString()))); } if (Werewolves && Zombies) { timer.Repeat(3f, (CreatureAmount / 2), () => { foreach (Player connectedplayer in Server.AllPlayersExcept(Server.GetPlayerFromString("Server"))) { Vector3 RandomPosition = Vector3Util.Randomize(connectedplayer.Entity.Position, -100, 100); Vector3 RandomToSurfacePosition = new Vector3(RandomPosition.x, TerrainAPIBase.GetTerrainHeightAt(RandomPosition), RandomPosition.z); SpawnSingleCreatureAroundEveryPlayer(RandomToSurfacePosition, connectedplayer, z); } }); timer.Repeat(3f, (CreatureAmount / 2), () => { foreach (Player connectedplayer in Server.AllPlayersExcept(Server.GetPlayerFromString("Server"))) { Vector3 RandomPosition = Vector3Util.Randomize(connectedplayer.Entity.Position, -100, 100); Vector3 RandomToSurfacePosition = new Vector3(RandomPosition.x, TerrainAPIBase.GetTerrainHeightAt(RandomPosition), RandomPosition.z); SpawnSingleCreatureAroundEveryPlayer(RandomToSurfacePosition, connectedplayer, w); } }); } else if (Zombies) { timer.Repeat(3f, (CreatureAmount), () => { foreach (Player connectedplayer in Server.AllPlayersExcept(Server.GetPlayerFromString("Server"))) { Vector3 RandomPosition = Vector3Util.Randomize(connectedplayer.Entity.Position, -100, 100); Vector3 RandomToSurfacePosition = new Vector3(RandomPosition.x, TerrainAPIBase.GetTerrainHeightAt(RandomPosition), RandomPosition.z); SpawnSingleCreatureAroundEveryPlayer(RandomToSurfacePosition, connectedplayer, z); } }); } else if (Werewolves) { timer.Repeat(3f, (CreatureAmount / 2), () => { foreach (Player connectedplayer in Server.AllPlayersExcept(Server.GetPlayerFromString("Server"))) { Vector3 RandomPosition = Vector3Util.Randomize(connectedplayer.Entity.Position, -100, 100); Vector3 RandomToSurfacePosition = new Vector3(RandomPosition.x, TerrainAPIBase.GetTerrainHeightAt(RandomPosition), RandomPosition.z); SpawnSingleCreatureAroundEveryPlayer(RandomToSurfacePosition, connectedplayer, w); } }); } else if (!Werewolves && !Zombies) { PrintToChat(player, string.Format(GetMessage("WrongConfig", player.Id.ToString()))); return; } }
void OnDrawGizmos() { //Dibujar el spawn de la pelota Gizmos.DrawSphere(Vector3Util.NoY(ballStartingPos) + Vector3.up * ballRadius, ballRadius); }
// Update is called once per frame private void Update() { if (_intervalTimer > 0) { _intervalTimer -= Time.deltaTime; return; } // Update the platform position if (_localTransform) { transform.localPosition = Vector3.Lerp(_positions[_currentPosition], _positions[_targetPosition], (_timer += Time.deltaTime) / _speedInSeconds); } else { transform.position = Vector3.Lerp(_positions[_currentPosition], _positions[_targetPosition], (_timer += Time.deltaTime) / _speedInSeconds); } // If we're approximately in the final position, change the indexes and restart the timer. if (Vector3Util.Approx((_localTransform ? transform.localPosition : transform.position), _positions[_targetPosition], 0.01f)) { switch (_loopMode) { case LoopModes.Circular: // Circular mode is simple, keep incrementing and user modulus to go back to start of the list when you hit the end. _currentPosition = (_currentPosition + 1) % _positions.Count; _targetPosition = (_targetPosition + 1) % _positions.Count; break; case LoopModes.Reverse: // Reverse mode needs to check if it's going (targetPosition > currentPosition) or coming back (currentPosition > targetPosition) // Then increment/decrement accordingly or change the direction if it hits the end/start of the list. if (_targetPosition > _currentPosition) { if (_targetPosition + 1 < _positions.Count) { _currentPosition++; _targetPosition++; } else { _currentPosition = _positions.Count - 1; _targetPosition = _positions.Count - 2; } } else { if (_targetPosition - 1 > -1) { _currentPosition--; _targetPosition--; } else { _currentPosition = 0; _targetPosition = 1; } } break; default: Debug.LogError("Invalid platform mode."); break; } _timer = 0; _intervalTimer = _movingInterval; } }
// Use this for initialization void Start() { rotAxis_ += Vector3Util.mul(Randoms.Vec3.valueCenter() * 2.0f, rotAxisRand_); }
protected override void OnGUIMain() { NavmeshBuild build = Context.Build; if (!build) { return; } Rect statusArea = Context.MainArea; if (build.BuildState == NavmeshBuildState.Invalid) { return; } InputBuildInfo info; InputGeometry geometry = null; ConnectionSet connections = null; int triCount = 0; int processorCount = 0; ViewOption viewFlags = 0; bool hasData = false; string topLabel; if (mCompiler != null) { if (mCompiler.IsFinished) { if (mCompiler.HasData) { topLabel = "Input successfully compiled. (Needs to be accepted.)"; } else { topLabel = "No input data produced."; } } else { topLabel = "Compiling"; } info = mCompiler.Info; geometry = mCompiler.Geometry; connections = mCompiler.Connections; triCount = mCompiler.TriCount; processorCount = (mCompiler.Processors == null ? 0 : mCompiler.Processors.Length); if (geometry != null) { hasData = true; } } else if (build.HasInputData) { topLabel = "Current Input"; viewFlags = (ViewOption.Input | ViewOption.Grid); info = build.InputInfo; geometry = build.InputGeom; connections = build.Connections; triCount = geometry.TriCount; processorCount = build.NMGenProcessors.Count; hasData = true; } else { topLabel = "Input needs to be compiled."; info = new InputBuildInfo(); } DebugContext.SetViews(viewFlags); if (!hasData && triCount > 0) { GUI.Box(Context.MainArea , string.Format("{0} {1:N0} triangles", topLabel, triCount) , EditorUtil.HelpStyle); OnGUICompiler(statusArea); return; } GUILayout.BeginArea(statusArea, GUI.skin.box); string currScene = System.IO.Path.GetFileName(EditorApplication.currentScene); int idx = currScene.LastIndexOf("."); if (idx >= 0) { currScene = currScene.Substring(0, idx); } if (currScene.Length == 0) { currScene = "None"; } GUILayout.BeginHorizontal(); GUILayout.Label("Input scene:"); GUILayout.Label(" Current: " + currScene); GUILayout.Label(" Last: " + NavEditorUtil.SceneDisplayName(build.BuildTarget.BuildInfo)); GUILayout.EndHorizontal(); if (NavEditorUtil.SceneMismatch(build.BuildTarget.BuildInfo)) { GUILayout.Box("Current scene does not match last input scene." , EditorUtil.WarningStyle); } GUILayout.Space(MarginSize); GUILayout.Label(topLabel); if (hasData) { GUILayout.Space(ControlUtil.MarginSize * 3); GUILayout.BeginHorizontal(); GUILayout.BeginVertical(); GUILayout.Label("Geometry"); GUILayout.Space(ControlUtil.MarginSize); GUILayout.Label(string.Format("Triangles: {0:N0}", triCount)); GUILayout.Space(ControlUtil.MarginSize); GUILayout.Label("Min Bounds: " + Vector3Util.ToString(geometry.BoundsMin)); GUILayout.Label("Max Bounds: " + Vector3Util.ToString(geometry.BoundsMax)); GUILayout.Space(ControlUtil.MarginSize); Vector3 diff = geometry.BoundsMax - geometry.BoundsMin; GUILayout.Label(string.Format("WxHxD: {0:f3} x {1:f3} x {2:f3}" , diff.x, diff.y, diff.z)); GUILayout.Space(ControlUtil.MarginSize * 2); // Note: The build press interprets zero root objects as a global search. GUILayout.Space(ControlUtil.MarginSize); GUILayout.Label("Components"); GUILayout.Space(ControlUtil.MarginSize); GUILayout.Label("Pre-filter: " + info.compCountPre); GUILayout.Label("Post-filter: " + info.compCountPost); GUILayout.EndVertical(); GUILayout.BeginVertical(); GUILayout.Label("Modifiers"); GUILayout.Space(ControlUtil.MarginSize); GUILayout.Label("Component loaders: " + info.loaderCount); GUILayout.Label("Component filters: " + info.filterCount); GUILayout.Label("Area assignment: " + info.areaModifierCount); GUILayout.Label("Component compilers: " + info.compilerCount); GUILayout.Label("Input post-processors: " + info.postCount); GUILayout.Label("NMGen processors: " + processorCount); GUILayout.Label("Off-Mesh connections: " + connections.Count); GUILayout.EndVertical(); GUILayout.EndHorizontal(); } GUILayout.EndArea(); OnGUICompiler(statusArea); }
/// <summary> /// Updates the planner. /// </summary> /// <returns>True on success.</returns> public bool Update() { // Detect position and goal changes, and constrain to navmesh. bool newPos = (agent.data.flags & NavFlag.HasNewPosition) != 0; bool newGoal = (agent.data.flags & NavFlag.HasNewGoal) != 0; NavmeshPoint pt; if (newPos) { pt = agent.GetPointSearch(agent.data.position); if (pt.polyRef == 0) { // Ignore new position. Debug.LogWarning(string.Format( "{0}: Could not constrain position to navigation mesh. Ignoring: {1}" , agent.transform.name, pt.ToString())); newPos = false; } else { agent.data.desiredPosition = pt; } } if (newGoal) { pt = agent.GetPointSearch(agent.data.goal); if (pt.polyRef == 0) { // Ignore new goal. Debug.LogWarning(string.Format( "{0}: Could not constrain goal to navigation mesh. Ignoring: {1}" , agent.transform.name, pt.ToString())); newGoal = false; } else { agent.data.plannerGoal = pt; } } agent.data.flags &= ~(NavFlag.HasNewPosition | NavFlag.HasNewGoal); // Handle planning. if (newGoal || newPos) { // Replanning needed. if (!HandlePlanning(newPos, newGoal)) { // Critical failure. return(false); } } // Is any movement needed? if (Vector3Util.SloppyEquals(agent.data.desiredPosition.point , agent.data.plannerGoal.point , NavAgent.ExactTolerance)) { // At goal. Don't need to do anything. mSpeed = 0; agent.data.desiredPosition = agent.data.plannerGoal; agent.data.desiredVelocity = Vector3.zero; agent.data.desiredSpeedSq = 0; return(true); } // Handle speed adjustments. float maxDelta = agent.crowdConfig.maxAcceleration * Time.deltaTime; float desiredSpeed = agent.crowdConfig.maxSpeed; // This shortcut test assumes the agent can halt in less than the // specified number of radii. if (Vector3Util.GetDistance2D(agent.data.desiredPosition.point , agent.data.plannerGoal.point) < agent.crowdConfig.radius * 3) { // Slow down to as low of 20% of maximum speed. desiredSpeed = Mathf.Max(mSpeed - maxDelta, desiredSpeed * 0.2f); } else { // Speed up to as high as maximum speed. desiredSpeed = Mathf.Min(mSpeed + maxDelta, desiredSpeed); } // Perform the move. if (--mOptimizationTimer < 1) { agent.corridor.OptimizePathTopology(true); mOptimizationTimer = OptimizationFrequency; } Vector3 movePos = Vector3.MoveTowards(agent.data.desiredPosition.point , agent.corridor.Corners.verts[0] , desiredSpeed * Time.deltaTime); agent.corridor.MovePosition(movePos); movePos = agent.corridor.Position.point; agent.data.desiredVelocity = (movePos - agent.data.desiredPosition.point).normalized * desiredSpeed; agent.data.desiredSpeedSq = desiredSpeed * desiredSpeed; agent.data.desiredPosition = agent.corridor.Position; mSpeed = desiredSpeed; return(true); }