EditorResourceTooltipPlugin in Godot – Complete Guide

Creating an engaging and informative game can often be enhanced by the subtle features that improve user experience – one such feature in Godot 4 is the use of custom tooltips for resources within the editor. Tooltips provide contextual information, and when tailored appropriately, they can significantly streamline the development process by allowing quick previews and relevant data to surface effortlessly as you work. Through this tutorial, you’ll explore the power of the EditorResourceTooltipPlugin class and unlock new ways to optimize your Godot workflows.

What is the EditorResourceTooltipPlugin?

The EditorResourceTooltipPlugin is a customizable class in Godot 4 that enables developers to create advanced tooltips within the Godot editor. By overriding default descriptions, you can present more informative previews specific to your game’s resources, such as textures, scripts, and scenes.

What is it for?

Customized tooltips are particularly useful in the Godot editor where developers manage numerous assets. For instance, seeing a texture’s dimensions and a large preview simply by hovering over it can help you quickly identify the right asset for the job, saving you time and the hassle of opening each one.

Why should I learn it?

Learning how to implement the EditorResourceTooltipPlugin can dramatically improve your efficiency and ease of navigation within your project. It’s a small investment of time for a feature that will continuously pay off during game development. As you become a more seasoned developer, these little efficiencies can combine to significantly streamline your production process. Let’s dive into this feature and uncover its potential!

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

Setting Up the EditorResourceTooltipPlugin

Before we begin implementing custom tooltips, we must first set up the EditorResourceTooltipPlugin in our Godot project. To start, create a new script called `custom_tooltip.gd` and ensure it extends the `EditorResourceTooltipPlugin` class.

extends EditorResourceTooltipPlugin

After creating the script, we need to tell Godot that it’s an Editor Plugin by adding the following function to our `custom_tooltip.gd` script:

func _get_name() -> String:
    return "CustomResourceTooltip"

Configuring the Plugin

Customizing tooltips is as simple as overriding two key functions: `_can_handle()` and `_forward_draw()`. The `_can_handle()` function tells Godot whether the plugin is capable of providing a tooltip for a given resource:

func _can_handle(resource: Resource) -> bool:
    # Assume we want tooltips for all Texture resources
    return resource is Texture

Once we’ve defined which resources our plugin will handle, we can then focus on drawing the tooltip using the `_forward_draw()` function:

func _forward_draw(p_item_rid: RID, p_tooltip_parent: Control, p_tooltip_rect: Rect2) -> bool:
    var resource: Resource = EditorInterface.get_resource_from_item(p_item_rid)
    
    if resource is Texture:
        # Calculate the size for our texture preview
        var preview_size = Vector2(128, 128) # This can be adjusted as needed
        # Draw the texture preview
        p_tooltip_parent.draw_texture_rect_region(
            resource,
            Rect2(p_tooltip_rect.position, preview_size),
            Rect2(Vector2(), resource.get_size()),
            Color.white,
            true
        )
        return true
    return false

Displaying Additional Information

Wouldn’t it be great if our tooltips could show more than just a texture preview? Let’s add some text to display the dimensions of the texture as well:

func _forward_draw(p_item_rid: RID, p_tooltip_parent: Control, p_tooltip_rect: Rect2) -> bool:
    # Same texture preview code as before...
    
    # Drawing text for dimensions beneath the texture
    var text = "Dimensions: %dx%d" % [resource.get_width(), resource.get_height()]
    var text_size = p_tooltip_parent.get_font("font").get_string_size(text)
    var text_pos = p_tooltip_rect.position + Vector2(0, preview_size.y + 5) # Positioning it below the image
    p_tooltip_parent.draw_string(
        p_tooltip_parent.get_font("font"),
        text_pos,
        text,
        Color.white,
        text_size.width
    )
    
    return true

Not only does this provide a visual preview, but it also instantaneously gives developers the texture’s resolution, which can be crucial when fine-tuning the game’s graphical assets.

Handling Different Resource Types

Our plugin is currently set up to handle Texture resources, but what if we want to extend it to other resource types? We simply modify `_can_handle()` and `_forward_draw()` to include additional logic for each resource type:

func _can_handle(resource: Resource) -> bool:
    # Now handling textures and audio stream resources
    return resource is Texture or resource is AudioStream
func _forward_draw(p_item_rid: RID, p_tooltip_parent: Control, p_tooltip_rect: Rect2) -> bool:
    # Same texture drawing code as before...
    
    var resource: Resource = EditorInterface.get_resource_from_item(p_item_rid)
    
    if resource is AudioStream:
        # Draw something specific for AudioStream resources
        var text = "AudioStream: " + resource.get_path().get_file()
        # You could add a small waveform preview or other relevant info here
        
        # Code for drawing text as before...
        
        return true
    return false

By applying these methods, you can enhance the information density and usability of your Godot editor, making it much more tailored to the specific needs of your game project. Remember, the goal is not only to improve aesthetics but also to streamline the development process by providing relevant information at your fingertips.Let’s expand on our tooltip plugin by including additional features and thereby increasing its utility. For example, we could add support for PackedScene resources, showing a list of nodes contained within the scene directly in the tooltip. This can help developers quickly understand the structure of a scene without opening it.

func _can_handle(resource: Resource) -> bool:
    # Handling textures, audio streams, and packed scenes
    return resource is Texture or resource is AudioStream or resource is PackedScene

Now, let’s extend our `_forward_draw()` function to include logic for `PackedScene` resources:

func _forward_draw(p_item_rid: RID, p_tooltip_parent: Control, p_tooltip_rect: Rect2) -> bool:
    var resource: Resource = EditorInterface.get_resource_from_item(p_item_rid)
    
    if resource is PackedScene:
        var scene = resource as PackedScene
        var node_names = []
        var root_node = scene.instance()
        for node in root_node.get_children():
            node_names.append(node.name)

        # Dispose of the instanced scene to avoid memory leaks
        root_node.queue_free()

        # Construct the text to be displayed
        var text = "Nodes: " + node_names.join(", ")
        
        # Drawing code as in the earlier example with textures...
        
        return true

    # Handle other resources as before...

For a more dynamic tooltip, what if we want to visibly show the script language (GDScript, VisualScript, etc.) used in a Script resource? This could give us immediate insight into the coding aspect of an asset. We’ll implement this by adding another condition within our existing methods.

func _can_handle(resource: Resource) -> bool:
    # Adding Scripts to the handled resources
    return resource is Texture or resource is AudioStream or resource is PackedScene or resource is Script

Here’s how we’d expand `_forward_draw()` to handle Script resources:

if resource is Script:
    # Determine the script language for display
    var language = ""
    if resource is GDScript:
        language = "GDScript"
    elif resource is VisualScript:
        language = "VisualScript"
    # Other languages can be added here

    var text = "Script Language: " + language
    
    # Drawing code to display the text...

    return true

We can also give attention to custom resources. Suppose we have a resource named `LevelData` that contains information like difficulty and theme. We’d need to adjust our tooltip plugin to account for that:

if resource is LevelData:
    var level_data = resource as LevelData
    var text = "Level Info: Difficulty - %s, Theme - %s" % [level_data.difficulty, level_data.theme]
    
    # Proceed with drawing the text...
    
    return true

Thanks to the flexibility provided by the EditorResourceTooltipPlugin class, we can fine-tune our tooltips for an array of different resource types. This encourages a more seamless flow in handling the diverse elements that comprise a game project, thus smoothening the path from concept to completion.

Lastly, don’t forget to make your plugin user-friendly by properly managing memory and ensuring performance is not hindered by any heavy tooltip processing. Godot’s philosophy of “human-centered design” should always be kept in mind, designing features and tools that enhance usability and contribute positively to the developer’s workflow.As we further our exploration of the `EditorResourceTooltipPlugin` class, let’s consider other practical applications. For instance, shaders and materials can be quite complex, so having a quick reference to their properties can be invaluable. We’ll extend our code to display a brief overview of these assets.

For shader resources, we might want to show the shader type and a summary of its properties:

if resource is Shader:
    var shader = resource as Shader
    var shader_type = shader.get_shader_mode()
    var shader_properties = shader.get_code().get_property_list()
    var property_names = [prop.name for prop in shader_properties]
    
    var text = "Shader Type: %s\nProperties:\n- %s" % [shader_type, property_names.join("\n- ")]
    
    # Drawing the shader information...

Going further, with materials, particularly showing details like whether it uses albedo textures or has transparency enabled, can instantly let us know how it interacts with light and objects in the scene:

if resource is SpatialMaterial or resource is StandardMaterial3D:
    var material = resource as Material
    var params = []
    
    if material.resource_local_to_scene:
        params.append("Local to Scene")
    if material.next_pass:
        params.append("Has Next Pass")
    
    var text = "Material Properties: " + params.join(", ")
    
    # Drawing the material properties...

What if you want to preview an animation? With the `Animation` resource, you could provide a list of all animation tracks along with their type and keyframe count.

if resource is Animation:
    var animation = resource as Animation
    var tracks_info = []
    for i in range(animation.get_track_count()):
        var track_name = animation.track_get_path(i)
        var key_count = animation.track_get_key_count(i)
        tracks_info.append("%s (%d keys)" % [track_name, key_count])
    
    var text = "Animation Tracks:\n- " + tracks_info.join("\n- ")
    
    # Drawing the animation track information...

As we’ve illustrated with these examples, Godot’s `EditorResourceTooltipPlugin` allows for rich informative layers to be added to virtually any resource. To ensure a clutter-free experience, it might be prudent to limit the amount of information shown or provide a concise summary, with the option to view more if needed.

For example, if an asset has numerous properties, we can choose to display only the most significant ones in the tooltip:

if resource has "important_property":
    var value = resource.get("important_property")
    var text = "Important Property: %s" % value
    
    # Draw tooltip with the important property highlighted...

Maintaining efficient tooltip processing is paramount. Godot’s editor should run smoothly, without tooltips causing noticeable lag. It’s recommended to perform any complex computations or data retrievals asynchronously or cache results where possible:

var cache = {}
func _forward_draw(p_item_rid: RID, p_tooltip_parent: Control, p_tooltip_rect: Rect2) -> bool:
    var resource: Resource = EditorInterface.get_resource_from_item(p_item_rid)
    
    if cache.has(resource.get_path()):
        var text = cache[resource.get_path()]
    else:
        # Compute the tooltip text for this resource
        # ...
        cache[resource.get_path()] = text
    
    # Now draw the tooltip using the cached text
    
    return true

Note that for more advanced usage, you could implement logic within your plugin to clear the cache periodically or when resources are modified, ensuring information stays current and the memory footprint remains minimal.

In summary, the `EditorResourceTooltipPlugin` class is a versatile tool within Godot 4, aiding developers by offering custom, context-sensitive information for their assets. When used judiciously, it can enhance productivity and clarity, making the editor workspace feel greatly more intuitive and accessible. By incorporating these advanced tooltip capabilities into your development toolkit, you’ll ensure a smoother, more responsive creative experience within the Godot environment.

Continuing Your Godot Learning Journey

Mastering the finer points of game development is an ongoing journey, and using the Godot engine’s expansive features like the EditorResourceTooltipPlugin is just the beginning. To further expand your skills and knowledge in Godot 4, we highly recommend exploring our Godot Game Development Mini-Degree. This comprehensive collection of courses will take you through the essentials of building cross-platform games, delving into both 2D and 3D game development, scripting, gameplay mechanics, and much more. The curriculum caters to both beginners and experienced developers, ensuring a path of learning that grows with you.

Whether you’re constructing an RPG, an RTS, a survival game, or a platformer, our project-based courses are designed to help you create a diverse portfolio that showcases your talents to potential employers. The Godot 4 engine is an exceptional choice given its lightweight, powerful, and easy-to-learn nature, not to mention it’s completely free and open-source. At Zenva, our goal is to provide you with high-quality content that bridges the gap from learning concepts to applying them in real-world projects.

Broaden your horizons and discover the full scope of what you can create with Godot by checking out our wide-ranging collection of Godot courses. Strengthen your game development repertoire with Zenva and take your coding and creative skills to new heights!

Conclusion

Embracing the full suite of tools that Godot 4 provides, such as the EditorResourceTooltipPlugin, is a powerful step in becoming a proficient game developer. By crafting custom tooltips, you’ve not only learned to enhance your workspace but also to make informed decisions faster while navigating through your game assets. It’s these kinds of efficiencies that can transform your workflow and elevate your projects from good to exceptional. As you continue to grow and refine your skills with us at Zenva, remember that every technique, every shortcut, and every piece of knowledge builds towards your ultimate goal – creating amazing games that resonate with players.

The world of game development is vast and full of possibilities. With our Godot Game Development Mini-Degree, you’re not just learning, you’re applying, creating, and innovating. We’re here to guide you every step of the way; let’s build those game worlds together, with Zenva as your learning companion on your quest towards game development mastery.

FREE COURSES
Python Blog Image

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