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;
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        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;
            }
        }
예제 #8
0
        /// <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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);
        }
예제 #12
0
        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();
                }
            }
        }
예제 #13
0
        /// <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);
            }
        }
예제 #14
0
        /// <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);
        }