NavigationLink2D in Godot – Complete Guide

Navigating through the virtual worlds we create can be just as complex and nuanced as moving through physical space. When developing a 2D game or application using the powerful Godot Engine, understanding the logistics of pathfinding is crucial. Enter “NavigationLink2D” in Godot 4: a versatile class designed to offer your game characters, or agents, a way to traverse the terrain effortlessly. Whether you’re a seasoned developer or just starting your coding journey, this tutorial will introduce you to the functionalities of NavigationLink2D, showcasing its ability to revolutionize how agents travel across different navigation zones, and thus, make your game environment feel alive and connected.

What is NavigationLink2D?

NavigationLink2D is a node class in the Godot Engine that serves as a connection or ‘link’ between two points on NavigationRegion2Ds. These links are essential components that allow navigation agents like game characters to find their way between different areas, or even across different navigation regions within a 2D space.

What is it for?

Imagine adding elements like ziplines, teleporters, or even jumpable gaps into your game world. NavigationLink2D makes these dynamic movements possible, providing a framework for developers to specify where and how agents can move between points that aren’t directly connected by the standard navigation mesh.

Why Should I Learn About NavigationLink2D?

Understanding this component amplifies the level of interactivity within your game’s environment. As you learn to integrate NavigationLink2D into your Godot projects, you’ll have the ability to create more intricate and interesting level designs. This adds depth to gameplay and offers a richer experience to players. But beyond the player experience, mastering this class will enhance your technical proficiency in game development, preparing you to tackle more complex navigation problems with ease.

CTA Small Image
FREE COURSES AT ZENVA
LEARN GAME DEVELOPMENT, PYTHON AND MORE
ACCESS FOR FREE
AVAILABLE FOR A LIMITED TIME ONLY

Setting Up NavigationLink2D

Before diving into the intricate world of pathfinding with NavigationLink2D, it’s crucial to have a foundation. Let’s start by establishing a basic navigation setup in Godot.

var nav = Navigation2D.new()
add_child(nav)

var nav_region = NavigationRegion2D.new()
nav.add_child(nav_region)

The snippet above creates a new `Navigation2D` node and a `NavigationRegion2D` node as its child. The `NavigationRegion2D` will hold our navigation mesh, defining walkable areas for agents.

var nav_mesh_instance = NavigationPolygonInstance.new()
nav_region.add_child(nav_mesh_instance)

var nav_poly = NavigationPolygon.new()
nav_mesh_instance.navpoly = nav_poly

Here, we’re adding a `NavigationPolygonInstance` to our `NavigationRegion2D`. This instance will use a `NavigationPolygon` which defines the contours of our navigable spaces.

Connecting Navigation Zones

Once our basic setup is ready, we can connect different navigation zones using NavigationLink2D.

var nav_link = NavigationLink2D.new()
nav.add_child(nav_link)

nav_link.path = PoolVector2Array([Vector2(0, 0), Vector2(100, 100)])

This code segment adds a `NavigationLink2D` as a child to our `Navigation2D` node. The link’s path is set from point `(0, 0)` to point `(100, 100)`, simulating a link between two different navigation areas in a straight line.

Enabling Agent Movement Across NavigationLinks

For agents to effectively use the NavigationLink2D, their movement code needs to take into consideration these links.

func _process(delta):
    var path = nav.get_simple_path(agent_global_position, target_global_position, true)

    if path.size() > 1:
        var next_position = path[1]
        agent_global_position = next_position

The function above calculates a path using `get_simple_path()` method, considers navigation links, and moves the agent to the next position along this path.

Creating Custom Navigation Behaviours

Sometimes, you’ll want agents to exhibit different behaviors when crossing a NavigationLink2D. This is where Godot’s powerful scripting comes into play.

func _on_NavigationLink2D_link_passed(nav_link):
    if nav_link.name == "ZipLine":
        # Perform zipline animation
    elif nav_link.name == "Teleport":
        # Perform teleportation

Here, we’ve connected a signal from our `NavigationLink2D` to a function that can perform different actions based on the link’s name or type.

Examples of Advanced NavigationLink2D Usage

For more dynamic navigation needs, you may have agents that need to consider multiple links or complex scenarios.

func find_path_with_links(start, end):
    var path = nav.get_simple_path(start, end, true)
    var extended_path = PoolVector2Array()

    for i in range(path.size() - 1):
        extended_path.append(path[i])
        var links = nav.get_links_between(path[i], path[i + 1])
        
        for link in links:
            extended_path.append_array(link.path)

    extended_path.append(path[path.size() - 1])

    return extended_path

In this custom function, we are computing a path and then extending it to include any `NavigationLink2D` paths that need to be traversed.

Embracing NavigationLink2D within your Godot projects opens up a new dimension of gameplay possibilities. By integrating these examples, you’re on the path to creating more nuanced and interactive game worlds. Keep experimenting with NavigationLink2D to see how it can further enrich your projects!Let’s delve further into NavigationLink2D features and how you can exploit them to create a seamless and immersive navigation system in your 2D games.

Pathfinding with Off-Mesh Connections

When it comes to adding special movement features like jumping over obstacles or traversing through portals, NavigationLink2D becomes invaluable. Here’s how you can mark a portal in your game world:

var portal_link = NavigationLink2D.new()
portal_link.path = PoolVector2Array([portal_entry_position, portal_exit_position])
nav.add_child(portal_link)

This code creates a simple portal link. The `path` property is assigned a 2-point line that represents the entrance and the exit of the portal. As an agent reaches the portal entry, they’ll be transported to the exit position.

Handling NavigationLink2D Callbacks

To respond to an agent traversing a link, you can connect callbacks:

nav_link.connect("link_left", self, "_on_link_left")
nav_link.connect("link_passed", self, "_on_link_passed")

func _on_link_left(link):
    print("Agent left the link: ", link.name)

func _on_link_passed(link):
    print("Agent passed through the link: ", link.name)

The `link_left` signal is fired when the agent leaves the starting point of a link, and the `link_passed` signal is emitted when the agent passes through the link. These can be used to trigger animations, sounds, or other game logic.

Dynamically Creating and Removing Links

Sometimes, you need to create links at runtime, perhaps to represent temporary bridges or destructible environments. Here’s how you can add and remove navigation links dynamically:

# Adding a new navigation link
var dynamic_link = NavigationLink2D.new()
dynamic_link.path = PoolVector2Array([dynamic_point_start, dynamic_point_end])
nav.add_child(dynamic_link)

# Removing an existing navigation link
dynamic_link.queue_free()

Using `queue_free()`, we remove a link when it’s no longer needed, which is crucial for managing resources and ensuring game performance.

Custom NavigationLink2D Properties

Godot allows custom properties on nodes, which can be useful for adjusting agent behavior on specific links:

var jump_link = NavigationLink2D.new()
jump_link.set("is_jump", true)
nav.add_child(jump_link)

func _on_link_passed(link):
    if link.get("is_jump"):
        # Trigger jump animation

In this example, we’re assigning a custom `is_jump` property to a `NavigationLink2D` node. Then, upon passing the link, we check this property to determine whether the agent should perform a jump animation.

Adjusting Link Bi-Directionality

NavigationLink2D can be made uni-directional or bi-directional. You may want an agent to use a zipline only in one direction:

var bi_directional = false
var zipline_link = NavigationLink2D.new()
zipline_link.path = PoolVector2Array([zipline_start, zipline_end])
zipline_link.bidirectional = bi_directional
nav.add_child(zipline_link)

By setting the `bidirectional` property to `false`, we ensure the zipline can only be used from start to end, not the reverse.

Querying Navigation Links

You may want to query the navigation system to get details about existing links:

var links = nav.get_navigation_links_in_region(region_global_position)

for link in links:
    print("Found link: ", link.name, " with path: ", link.path)

This is valuable for debugging or for AI that needs to make decisions about available navigation options based on the surrounding environment.

As you integrate these code examples into your Godot projects, you’ll begin to see the flexibility and power that NavigationLink2D can offer. Tailor these examples to fit the specific needs of your game’s design, and you’ll elevate your players’ 2D navigation experience to new heights. Continue experimenting with these features, and remember, your creativity is the only limit to what you can achieve in Godot!Now, let’s explore how you can make NavigationLink2Ds react to dynamic game states, such as creating a bridge that only appears when a lever is pulled or a collapsing floor that temporarily disables a path. We’ll add some variety to the NavigationLink2D behavior based on in-game events.

Conditional Navigation Links

Imagine a scenario where a bridge is formed in-game, enabling new paths for the agent. In Godot, setting up and responding to this event can be done elegantly with a few lines of code:

# Create a bridge link that is initially disabled
var bridge_link = NavigationLink2D.new()
bridge_link.set("enabled", false)
nav.add_child(bridge_link)

# Function to call when the lever is pulled
func on_lever_pulled():
    bridge_link.set("enabled", true)
    # Optionally, update the navigation mesh if needed

In the above code, the bridge link is disabled by default. When the player interacts with a lever in the game, the link is enabled through an event callback.

To make the link responsive to its enabled state:

func _process(delta):
    if bridge_link.get("enabled"):
        var path = nav.get_simple_path(agent_global_position, target_global_position, true)
        # Move the agent along the path
    else:
        # Perform alternative logic when the bridge is not enabled

By checking the state of `bridge_link` in the `_process` method, we dynamically change the behavior of the agent based on the environment.

Responding to Environment Changes

Let’s consider a more dynamic environment where certain paths become blocked or opened as the game progresses. For example, a collapsed ceiling might temporarily disable a path. Here’s how this can be handled:

# Suppose an event causes a path to be blocked
func on_collapse_event():
    var path_block_link = nav.get_navigation_links_in_region(area_of_collapse)
    for link in path_block_link:
        # Disable link perhaps by setting a property or directly removing it
        link.queue_free()  # For this example, the link is removed

In this snippet, the `on_collapse_event` function searches for all links in the area affected by the collapse and removes them.

If you want the path to be blocked for a certain duration, you can make use of timers:

func on_collapse_event(duration):
    var path_block_link = nav.get_navigation_links_in_region(area_of_collapse)
    for link in path_block_link:
        link.set("enabled", false)
        
    # Set a timer to re-enable the path after the duration
    var timer = Timer.new()
    timer.wait_time = duration
    timer.one_shot = true
    timer.connect("timeout", self, "_on_timer_timeout", [path_block_link])
    add_child(timer)
    timer.start()

func _on_timer_timeout(links):
    for link in links:
        link.set("enabled", true)

Here, we temporarily disable links and set a timer to automatically re-enable them after a specified period. This adds an element of time-based challenges to the game.

Customizing Agent Navigation Preferences

Different agents might have different navigation preferences or needs. For instance, one type of agent might be able to use ziplines, while another cannot. You can customize this behavior as follows:

var agent_type = "walker"

func _get_custom_path(start, end):
    var path = nav.get_simple_path(start, end)
    if agent_type == "zipline_user":
        path = _handle_special_links(path, "Zipline")
    return path

func _handle_special_links(path, link_type):
    var new_path = PoolVector2Array()
    for i in range(path.size()):
        var links = nav.get_links_at_point(path[i])
        for link in links:
            if link.name == link_type:
                new_path.append_array(link.path)
            else:
                new_path.append(path[i])
    return new_path

This customizes the agent’s path based on their type, using specifically named links (`”Zipline”`) that only certain agents (like `”zipline_user”`) should use.

Interactive Links Based on Agent Abilities

Suppose you have a game where agents get upgrades that allow them to interact with the environment differently, like a “double jump” ability to leap over larger gaps. Here’s a way to implement this:

var agent_abilities = {"double_jump": false}

func _update_agent_path():
    if agent_abilities["double_jump"]:
        var jump_link = nav.get_navigation_links_in_region(area_of_double_jump)
        for link in jump_link:
            link.set("is_double_jump", true)

This script would update a NavigationLink2D to reflect new abilities gained by the agent, such as the capability to double jump across larger gaps. You’d mark certain links with properties like `”is_double_jump”` to indicate that those links require such abilities.

These code snippets and explanations showcase the versatility of the NavigationLink2D class in Godot 4. By adapting these examples to your games, you can craft complex and dynamic navigation systems that respond to environment changes and agent capabilities, enhancing the gaming experience. Stay tuned for more tutorials that help you push the boundaries of 2D game development with Zenva.

Continue Your Game Development Journey with Zenva

You’ve taken an amazing step forward in understanding the nuances of NavigationLink2D with Godot 4, but the journey doesn’t end here. If you’re keen to delve deeper into game development and expand your skill set, our Godot Game Development Mini-Degree is the perfect next step. This program is fitting for anyone looking to learn game creation from scratch or aiming to enhance their abilities with hands-on, project-based learning.

In our comprehensive mini-degree, you’ll explore 2D and 3D game development, polish your programming with GDScript, and design intricate gameplay mechanics across different genres. With a project-oriented approach, you’ll build a robust portfolio of games, all while learning at your own pace in a flexible, supportive environment. Our offerings cater to both beginners and seasoned developers, with over 250 courses to sharpen your expertise.

For those intrigued by Godot’s rich capabilities and its thriving, supportive community, we invite you to check out our broader range of Godot courses. Begin your journey into game creation with Zenva today, and transform your passion into a portfolio of completed projects that open new horizons in the digital world!

Conclusion

As you’ve seen, mastering the power of NavigationLink2D in Godot 4 can elevate your game development skills to new heights. From creating intricate levels with dynamic pathfinding to responding to real-time changes within your game world, the possibilities are truly limitless. We encourage you to keep building, experimenting, and learning; every line of code is a step closer to crafting your next engaging game.

Remember, whether you’re just starting out or you’re looking to polish your game development prowess, our Godot Game Development Mini-Degree is here to support your creative journey. Embrace the challenge, join us at Zenva, and let’s bring your vision to life, one game at a time. Happy coding!

FREE COURSES
Python Blog Image

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.