void Update() { #if UNITY_EDITOR // For hit testing in Unity editor simulation if (Input.GetMouseButtonDown(0)) { MDSNode node = TouchedEPNode(Input.mousePosition); if (node != null) { node.OnTouch(); } } #else // For hit testing on device if (Input.touchCount > 0) { Touch touch = Input.GetTouch(0); if (touch.phase == TouchPhase.Ended) { MDSNode node = TouchedEPNode(touch.position); if (node != null) { node.OnTouch(); } } } #endif }
/// <summary> /// Adds a node into the scene /// </summary> public void AddNode(NodeInfo nodeInfo) { MDSNode newNode = m_WPNodePrefab; MDSNodeType nodeType = (MDSNodeType)nodeInfo.nodeType; if (nodeType == MDSNodeType.WAYPOINT) { newNode = Instantiate(m_WPNodePrefab); } else { newNode = Instantiate(m_EPNodePrefab); m_TargetNode = newNode; } newNode.NodeInfo = nodeInfo; newNode.transform.position = new Vector3(nodeInfo.px, nodeInfo.py, nodeInfo.pz); if (newNode.nameInputBehaviour != null) { if (MainController.Instance._mode == Mode.EDITOR_MODE) { newNode.nameInputBehaviour.SetInputText(nodeInfo.name); } else { newNode.nameInputBehaviour.gameObject.SetActive(false); } } if (newNode.answerInputBehaviour != null) { if (MainController.Instance._mode == Mode.EDITOR_MODE) { newNode.answerInputBehaviour.SetInputText(nodeInfo.answer); } else { newNode.answerInputBehaviour.gameObject.SetActive(false); } } m_NodeObjList.Add(newNode); if (nodeType == MDSNodeType.ENDPOINT) { m_TargetNodeObjList.Add(newNode); // Add one to number of puzzles if (MainController.Instance._mode == Mode.PLAY_MODE) { MainController.Instance.GetGUIController().puzzlePanel.NumOfPuzzles += 1; } } }
/// <summary> /// Helper method that sets the target node from the targetNodeObjList using an int /// </summary> public void SetTargetNode(int targetIndex) { m_TargetNode = m_TargetNodeObjList[targetIndex]; // Callback foreach (INodeListener listener in m_NodeListenersList) { listener.OnTargetNodeChanged(m_TargetNode); } }
/// <summary> /// Helper method that sets the passed nodes puzzle answer /// </summary> public void SetNodeAnswer(MDSNode node, string answer) { if (answer == "") { MainController.Instance.GetSaveAndLoadController().notificationText.text = "Please enter a value greater than 0!"; return; } node.NodeInfo.answer = answer; }
/// <summary> /// Helper function that sets the passed nodes name /// </summary> public void SetNodeName(MDSNode node, string name) { if (name.Length <= 0) { MainController.Instance.GetSaveAndLoadController().notificationText.text = "Please enter something in the text field!"; return; } node.NodeInfo.name = name; }
/// <summary> /// AStar algorithm method that finds a path using start node, target node, and all nodes. /// Returns a list of nodes /// </summary> public List <MDSNode> FindPath(MDSNode startNode, MDSNode targetNode, List <MDSNode> allNodes) { List <MDSNode> openSet = new List <MDSNode>(); List <MDSNode> closedSet = new List <MDSNode>(); openSet.Add(startNode); while (openSet.Count > 0) { MDSNode currentNode = openSet[0]; for (int i = 1; i < openSet.Count; i++) { if (openSet[i].FCost < currentNode.FCost || (openSet[i].FCost == currentNode.FCost && openSet[i].HCost < currentNode.HCost)) { currentNode = openSet[i]; } } openSet.Remove(currentNode); closedSet.Add(currentNode); if (currentNode == targetNode) { Debug.Log("Returning the correct node"); return(RetracePath(startNode, targetNode)); } foreach (MDSNode connection in currentNode.neighbors) { if (!closedSet.Contains(connection)) { float costToConnection = currentNode.GCost + GetEstimate(currentNode, connection) + connection.Cost; if (costToConnection < connection.GCost || !openSet.Contains(connection)) { connection.GCost = costToConnection; connection.HCost = GetEstimate(connection, targetNode); connection.Parent = currentNode; if (!openSet.Contains(connection)) { openSet.Add(connection); } } } } } return(null); }
public void StartNavigation() { if (m_InitStatus == NavInitStatus.INCOMPLETE) { Debug.Log("Starting Navigation!"); List <MDSNode> allNodes = MainController.Instance.GetNodeController().NodeObjList; Debug.Log("Nodes: " + allNodes.Count); MDSNode closestNode = ReturnClosestNode(allNodes, _referencePoint.position); Debug.Log("Closest node: " + closestNode.gameObject.name); MDSNode targetNode = MainController.Instance.GetNodeController().TargetNode; Debug.Log("Target node: " + targetNode.NodeInfo.name); // Set neighbor nodes for all nodes foreach (MDSNode node in allNodes) { node.FindNeighbors(maxDistance); } // Get path from AStar algorithm path = m_AStar.FindPath(closestNode, targetNode, allNodes); if (path == null) { // Increase search distance for neighbors if none are found maxDistance += .1f; Debug.Log("Increasing search distance to: " + maxDistance); StartNavigation(); return; } // Set next nodes for (int i = 0; i < path.Count - 1; i++) { path[i].NextInList = path[i + 1]; } // Activate the first node path[0].Activate(); m_InitStatus = NavInitStatus.COMPLETED; } }
/// <summary> /// Method that back tracks from the end node, and creates a path to the start node /// </summary> private List <MDSNode> RetracePath(MDSNode startNode, MDSNode endNode) { List <MDSNode> path = new List <MDSNode>(); MDSNode currentNode = endNode; while (currentNode != startNode) { path.Add(currentNode); currentNode = currentNode.Parent; } path.Reverse(); return(path); }
/// <summary> /// Clears the passed node object from memory /// </summary> public void ClearNode(MDSNode node) { if (node == null) { Debug.Log("Cannot clear node as node is null"); return; } m_NodeObjList.Remove(node); if ((MDSNodeType)node.NodeInfo.nodeType == MDSNodeType.ENDPOINT) { m_TargetNodeObjList.Remove(node); } Destroy(node.gameObject); }
private float GetEstimate(MDSNode first, MDSNode second) { float distance; float xDistance = Mathf.Abs(first.transform.position.x - first.transform.position.x); float yDistance = Mathf.Abs(second.transform.position.z - second.transform.position.z); if (xDistance > yDistance) { distance = 14 * yDistance + 10 * (xDistance - yDistance); } else { distance = 14 * xDistance + 10 * (yDistance - xDistance); } return(distance); }
public MDSNode ReturnClosestNode(List <MDSNode> nodes, Vector3 point) { float minDist = Mathf.Infinity; MDSNode closestNode = null; foreach (MDSNode node in nodes) { float dist = Vector3.Distance(node.transform.position, point); if (dist < minDist) { closestNode = node; minDist = dist; } } return(closestNode); }
public void OnTrigger(Collider other) { if (m_InitStatus == NavInitStatus.COMPLETED && other.GetComponent <MDSNode>() != null) { currentNode = other.GetComponent <MDSNode>(); if (path.Contains(currentNode)) { if (currentNode.NextInList != null) { // Activate the next node currentNode.NextInList.Activate(); } // Deactivate the current node // currentNode.Deactivate(); } } }
/// <summary> /// Adds a deactivated node into the scene public void AddDeactiveNode(NodeInfo nodeInfo) { MDSNode newNode = m_WPNodePrefab; MDSNodeType nodeType = (MDSNodeType)nodeInfo.nodeType; // Cast stored node type from int to MDSNodeType if (nodeType == MDSNodeType.WAYPOINT) { newNode = Instantiate(m_WPNodePrefab); } else { newNode = Instantiate(m_EPNodePrefab); m_TargetNode = newNode; } newNode.Deactivate(); newNode.NodeInfo = nodeInfo; newNode.transform.position = new Vector3(nodeInfo.px, nodeInfo.py, nodeInfo.pz); if (newNode.nameInputBehaviour != null) { newNode.nameInputBehaviour.SetInputText(nodeInfo.name); } if (newNode.answerInputBehaviour != null) { newNode.answerInputBehaviour.SetInputText(nodeInfo.answer.ToString()); } m_NodeObjList.Add(newNode); if (nodeType == MDSNodeType.ENDPOINT) { m_TargetNodeObjList.Add(newNode); } }
/// <summary> /// Helper method that determines whether an EP node has been tapped on, and returns that node /// </summary> public MDSNode TouchedEPNode(Vector3 touchPos) { RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(touchPos); if (Physics.Raycast(ray, out hit)) { Collider[] colliders = Physics.OverlapSphere(hit.point, 2.0f); for (int i = 0; i < colliders.Length; i++) { MDSNode node = colliders[i].gameObject.GetComponent <MDSNode>(); if (node != null && node.NodeInfo.nodeType == (int)MDSNodeType.ENDPOINT) { return(node); } } } return(null); }