public NNInfo GetNearest(Vector3 position, NNConstraint constraint, GraphNode hint) { NavGraph[] graphs = this.graphs; float num = float.PositiveInfinity; NNInfoInternal internalInfo = default(NNInfoInternal); int num2 = -1; if (graphs != null) { for (int i = 0; i < graphs.Length; i++) { NavGraph navGraph = graphs[i]; if (navGraph != null && constraint.SuitableGraph(i, navGraph)) { NNInfoInternal nninfoInternal; if (this.fullGetNearestSearch) { nninfoInternal = navGraph.GetNearestForce(position, constraint); } else { nninfoInternal = navGraph.GetNearest(position, constraint); } if (nninfoInternal.node != null) { float magnitude = (nninfoInternal.clampedPosition - position).magnitude; if (this.prioritizeGraphs && magnitude < this.prioritizeGraphsLimit) { internalInfo = nninfoInternal; num2 = i; break; } if (magnitude < num) { num = magnitude; internalInfo = nninfoInternal; num2 = i; } } } } } if (num2 == -1) { return(default(NNInfo)); } if (internalInfo.constrainedNode != null) { internalInfo.node = internalInfo.constrainedNode; internalInfo.clampedPosition = internalInfo.constClampedPosition; } if (!this.fullGetNearestSearch && internalInfo.node != null && !constraint.Suitable(internalInfo.node)) { NNInfoInternal nearestForce = graphs[num2].GetNearestForce(position, constraint); if (nearestForce.node != null) { internalInfo = nearestForce; } } if (!constraint.Suitable(internalInfo.node) || (constraint.constrainDistance && (internalInfo.clampedPosition - position).sqrMagnitude > this.maxNearestNodeDistanceSqr)) { return(default(NNInfo)); } return(new NNInfo(internalInfo)); }
/** * Returns the nearest node to a position using the specified \link Pathfinding.NNConstraint constraint \endlink. * \returns an NNInfo. This method will only return an empty NNInfo if there are no nodes which comply with the specified constraint. */ public virtual NNInfoInternal GetNearestForce(Vector3 position, NNConstraint constraint) { return(GetNearest(position, constraint)); }
public NNInfo GetNearest(Vector3 position, NNConstraint constraint) { return(this.GetNearest(position, constraint, null)); }
void Awake() { _constraint = NNConstraint.None; _constraint.constrainWalkability = true; _constraint.walkable = true; }
/** Returns the nearest node to a position using the specified NNConstraint. * \param position The position to try to find a close node to * \param constraint Can for example tell the function to try to return a walkable node. If you do not get a good node back, consider calling GetNearestForce. */ public NNInfoInternal GetNearest(Vector3 position, NNConstraint constraint) { return(GetNearest(position, constraint, null)); }
public NNInfo GetNearest(Vector3 position, NNConstraint constraint, GraphNode hint) { // Cache property lookup var graphs = this.graphs; float minDist = float.PositiveInfinity; NNInfoInternal nearestNode = new NNInfoInternal(); int nearestGraph = -1; if (graphs != null) { for (int i = 0; i < graphs.Length; i++) { NavGraph graph = graphs[i]; // Check if this graph should be searched if (graph == null || !constraint.SuitableGraph(i, graph)) { continue; } NNInfoInternal nnInfo; if (fullGetNearestSearch) { // Slower nearest node search // this will try to find a node which is suitable according to the constraint nnInfo = graph.GetNearestForce(position, constraint); } else { // Fast nearest node search // just find a node close to the position without using the constraint that much // (unless that comes essentially 'for free') nnInfo = graph.GetNearest(position, constraint); } GraphNode node = nnInfo.node; // No node found in this graph if (node == null) { continue; } // Distance to the closest point on the node from the requested position float dist = ((Vector3)nnInfo.clampedPosition - position).magnitude; if (prioritizeGraphs && dist < prioritizeGraphsLimit) { // The node is close enough, choose this graph and discard all others minDist = dist; nearestNode = nnInfo; nearestGraph = i; break; } else { // Choose the best node found so far if (dist < minDist) { minDist = dist; nearestNode = nnInfo; nearestGraph = i; } } } } // No matches found if (nearestGraph == -1) { return(new NNInfo()); } // Check if a constrained node has already been set if (nearestNode.constrainedNode != null) { nearestNode.node = nearestNode.constrainedNode; nearestNode.clampedPosition = nearestNode.constClampedPosition; } if (!fullGetNearestSearch && nearestNode.node != null && !constraint.Suitable(nearestNode.node)) { // Otherwise, perform a check to force the graphs to check for a suitable node NNInfoInternal nnInfo = graphs[nearestGraph].GetNearestForce(position, constraint); if (nnInfo.node != null) { nearestNode = nnInfo; } } if (!constraint.Suitable(nearestNode.node) || (constraint.constrainDistance && (nearestNode.clampedPosition - position).sqrMagnitude > maxNearestNodeDistanceSqr)) { return(new NNInfo()); } // Convert to NNInfo which doesn't have all the internal fields return(new NNInfo(nearestNode)); }
public void DoStuff() { var go = gameObject.OwnerOption == OwnerDefaultOption.UseOwner ? Owner : gameObject.GameObject.Value; g.root = go.transform; // set the root so the scan will turn it into nodes g.maxDistance = -1; // no autoconnect g.initialPenalty = (uint)cost.Value; g.name = name.Value; AstarPathExtensions.ScanGraph(g); // turn the gameObjects into ndoes. if (width.Value <= 1) { for (var i = 1; i < g.nodes.Length; i++) { // connect the node with the previously created node g.nodes[i].AddConnection(g.nodes[i - 1], cost.Value); g.nodes[i - 1].AddConnection(g.nodes[i], cost.Value); } if (connectStart.Value || connectEnd.Value) { // You would want to use an NNConstraint to ignore this graph when searching (graphMask) // Since it currently will find g.nodes[0] when searching nnc = NNConstraint.Default; var nncSave = nnc.graphMask; var index = AstarPath.active.astarData.GetGraphIndex(g); nnc.graphMask = ~(1 << index); if (connectStart.Value) { connectEm(0); } if (connectEnd.Value) { connectEm(g.nodes.Length - 1); } nnc.graphMask = nncSave; } } else { for (var i = 0; i < g.nodes.Length; i++) { // connect the node with the previously created node //g.nodes[i].AddConnection(g.nodes[i-1], cost.Value); //g.nodes[i-1].AddConnection(g.nodes[i], cost.Value); //if(i + width.Value <= g.nodes.Length) //{ //connect the node with the next node in line //g.nodes[i-1].AddConnection(g.nodes[i-1+width.Value], cost.Value); //g.nodes[i-1+width.Value].AddConnection(g.nodes[i-1], cost.Value); //} // there are 3 scenarios: Either a node is in the middle or at either of the ends of the row. if (i % width.Value == width.Value - 1) //2 { if (i + width.Value < g.nodes.Length) { g.nodes[i].AddConnection(g.nodes[i + width.Value], cost.Value); g.nodes[i + width.Value].AddConnection(g.nodes[i], cost.Value); } if (i + width.Value - 1 < g.nodes.Length) { g.nodes[i].AddConnection(g.nodes[i + width.Value - 1], cost.Value); g.nodes[i + width.Value - 1].AddConnection(g.nodes[i], cost.Value); } } else if (i == 0 || 0 == i % width.Value) //1 // if i is 0 or a multiple of width { if (i + width.Value < g.nodes.Length) { g.nodes[i].AddConnection(g.nodes[i + width.Value], cost.Value); g.nodes[i + width.Value].AddConnection(g.nodes[i], cost.Value); } if (i + 1 < g.nodes.Length) { g.nodes[i].AddConnection(g.nodes[i + 1], cost.Value); g.nodes[i + 1].AddConnection(g.nodes[i], cost.Value); } if (i + width.Value + 1 < g.nodes.Length) { g.nodes[i].AddConnection(g.nodes[i + width.Value + 1], cost.Value); g.nodes[i + width.Value + 1].AddConnection(g.nodes[i], cost.Value); } } else //3 { if (i + width.Value < g.nodes.Length) { g.nodes[i].AddConnection(g.nodes[i + width.Value], cost.Value); g.nodes[i + width.Value].AddConnection(g.nodes[i], cost.Value); } if (i + 1 < g.nodes.Length) { g.nodes[i].AddConnection(g.nodes[i + 1], cost.Value); g.nodes[i + 1].AddConnection(g.nodes[i], cost.Value); } if (i + width.Value + 1 < g.nodes.Length) { g.nodes[i].AddConnection(g.nodes[i + width.Value + 1], cost.Value); g.nodes[i + width.Value + 1].AddConnection(g.nodes[i], cost.Value); } if (i + width.Value - 1 < g.nodes.Length) { g.nodes[i].AddConnection(g.nodes[i + width.Value - 1], cost.Value); g.nodes[i + width.Value - 1].AddConnection(g.nodes[i], cost.Value); } } } if (connectStart.Value || connectEnd.Value) { // You would want to use an NNConstraint to ignore this graph when searching (graphMask) // Since it currently will find g.nodes[0] when searching nnc = NNConstraint.Default; var nncSave = nnc.graphMask; var index = AstarPath.active.astarData.GetGraphIndex(g); nnc.graphMask = ~(1 << index); if (connectStart.Value) { connectEm(0); } if (connectEnd.Value) { connectEm(g.nodes.Length - width.Value); } nnc.graphMask = nncSave; } } Nodes.Value = FsmConverter.SetNodes(FsmConverter.NodeListToArray(g.nodes)); //Required since the graph connections have been updated AstarPath.active.FloodFill(); //g.AddChildren(Count, go.transform); return; }
public void OnPathComplete(Path p) { if (!p.error) { if (this.path != null) { this.path.Release(this); } this.path = p; this.path.Claim(this); if (this.groundNode != null && this.groundNode.Walkable && !this.setup.search.fsmInCave.Value && !this.creepy && !this.creepy_baby && !this.creepy_male && !this.creepy_fat) { GraphNode node = AstarPath.active.GetNearest(this.tr.position, NNConstraint.Default).node; if (node != null) { uint area = node.Area; NNConstraint nNConstraint = new NNConstraint(); nNConstraint.constrainArea = true; int area2 = (int)area; nNConstraint.area = area2; GraphNode node2 = AstarPath.active.GetNearest(this.target.position, nNConstraint).node; Vector3 vector = new Vector3((float)(node2.position[0] / 1000), (float)(node2.position[1] / 1000), (float)(node2.position[2] / 1000)); if (Vector3.Distance(vector, this.target.position) > 10f) { this.setup.search.updateCurrentWaypoint(vector); this.setup.search.setToWaypoint(); if (this.target.gameObject.CompareTag("Player") || this.target.gameObject.CompareTag("PlayerNet")) { if (this.setup.pmBrain) { this.setup.pmBrain.SendEvent("toSetPassive"); } } else { if (this.setup.pmBrain) { this.setup.pmBrain.SendEvent("toSetAggressive"); } if (this.setup.pmCombat) { this.setup.pmCombat.FsmVariables.GetFsmBool("fsmInsideBase").Value = true; } this.insideBase = true; base.Invoke("resetInsideBase", 25f); } if (this.setup.pmSearch) { this.setup.pmSearch.SendEvent("noValidPath"); } if (this.setup.pmStalk) { this.setup.pmStalk.SendEvent("noValidPath"); } if (this.setup.pmCombat) { this.setup.pmCombat.SendEvent("noValidPath"); } if (this.setup.pmEncounter) { this.setup.pmEncounter.SendEvent("noValidPath"); } } } } if (this.setup.pmSearch) { this.setup.pmSearch.SendEvent("validPath"); } if (this.setup.pmStalk) { this.setup.pmStalk.SendEvent("validPath"); } if (this.setup.pmCombat) { this.setup.pmCombat.SendEvent("validPath"); } if (this.setup.pmEncounter) { this.setup.pmEncounter.SendEvent("validPath"); } this.currentWaypoint = 1; return; } if (this.setup.pmSearch) { this.setup.pmSearch.SendEvent("noValidPath"); } if (this.setup.pmStalk) { this.setup.pmStalk.SendEvent("noValidPath"); } if (this.setup.pmCombat) { this.setup.pmCombat.SendEvent("noValidPath"); } if (this.setup.pmEncounter) { this.setup.pmEncounter.SendEvent("noValidPath"); } }
public void OnPathComplete(Path p) { if (!p.error) { if (this.path != null) { this.path.Release(this, false); } this.path = p; this.path.Claim(this); if (this.groundNode != null && this.target != null && this.groundNode.Walkable && !this.setup.search.fsmInCave.Value && !this.creepy && !this.creepy_baby && !this.creepy_male && !this.creepy_fat) { uint area = this.groundNode.Area; NNConstraint nnconstraint = new NNConstraint(); nnconstraint.constrainArea = true; int area2 = (int)area; nnconstraint.area = area2; this.targetNode = this.rg.GetNearest(this.target.position, NNConstraint.Default).node; bool flag = false; targetStats targetStats = null; if (this.target.gameObject.CompareTag("Player") || this.target.gameObject.CompareTag("PlayerNet")) { targetStats = this.target.GetComponent <targetStats>(); if (targetStats.inWater || targetStats.onRaft) { flag = true; } } if (this.targetNode != null || flag) { if (flag) { GraphNode node = this.rg.GetNearest(this.target.position, nnconstraint).node; Vector3 position = this.target.position; if (node == null) { node = this.groundNode; } this.lastPlayerTarget = this.target; position = new Vector3((float)(node.position[0] / 1000), (float)(node.position[1] / 1000), (float)(node.position[2] / 1000)); this.setup.search.updateCurrentWaypoint(position); this.setup.search.setToWaypoint(); if (this.setup.pmCombat) { this.setup.pmCombat.SendEvent("noValidPath"); } if (this.setup.pmEncounter) { this.setup.pmEncounter.SendEvent("noValidPath"); } if (this.setup.pmSearchScript) { this.setup.pmSearchScript._validPath = false; } if (this.setup.pmCombat) { this.setup.pmCombat.FsmVariables.GetFsmBool("playerWasOffNav").Value = true; } } else if (this.targetNode.Area != this.groundNode.Area) { GraphNode node2 = this.rg.GetNearest(this.target.position, nnconstraint).node; Vector3 position2 = this.target.position; if (node2 != null) { position2 = new Vector3((float)(node2.position[0] / 1000), (float)(node2.position[1] / 1000), (float)(node2.position[2] / 1000)); } float num = this.target.position.y - position2.y; if (!this.target.gameObject.CompareTag("Player") && !this.target.gameObject.CompareTag("PlayerNet")) { this.setup.search.updateCurrentWaypoint(base.transform.position); } if (Vector3.Distance(position2, this.target.position) > 10f) { if (this.target.gameObject.CompareTag("Player") || (this.target.gameObject.CompareTag("PlayerNet") && num > 2f)) { if (!targetStats || targetStats.onStructure) { } if (!this.climbingWallCooDown && !this.doneClimbCoolDown && !this.setup.hitReactions.onStructure) { base.StartCoroutine(this.findCloseClimbingWall(this.target, this.targetNode)); this.lastPlayerTarget = this.target; this.climbingWallCooDown = true; } if (this.setup.pmBrain && !this.doingClimbWall) { this.setup.pmBrain.SendEvent("toSetPassive"); } } this.setup.search.updateCurrentWaypoint(position2); if (!this.setup.hitReactions.onStructure && !this.fsmOnWallBool.Value) { if (this.setup.pmCombat) { this.setup.pmCombat.SendEvent("noValidPath"); } if (this.setup.pmEncounter) { this.setup.pmEncounter.SendEvent("noValidPath"); } if (this.setup.pmSearchScript) { this.setup.pmSearchScript._validPath = false; } } } } if (this.target.gameObject.CompareTag("Player") || this.target.gameObject.CompareTag("PlayerNet")) { if (this.setup.hitReactions.onStructure && this.thisTr.position.y - this.target.position.y > 3f) { if (this.setup.pmCombat) { this.setup.pmCombat.FsmVariables.GetFsmBool("attackBelowBool").Value = true; } } else if (this.setup.pmCombat) { this.setup.pmCombat.FsmVariables.GetFsmBool("attackBelowBool").Value = false; } } } } if (this.setup.pmCombat) { this.setup.pmCombat.SendEvent("validPath"); } if (this.setup.pmEncounter) { this.setup.pmEncounter.SendEvent("validPath"); } if (this.setup.pmSearchScript) { this.setup.pmSearchScript._validPath = true; } this.currentWaypoint = 1; return; } if (this.setup.pmCombat) { this.setup.pmCombat.SendEvent("noValidPath"); } if (this.setup.pmEncounter) { this.setup.pmEncounter.SendEvent("noValidPath"); } if (this.setup.pmSearchScript) { this.setup.pmSearchScript._validPath = false; } }
private IEnumerator findCloseClimbingWall(Transform getTarget, GraphNode targetNode) { bool foundValidWall = false; int randVal = UnityEngine.Random.Range(0, Scene.SceneTracker.climbableStructures.Count); for (int i = 0; i < Scene.SceneTracker.climbableStructures.Count; i++) { if (randVal == Scene.SceneTracker.climbableStructures.Count) { randVal = 0; } if (!foundValidWall && getTarget && Scene.SceneTracker.climbableStructures[randVal] != null) { Vector3 position = getTarget.position; position.y = this.thisTr.position.y; Vector3 position2 = Scene.SceneTracker.climbableStructures[randVal].transform.position; position2.y = this.thisTr.position.y; Vector3 vector = position - position2; Vector3 from = this.thisTr.position - position2; Vector3 to = this.thisTr.position - position; float num = Vector3.Angle(from, to); float sqrMagnitude = vector.sqrMagnitude; float sqrMagnitude2 = from.sqrMagnitude; float sqrMagnitude3 = to.sqrMagnitude; if (sqrMagnitude < sqrMagnitude3 && sqrMagnitude < 2500f && sqrMagnitude2 > 225f && num < 70f) { Vector3 position3 = Scene.SceneTracker.climbableStructures[randVal].transform.position; position3.y = getTarget.position.y; uint area = targetNode.Area; NNConstraint nnconstraint = new NNConstraint(); nnconstraint.constrainArea = true; int area2 = (int)area; nnconstraint.area = area2; bool flag = false; GraphNode node = this.rg.GetNearest(position3, nnconstraint).node; if (node != null) { Vector3 b = new Vector3((float)(node.position[0] / 1000), (float)(node.position[1] / 1000), (float)(node.position[2] / 1000)); if (Vector3.Distance(position3, b) < 8f) { flag = true; } } climbableWallSetup component = Scene.SceneTracker.climbableStructures[randVal].GetComponent <climbableWallSetup>(); if (component && !component.occupied && !component.invalid && flag) { this.setup.pmCombat.FsmVariables.GetFsmGameObject("wallGo").Value = Scene.SceneTracker.climbableStructures[randVal]; this.setup.pmCombatScript.wallGo = Scene.SceneTracker.climbableStructures[randVal]; this.setup.pmCombat.FsmVariables.GetFsmBool("toClimbWall").Value = true; foundValidWall = true; if (component) { component.occupied = true; } } } } randVal++; yield return(null); } yield return(YieldPresets.WaitTenSeconds); this.climbingWallCooDown = false; yield break; }