////////////////////////////////////////////////////////////////////////// // FindPath public int FindPath(Vector3 startPosition, Vector3 endPosition, ref IAINode[] path) { IAINode startNode = GraphMaker.Instance.GetNearestNode(startPosition); IAINode endNode = GraphMaker.Instance.GetNearestNode(endPosition); return(FindPath(startNode, endNode, ref path)); }
public bool this[IAINode node] { get { if (node.IsNullOrDestroyed()) { return(true); } bool result; if (_table.TryGetValue(AITreeDebugWindow.GetNodeHash(node), out result)) { return(result); } return(true); } set { if (node.IsNullOrDestroyed()) { return; } _table[AITreeDebugWindow.GetNodeHash(node)] = value; } }
int IComparable <IAINode> .CompareTo(IAINode other) { IAINode node = (this as IAINode); int compare = node.fCost.CompareTo(other.fCost); if (compare == 0) { compare = node.Heuristic.CompareTo(other.Heuristic); } return(-compare); }
////////////////////////////////////////////////////////////////////////// // START ( Override ) protected override void Start() { base.Start(); m_Animator = GetComponent <Animator>(); m_AINode = GetComponentInChildren <IAINode>(); if (m_IsActivated == false) { m_AINode.IsWalkable = false; } }
private static int GetNodeHash(IAINode node) { if (node is Component) { return((node as Component).GetInstanceID()); } else { //TODO - need better method of doing this return(node.GetHashCode()); } }
////////////////////////////////////////////////////////////////////////// // START protected override void Start() { base.Start(); m_CurrentNode = AI.Pathfinding.GraphMaker.Instance.GetNearestNode(transform.position); float height = transform.position.y; transform.position = new Vector3(m_CurrentNode.Position.x, height, m_CurrentNode.Position.z); m_Movement = new Navigation(); m_Movement.Path = new IAINode[AI.Pathfinding.GraphMaker.Instance.NodeCount]; }
////////////////////////////////////////////////////////////////////////// // GetNearestNode public IAINode GetNearestNode(Vector3 position) { float currentDistance = float.MaxValue; IAINode result = null; foreach (IAINode node in m_Nodes) { float distance = (node.Position - position).sqrMagnitude; if (distance < currentDistance * currentDistance) { currentDistance = distance; result = node; } } return(result); }
////////////////////////////////////////////////////////////////////////// // Move public void Move(Interactable interactable, bool checkOverride = false) { if (m_InputWaitCO != null && checkOverride == false) { return; } if (m_InputWaitCO != null) { StopCoroutine(m_InputWaitCO); } StartCoroutine(m_InputWaitCO = WaitForNextInput()); IAINode startNode = AI.Pathfinding.GraphMaker.Instance.GetNearestNode(transform.position); IAINode endNode = AI.Pathfinding.GraphMaker.Instance.GetNearestNode(interactable.transform.position); m_Movement.PathLength = AI.Pathfinding.AStarSearch.Instance.FindPath(startNode, endNode, ref m_Movement.Path); if (m_Movement.PathLength == 0) { return; } if (interactable is Lever || interactable is Openable) { m_Movement.PathLength--; if (m_Movement.PathLength == 1 && m_Movement.Path[m_Movement.PathLength - 1] == null) { CheckForUsage(interactable); return; } } m_Movement.Reset(); m_Movement.HasPath = true; m_Movement.PrevPosition = transform.position; m_Movement.NodeIdx = 0; m_Movement.NextNodeDistance = (m_Movement.Path[0].Position - transform.position).sqrMagnitude; m_Movement.Action = delegate { CheckForUsage(interactable); }; m_Movement.Interactable = interactable; m_MovementStartPosition = transform.position; }
////////////////////////////////////////////////////////////////////////// // FindPath private int RetracePath(IAINode startNode, IAINode endNode, ref IAINode[] path) { int currentNodeCount = 0; IAINode currentNode = endNode; while (currentNode.Equals(startNode) == false) { path[currentNodeCount] = currentNode; currentNode = currentNode.Parent; currentNodeCount++; } path[currentNodeCount] = currentNode; currentNodeCount++; // sw.Stop(); // print( "Node count: " + currentNodeCount + ", path found in " + sw.ElapsedMilliseconds + "ms" ); GraphMaker.Instance.ResetNodes(); m_OpenSet.Reset(); return(currentNodeCount); }
////////////////////////////////////////////////////////////////////////// // GetBestNode private IAINode GetBestNode(IEnumerable set, bool useHeuristic) { IAINode bestNode = null; float bestTotal = float.MaxValue; foreach (IAINode n in set) { if (n.IsWalkable == false) { continue; } float totalCost = useHeuristic ? n.gCost + n.Heuristic : n.gCost; if (totalCost < bestTotal) { bestTotal = totalCost; bestNode = n; } } return(bestNode); }
private void DrawPopup(IAINode node) { }
private void DrawNode(IAINode node) { var rect = EditorGUILayout.GetControlRect(); bool hasChildren = (node is IAIActionGroup || node is IAIStateMachine); //first click region if (MouseUtil.GuiClicked(Event.current, MouseUtil.BTN_LEFT, rect)) { _currentSelectionId = AITreeDebugWindow.GetNodeHash(node); if (node is Component) { Selection.activeGameObject = (node as Component).gameObject; EditorGUIUtility.PingObject(node as Component); } this.Repaint(); } else if (MouseUtil.GuiClicked(Event.current, MouseUtil.BTN_RIGHT, rect)) { this.DrawPopup(node); } //draw selection rect if (_currentSelectionId == AITreeDebugWindow.GetNodeHash(node)) { EditorGUI.DrawRect(rect, _selectedColor); } //draw label if (hasChildren) { _currentTable[node] = EditorGUI.Foldout(rect, _currentTable[node], node.DisplayName); } else { EditorGUI.LabelField(rect, node.DisplayName); } //highlight if running if (node is IAIAction) { var act = node as IAIAction; switch (act.ActionState) { case ActionResult.Waiting: EditorGUI.DrawRect(rect, _waitingColor); break; case ActionResult.Success: EditorGUI.DrawRect(rect, _successColor); break; case ActionResult.Failed: EditorGUI.DrawRect(rect, _failedColor); break; } } else if (node is IAIState) { var state = node as IAIState; if (state.IsActive) { EditorGUI.DrawRect(rect, _activeStateColor); } } if (hasChildren && _currentTable[node]) { EditorGUI.indentLevel++; if (node is IAIActionGroup) { foreach (var child in (node as IAIActionGroup)) { this.DrawNode(child); } } else if (node is IAIStateMachine) { foreach (var child in (node as IAIStateMachine)) { this.DrawNode(child); } } EditorGUI.indentLevel--; } }
public abstract void addNode(IAINode node);
////////////////////////////////////////////////////////////////////////// // FindPath public int FindPath(IAINode startNode, IAINode endNode, ref IAINode[] path) { if (GraphMaker.Instance.NodeCount == 0) { print("AStarSearch::FindPath:Node graph has to be build !!"); return(0); } if (endNode.IsWalkable == false) { return(0); } endNode.gCost = 0; endNode.Heuristic = (endNode.Position - startNode.Position).sqrMagnitude; // First node is always discovered m_OpenSet.Add(endNode); // sw.Reset(); // sw.Start(); // Start scan while (m_OpenSet.Count > 0) { IAINode currentNode = m_OpenSet.RemoveFirst(); if (currentNode.ID == startNode.ID) { // Debug.Log("We found the end node!"); return(RetracePath(endNode, startNode, ref path)); } // if ( currentNode == null ) return null; currentNode.Visited = true; // Setup its neighbours for (int i = 0; i < currentNode.Neighbours.Length; i++) { IAINode iNeighbour = currentNode.Neighbours[i]; if (iNeighbour == null) { print("node " + (currentNode as AINode).name + " has neighbour as null "); return(0); } // Ignore the neighbour which is already evaluated. if (iNeighbour.IsWalkable == false || iNeighbour.Visited == true) { continue; } float gCost = currentNode.gCost + (currentNode.Position - iNeighbour.Position).sqrMagnitude; bool containsNehigbour = m_OpenSet.Contains(iNeighbour); if (gCost < iNeighbour.gCost || containsNehigbour == false) { iNeighbour.gCost = gCost; iNeighbour.Heuristic = (iNeighbour.Position - startNode.Position).sqrMagnitude; iNeighbour.Parent = currentNode; if (containsNehigbour == false) { m_OpenSet.Add(iNeighbour); m_PathNodeCount++; } } } } // no path found return(0); }
bool IEquatable <IAINode> .Equals(IAINode other) { return(m_ID == other.ID); }
////////////////////////////////////////////////////////////////////////// // UpdaeNeighbours private void UpdateNeighbours(IAINode iNode, bool isUpdate) { IGrapMakerEditor graphInterface = ( IGrapMakerEditor )target; if (iNode is IAINodeLinker) { return; } // UPDATE PREVIOUS NEIGHBOURS if (isUpdate == true) { // update previous neighbours foreach (IAINode neigh in iNode.Neighbours) { UpdateNeighbours(neigh, false); } } // Get neighbours by distance IAINode[] neighbours = System.Array.FindAll ( graphInterface.Nodes, n => (n.transform.position - iNode.Position).sqrMagnitude <= graphInterface.ScanRadius * graphInterface.ScanRadius && (AINode)n != (AINode)iNode ); // create temporary array of neighbours and copy neighbours found bool hasLinker = iNode.Linker != null; AINode[] nodeNeighbours = new AINode[neighbours.Length + (hasLinker ? 1 : 0)]; System.Array.Copy(neighbours, nodeNeighbours, neighbours.Length); // LINKER ASSIGNMENT if (hasLinker) { // add linker to this node nodeNeighbours[nodeNeighbours.Length - 1] = iNode.Linker as AINode; IAINode ILinker = iNode.Linker; // resize Neighbours array var tmpNeighbours = ILinker.Neighbours; System.Array.Resize(ref tmpNeighbours, (ILinker.Neighbours != null) ? ILinker.Neighbours.Length + 1 : 1); // add this node to linker tmpNeighbours[tmpNeighbours.Length - 1] = iNode as AINode; ILinker.Neighbours = tmpNeighbours; } iNode.Neighbours = nodeNeighbours; // UPDATE CURRENT NEIGHBOURS if (isUpdate == true) { // update previous neighbours foreach (IAINode neigh in iNode.Neighbours) { UpdateNeighbours(neigh, false); } } }
public void addNode(IAINode node) { }