Exemple #1
0
        private void UpdateNavigationMesh()
        {
            var worldTileMap = GetNode <TileMap>("WorldTileMap");
            var worldTileSet = worldTileMap.TileSet;
            var blockedSet   = new HashSet <Vector2>();

            foreach (var node in EntitiesLayer.GetChildren())
            {
                if (node is StaticBody2D staticBody)
                {
                    var collisionShapeNode = staticBody.GetFirstNodeOfType <CollisionShape2D>();
                    if (collisionShapeNode == null)
                    {
                        continue;
                    }

                    var collisionShape = collisionShapeNode.Shape as RectangleShape2D;
                    if (collisionShape == null)
                    {
                        continue;
                    }

                    List <Vector2> subdividedPoints = new List <Vector2>();
                    var            shapeSize        = collisionShape.Extents * 2f;
                    var            xOffset          = -collisionShape.Extents.x;
                    while (xOffset < collisionShape.Extents.x)
                    {
                        var yOffset = -collisionShape.Extents.y;
                        while (yOffset < collisionShape.Extents.y)
                        {
                            subdividedPoints.Add(new Vector2(xOffset, yOffset));
                            yOffset += TILE_SIZE;
                        }
                        xOffset += TILE_SIZE;
                    }

                    // add the right corners
                    subdividedPoints.Add(new Vector2(collisionShape.Extents.x, -collisionShape.Extents.y));
                    subdividedPoints.Add(new Vector2(collisionShape.Extents.x, collisionShape.Extents.y));

                    foreach (var point in subdividedPoints)
                    {
                        var blockedCellV = worldTileMap.WorldToMap(collisionShapeNode.GlobalPosition + point * .99f);
                        blockedSet.Add(blockedCellV);
                    }
                }
            }

            foreach (var cellvObj in worldTileMap.GetUsedCells())
            {
                var cellv  = (Vector2)cellvObj;
                var cellId = worldTileMap.GetCellv(cellv);

                if (blockedSet.Contains(cellv))
                {
                    continue;
                }

                var cellCoord = worldTileMap.GetCellAutotileCoord((int)cellv.x, (int)cellv.y);
                var poly      = worldTileSet.AutotileGetNavigationPolygon(cellId, cellCoord);
                if (poly == null)
                {
                    poly = worldTileSet.TileGetNavigationPolygon(cellId);
                    if (poly == null)
                    {
                        continue;
                    }
                }

                var transform = Transform2D.Identity;
                transform.origin = worldTileMap.MapToWorld(cellv);

                if (OS.IsDebugBuild() && _drawNavigation)
                {
                    var polygonNode = new Polygon2D();
                    polygonNode.Polygon   = poly.GetVertices();
                    polygonNode.Transform = transform;
                    polygonNode.Modulate  = new Color(0f, .5f, .5f, .5f);
                    _navigation.AddChild(polygonNode);
                }
                _navigation.NavpolyAdd(poly, transform);
            }
        }