예제 #1
0
        public void RaycastInGrid()
        {
            if (m_Grid == null || m_Camera == null)
            {
                return;
            }

            Vector3 mousePosition = Input.mousePosition;

            Ray ray = m_Camera.ScreenPointToRay(mousePosition);

            if (Physics.Raycast(ray, out RaycastHit hit))
            {
                if (hit.transform != transform)
                {
                    m_Grid.UnselectNode();
                }

                Vector3 hitPosition = hit.point;
                Vector3 difference  = hitPosition - m_Offset;

                int x = (int)(difference.x / m_NodeSize);
                int y = (int)(difference.z / m_NodeSize);

                // Debug.Log(x + " " + y);

                if (Input.GetMouseButtonDown(0))
                {
                    m_Grid.SelectCoordinate(m_Grid.GetNode(new Vector2Int(x, y)));
                }
            }
        }
예제 #2
0
        private void ResetCache()
        {
            Debug.Log("Cache reset!");
            for (int y = 0; y < m_Grid.Height; ++y)
            {
                for (int x = 0; x < m_Grid.Width; ++x)
                {
                    m_Grid.GetNode(x, y).OccupationAvailability = EOccupationAvailability.CanOccupy;
                }
            }

            var current_node = m_Grid.GetNode(m_Grid.Start);

            while (current_node.Coords != m_Grid.Target)
            {
                current_node.OccupationAvailability = EOccupationAvailability.Undefined;

                /*
                 *
                 * : Node
                 * ? : Undefinded
                 | : Vertical edge
                 | /, \ : Diagonal edge
                 |
                 | Case 1:
                 | . . .      . . .
                 | . * .      . ? .
                 | . | .  =>  . | .
                 | . * .      . ? .
                 | . . .      . . .
                 | Same for horisontal
                 |
                 | Case 2:
                 | . . . . .      . . . . .
                 | . * . * .      . ? . ? .
                 | . . / . .  =>  . . / . .
                 | . * . * .      . ? . ? .
                 | . . . . .      . . . . .
                 | Same for other diagonal
                 |
                 */

                if (current_node.HasDiagonalEdge())
                {
                    int x1 = current_node.Coords.x;
                    int y1 = current_node.Coords.y;
                    int x2 = current_node.NextNode.Coords.x;
                    int y2 = current_node.NextNode.Coords.y;

                    m_Grid.GetNode(x1, y2).OccupationAvailability = EOccupationAvailability.Undefined;
                    m_Grid.GetNode(x2, y1).OccupationAvailability = EOccupationAvailability.Undefined;
                }

                current_node = current_node.NextNode;
            }

            m_Grid.GetNode(m_Grid.Start).OccupationAvailability  = EOccupationAvailability.CannotOccupy;
            m_Grid.GetNode(m_Grid.Target).OccupationAvailability = EOccupationAvailability.CannotOccupy;
            m_NeedUpdate = false;
        }
예제 #3
0
        public void UpdateField()
        {
            foreach (Node node in m_Grid.EnumerateAllNodes())
            {
                node.ResetWeight();
            }

            Queue <Vector2Int> queue = new Queue <Vector2Int>();

            queue.Enqueue(m_Target);
            m_Grid.GetNode(m_Target).PathWeight = 0f;

            while (queue.Count > 0)
            {
                Vector2Int current        = queue.Dequeue();
                Node       currentNode    = m_Grid.GetNode(current);
                float      weightToTarget = currentNode.PathWeight + 1f;

                foreach (Vector2Int neighbour in GetNeighbours(current))
                {
                    Node neighbourNode = m_Grid.GetNode(neighbour);
                    if (weightToTarget < neighbourNode.PathWeight)
                    {
                        neighbourNode.NextNode   = currentNode;
                        neighbourNode.PathWeight = weightToTarget;
                        queue.Enqueue(neighbour);
                    }
                }
            }
        }
예제 #4
0
        public void UpdatePaths()
        {
            ResetAllWeights();

            Queue <Vector2Int> queue = new Queue <Vector2Int>();

            m_Grid.GetNode(m_FinalTarget).PathWeight = 0f;
            queue.Enqueue(m_FinalTarget);

            while (queue.Count > 0)
            {
                Vector2Int current     = queue.Dequeue();
                Node       currentNode = m_Grid.GetNode(current);
                foreach (Vector2Int neighbour in GetNeighbours(current))
                {
                    Node neighbourNode = m_Grid.GetNode(neighbour);
                    if (!m_Grid.CheckCoordinate(neighbour) || neighbourNode.IsOccupied)
                    {
                        continue;
                    }

                    if ((current - neighbour).magnitude > 1)
                    {
                        // checking adjacent nodes
                        if (GetNeighbours(current).Any(adj =>
                                                       CheckAdjacent(adj, current) && CheckAdjacent(adj, neighbour) &&
                                                       m_Grid.GetNode(adj).IsOccupied))
                        {
                            continue;
                        }
                    }

                    if (currentNode.PathWeight + (current - neighbour).magnitude < neighbourNode.PathWeight)
                    {
                        neighbourNode.NextNode   = currentNode;
                        neighbourNode.PathWeight = currentNode.PathWeight + (current - neighbour).magnitude;
                        queue.Enqueue(neighbour);
                    }
                }
            }

            CalculateAccessibility();
        }
예제 #5
0
        public void UpdateField()
        {
            foreach (Node node in m_Grid.EnumerateAllNodes())
            {
                node.ResetWeight();
                node.m_OccupationAvailability = OccupationAvailability.CanOccupy;
            }

            Queue <Vector2Int> queue = new Queue <Vector2Int>();

            queue.Enqueue(m_Target);

            Node start  = m_Grid.GetNode(m_Start);
            Node target = m_Grid.GetNode(m_Target);

            target.PathWeight = 0f;

            while (queue.Count > 0)
            {
                Vector2Int current     = queue.Dequeue();
                Node       currentNode = m_Grid.GetNode(current);

                foreach (Connection neighbour in GetNeighbours(current))
                {
                    float weightToTarget = currentNode.PathWeight + neighbour.Weight;
                    Node  neighbourNode  = m_Grid.GetNode(neighbour.Coordinate);
                    if (weightToTarget < neighbourNode.PathWeight)
                    {
                        neighbourNode.NextNode   = currentNode;
                        neighbourNode.PathWeight = weightToTarget;
                        queue.Enqueue(neighbour.Coordinate);
                    }
                }
            }

            start.m_OccupationAvailability  = OccupationAvailability.CanNotOccupy;
            target.m_OccupationAvailability = OccupationAvailability.CanNotOccupy;

            while (start != target && start != null) // rider ругается, но почему?
            {
                start = start.NextNode;
                start.m_OccupationAvailability = OccupationAvailability.Undefined;
            }
        }
예제 #6
0
        public void UpdateField()
        {
            foreach (Node node in m_Grid.EnumerateAllNodes())
            {
                node.ResetWeight();
                node.OccupationAvailability = OccupationAvailability.CanOccupy;
            }

            Queue <Connection> queue = new Queue <Connection>();

            queue.Enqueue(new Connection(m_Target, 0f));
            m_Grid.GetNode(m_Target).PathWeight = 0f;

            while (queue.Count > 0)
            {
                Connection current     = queue.Dequeue();
                Node       currentNode = m_Grid.GetNode(current.coordinate);

                foreach (Connection neighbour in GetNeighbours(current.coordinate))
                {
                    Node neighbourNode = m_Grid.GetNode(neighbour.coordinate);
                    if (current.weight + neighbour.weight < neighbourNode.PathWeight - Mathf.Epsilon)
                    {
                        neighbourNode.NextNode   = currentNode;
                        neighbourNode.PathWeight = current.weight + neighbour.weight;
                        queue.Enqueue(new Connection(neighbour.coordinate, neighbourNode.PathWeight));
                    }
                }
            }

            Node curNode = m_Grid.GetNode(m_Start);

            curNode.OccupationAvailability = OccupationAvailability.CanNotOccupy;
            curNode = curNode.NextNode;
            while (curNode.PositionOnGrid != m_Target)
            {
                curNode.OccupationAvailability = OccupationAvailability.Undefined;
                curNode = curNode.NextNode;
            }
            curNode.OccupationAvailability = OccupationAvailability.CanNotOccupy;
        }
예제 #7
0
        private void Update()
        {
            if (m_Grid == null || m_Camera == null)
            {
                return;
            }

            Vector3 mousePosition = Input.mousePosition;

            Ray ray = m_Camera.ScreenPointToRay(mousePosition);

            if (Physics.Raycast(ray, out RaycastHit hit))
            {
                if (hit.transform != transform)
                {
                    return;
                }

                Vector3 hitPosition = hit.point;
                Vector3 difference  = hitPosition - m_Offset;

                int x = (int)(difference.x / m_NodeSize);
                int y = (int)(difference.z / m_NodeSize);

                if (Input.GetMouseButtonDown(0))
                {
                    if (m_Grid.GetNode(x, y).IsOccupied)
                    {
                        m_Grid.FreeNode(new Vector2Int(x, y));
                    }
                    else
                    {
                        m_Grid.TryOccupyNode(new Vector2Int(x, y));
                    }
                }
            }
        }
예제 #8
0
        // Dijkstra algorithm
        public void UpdateField()
        {
            foreach (Node node in m_Grid.AllNodes())
            {
                node.ResetWeight();
            }

            var heap = new SortedSet <Vector2Int>(new DijkstraCompare(m_Grid));

            m_Grid.GetNode(m_Target).PathWeight = 0f;
            heap.Add(m_Target);

            while (heap.Count > 0)
            {
                Vector2Int current = heap.Min;
                heap.Remove(current);
                Node currentNode = m_Grid.GetNode(current);

                foreach (Connection neighbour in GetNeighbours(current))
                {
                    Node  neighbourNode  = m_Grid.GetNode(neighbour.coord);
                    float weightToTarget = currentNode.PathWeight + neighbour.weight;
                    if (weightToTarget < neighbourNode.PathWeight)
                    {
                        if (heap.Contains(neighbour.coord))
                        {
                            heap.Remove(neighbour.coord);
                        }

                        neighbourNode.NextNode   = currentNode;
                        neighbourNode.PathWeight = weightToTarget;
                        heap.Add(neighbour.coord);
                    }
                }
            }
        }
예제 #9
0
        private void OnDrawGizmos()
        {
            // Draw gizmo grid
            foreach (Node node in m_Grid.EnumerateAllNodes())
            {
                if (node.EnemyDatas.Count == 0)
                {
                    continue;
                }
                Gizmos.color = Color.white;
                Gizmos.DrawWireSphere(node.Position, 1.1f);
            }

            Debug.Log(m_Offset);
            Gizmos.color = Color.black;
            float height = m_GridHeight * m_NodeSize;
            float width  = m_GridWidth * m_NodeSize;

            for (int i = 0; i <= m_GridWidth; i++)
            {
                Vector3 from = m_Offset + new Vector3(i * m_NodeSize, 0f, 0f);
                Vector3 to   = m_Offset + new Vector3(i * m_NodeSize, 0f, height);
                Gizmos.DrawLine(from, to);
            }
            for (int i = 0; i <= m_GridHeight; i++)
            {
                Vector3 from = m_Offset + new Vector3(0f, 0f, i * m_NodeSize);
                Vector3 to   = m_Offset + new Vector3(width, 0f, i * m_NodeSize);
                Gizmos.DrawLine(from, to);
            }

            //Gizmos.DrawSphere(m_Offset, 1f);


            Gizmos.DrawSphere(m_Grid.GetNode(0, 0).Position, 2f);
            if (m_Grid == null)
            {
                return;
            }

            foreach (var node in m_Grid.EnumerateAllNodes())
            {
                if (node.NextNode == null)
                {
                    continue;
                }

                if (node.IsOccupied)
                {
                    Gizmos.color = Color.black;
                    Gizmos.DrawSphere(node.Position, 5f);
                    continue;
                }
                Gizmos.color = Color.red;
                Vector3 start = node.Position;
                Vector3 end   = node.NextNode.Position;

                Vector3 dir = end - start;

                start -= dir * 0.25f;
                end   -= dir * 0.75f;

                Gizmos.DrawLine(start, end);
                Gizmos.DrawSphere(end, 0.01f);
            }
        }
예제 #10
0
        public void UpdateField()
        {
            foreach (Node node in m_Grid.EnumerateAllNodes())
            {
                node.ResetWeight();
                if (!node.IsOccupied)
                {
                    node.OccupationAvailability = OccupationAvailability.CanOccupy;
                }
                else
                {
                    node.OccupationAvailability = OccupationAvailability.CanNotOccupy;
                }
            }

            Node startNode  = m_Grid.GetNode(m_Start);
            Node targetNode = m_Grid.GetNode(m_Target);

            startNode.OccupationAvailability  = OccupationAvailability.CanNotOccupy;
            targetNode.OccupationAvailability = OccupationAvailability.CanNotOccupy;
            Queue <Vector2Int> queue = new Queue <Vector2Int>();

            queue.Enqueue(m_Target);
            m_Grid.GetNode(m_Target).PathWeight = 0f;

            while (queue.Count > 0)
            {
                Vector2Int current        = queue.Dequeue();
                Node       currentNode    = m_Grid.GetNode(current);
                float      weightToTarget = m_Grid.GetNode(current).PathWeight;
                foreach (Connection neighbour in GetNeighbours(current))
                {
                    Node neighbourNode = m_Grid.GetNode(neighbour.Coordinate);
                    if (weightToTarget + neighbour.Weight < neighbourNode.PathWeight)
                    {
                        neighbourNode.NextNode   = currentNode;
                        neighbourNode.PathWeight = weightToTarget + neighbour.Weight;
                        queue.Enqueue(neighbour.Coordinate);
                    }
                }
            }

            Node wayNode = startNode.NextNode;

            while (wayNode != targetNode)
            {
                wayNode.OccupationAvailability = OccupationAvailability.Undefined;
                wayNode = wayNode.NextNode;
            }
        }
예제 #11
0
        public void UpdateField()
        {
            foreach (Node node in m_Grid.EnumerateAllNodes())
            {
                node.Reset();
            }
            Queue <Connection> queue = new Queue <Connection>();

            queue.Enqueue(new Connection(m_Target, 0));
            m_Grid.GetNode(m_Target).PathWeight = 0;

            while (queue.Count > 0)
            {
                Connection current        = queue.Dequeue();
                Node       currentNode    = m_Grid.GetNode(current.Coordinate);
                float      weightToTarget = currentNode.PathWeight + current.Weight;

                foreach (Connection neighbour in GetNeighbours(current.Coordinate))
                {
                    Node neighbourNode = m_Grid.GetNode(neighbour.Coordinate);
                    if (weightToTarget < neighbourNode.PathWeight)
                    {
                        neighbourNode.NextNode   = currentNode;
                        neighbourNode.PathWeight = weightToTarget;
                        queue.Enqueue(neighbour);
                    }
                }
            }

            Node startNode  = m_Grid.GetNode(m_Start);
            Node targetNode = m_Grid.GetNode(m_Target);

            startNode.OccupationAvailability = OccupationAvailability.CanNotOccupy;
            Node nextNode = startNode.NextNode;

            while (nextNode != targetNode)
            {
                nextNode.OccupationAvailability = OccupationAvailability.Undefined;
                nextNode = nextNode.NextNode;
            }
            targetNode.OccupationAvailability = OccupationAvailability.CanNotOccupy;
        }
예제 #12
0
 public void OnStart()
 {
     SpawnDesk(Game.s_Runner.InitDeskAsset, m_Grid.GetNode(Mathf.RoundToInt(m_Grid.Height / 2), Mathf.RoundToInt(m_Grid.Width / 2)));
 }
예제 #13
0
        public void UpdateField()
        {
            foreach (Node node in m_Grid.EnumerableAllNodes())
            {
                node.ResetWeight();
                node.m_OccupationAvailability = OccupationAvailability.Undefined;
            }


            Queue <Vector2Int> queue = new Queue <Vector2Int>();

            queue.Enqueue(m_Target);
            m_Grid.GetNode(m_Target).PathWeight = 0f;

            Node currentNode;

            while (queue.Count > 0)
            {
                Vector2Int current = queue.Dequeue();
                currentNode = m_Grid.GetNode(current);

                foreach (Connection neighbour in GetNeighbours(current))
                {
                    Node neighbourNode = m_Grid.GetNode(neighbour.Coordinate);
                    if (currentNode.PathWeight + neighbour.Weight < neighbourNode.PathWeight)
                    {
                        neighbourNode.NextNode   = currentNode;
                        neighbourNode.PathWeight = currentNode.PathWeight + neighbour.Weight;
                        queue.Enqueue(neighbour.Coordinate);
                    }
                }
            }

            foreach (Node node in m_Grid.EnumerableAllNodes())
            {
                node.m_OccupationAvailability = OccupationAvailability.CanOccupy;
            }

            m_Grid.GetNode(m_Start).m_OccupationAvailability = OccupationAvailability.CanNotOccupy;
            currentNode = m_Grid.GetNode(m_Start).NextNode;
            while (currentNode != m_Grid.GetNode(m_Target))
            {
                currentNode.m_OccupationAvailability = OccupationAvailability.Undefined;
                currentNode = currentNode.NextNode;
            }
            m_Grid.GetNode(m_Target).m_OccupationAvailability = OccupationAvailability.CanNotOccupy;
        }