TextureRect in Godot – Complete Guide

What Is TextureRect and What Is It Used For?

Imagine you’re designing the user interface for a game and you want to add images or icons that make your game visually appealing. This is where TextureRect comes into play in Godot 4. It’s a versatile class designed to display textures in all their glory within a game’s user interface. Whether you’re aiming to showcase a hero’s portrait, an inventory icon, or a decorative background element, TextureRect offers you the tools to integrate these visuals seamlessly.

TextureRect is a nested class that inherits from Control, which means it is part of Godot’s extensive UI system. Its prime functionality revolves around displaying images or textures with a multitude of options for scaling, tiling, and positioning. With TextureRect, we can create a robust and flexible user interface that can adapt to various game aesthetics and functional requirements.

Why Should I Learn to Use TextureRect?

Understanding how to use TextureRect can significantly enhance your game development skills in Godot 4. Here’s why mastering this class is useful:

  • Creative Control: You gain the ability to manipulate textures in your UI, ensuring that your interface elements are not only functional but also stylistically in tune with the rest of your game.
  • Adaptability: With properties like stretch_mode and expand_mode, you can ensure your textures fit within the UI regardless of screen size or resolution, making your game more accessible and user-friendly.
  • Simplicity: Despite its power, TextureRect is relatively easy to use, making it an excellent tool for both beginners and experienced developers who want to add visual elements to their UI without complexity.

By learning how to utilize TextureRect effectively, you open up a world of possibilities in UI design for your games. This tutorial aims to give you a solid foundation in using TextureRect, setting the stage for you to create engaging and dynamic game interfaces.

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

Creating a Simple TextureRect

To start off with TextureRect in Godot 4, it’s important to get to grips with how to create a basic TextureRect node and display a texture. Here’s a simple example of how you can add a TextureRect to your scene and set a texture to it:

var texture_rect = TextureRect.new()
texture_rect.texture = preload("res://path_to_your_texture.png")
add_child(texture_rect)

This code snippet creates a new TextureRect, preloads a texture, and adds it as a child to the current node, which will show the texture on the screen. Now, let’s get it anchored to a specific corner:

texture_rect.anchor_left = 0
texture_rect.anchor_top = 0
texture_rect.anchor_right = 0
texture_rect.anchor_bottom = 0
texture_rect.margin_right = texture_rect.texture.get_width()
texture_rect.margin_bottom = texture_rect.texture.get_height()

The above code positions the TextureRect to the top-left corner of its parent node and sizes it according to the dimensions of the texture.

Adjusting the Stretch Mode

Godot’s TextureRect allows you to control how textures scale with the stretch_mode property. This can be particularly useful for backgrounds or when creating responsive UI elements. Here are some examples of different stretch modes:

# Keep the aspect ratio of the texture.
texture_rect.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT

# Cover the entire area, ignoring the aspect ratio.
texture_rect.stretch_mode = TextureRect.STRETCH_COVER

# Tile the texture across the available area.
texture_rect.stretch_mode = TextureRect.STRETCH_TILE

# Expand the texture to fill the area, maintaining the aspect ratio.
texture_rect.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_COVERED

By setting the stretch_mode property to any of the above constants, the TextureRect will render the texture differently to fit or fill the available space, which greatly enhances the versatility of your UI.

Controlling TextureRect’s Expand Mode

The expand property is used when dealing with textures that are smaller than the TextureRect’s size. By toggling this property, you can determine whether or not the texture should be scaled up. Let’s take a look at some examples:

# Enable expand mode to allow the texture to grow.
texture_rect.expand = true

# Use a specific filter mode when the texture is expanded.
var texture = preload("res://path_to_your_texture.png")
texture_rect.texture = texture
texture.flags_filter = true  # Enable filtering

If expand is set to true and the texture’s filter flag is enabled, the texture will scale up smoothly. On the other hand, if the filter flag is set to false, the texture will scale up but may appear pixelated, which could be the desired effect for certain pixel art games.

Manipulating Alignment and Tiling

Alignment and tiling are essential when arranging textures in TextureRect. These properties can help you position textures perfectly and control their tiling behavior. The following examples illustrate how you can manipulate these settings:

# Align the texture to the center of the TextureRect area.
texture_rect.align = TextureRect.ALIGN_CENTER

# Tile the texture within the TextureRect.
texture_rect.tile_mode = TextureRect.TILE_MODE_ENABLED
texture_rect.tile_mode_stretch = false  # Keep the original aspect ratio

With these properties, you can centralize textures or enable tiling, which repeats the texture across the area it occupies. Tiling can be particularly useful when creating patterns or textured backgrounds that need to fill a varying space without losing quality.

Stay tuned for the next part where we’ll dive deeper into how we manipulate visibility and integrate TextureRect with other UI components to build a cohesive and interactive interface.

Now that we’ve covered the basics of the TextureRect in Godot 4, including alignment and tiling, let’s delve deeper into how to make your UI elements respond to user interactions and improve their visual properties.

First, let’s talk about responding to mouse hover events, which is a common requirement for interactive UIs. In Godot, this can be controlled through the mouse_filter property of the Control class, from which TextureRect inherits:

# Change the mouse_filter to react to mouse hover events.
texture_rect.mouse_filter = Control.MOUSE_FILTER_PASS

# You can also set it to ignore or stop the events.
texture_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
texture_rect.mouse_filter = Control.MOUSE_FILTER_STOP

With mouse hover interaction in place, let’s make our UI elements more dynamic by changing the texture when the mouse hovers over them:

# Assume we have two textures: one for the normal state and one for the hover state.
var normal_texture = preload("res://path_to_normal_texture.png")
var hover_texture = preload("res://path_to_hover_texture.png")

texture_rect.connect("mouse_entered", self, "_on_TextureRect_mouse_entered")
texture_rect.connect("mouse_exited", self, "_on_TextureRect_mouse_exited")

func _on_TextureRect_mouse_entered():
    texture_rect.texture = hover_texture

func _on_TextureRect_mouse_exited():
    texture_rect.texture = normal_texture

This will create a simple rollover effect, updating the texture when the mouse enters and exits the TextureRect’s area. Now let’s alter the visibility of TextureRect dynamically. You may want some textures to appear only under certain conditions, such as when a level is completed, or an item is collected:

# To hide the TextureRect.
texture_rect.visible = false

# To show the TextureRect.
texture_rect.visible = true

# You can also toggle it based on a condition.
func toggle_visibility(condition):
    texture_rect.visible = condition

Visibility toggling is a great way to introduce visual cues and feedback for the player. But sometimes, instead of outright hiding UI elements, you might want to dim them to indicate a disabled state. Let’s see how we can modify the modulate property of TextureRect to achieve this:

# Dim the texture to half its brightness.
texture_rect.modulate = Color(1, 1, 1, 0.5)

# Reset the texture to full brightness.
texture_rect.modulate = Color(1, 1, 1, 1)

The modulate property applies a color filter to the texture, allowing not only for dimming but also for colorizing your textures to match a particular mood or design scheme.

Lastly, a consideration often overlooked in the design of UI elements is the application of themes. In Godot, you can apply a consistent style to your UI elements, including TextureRects, through the use of Themes:

# Load a pre-existing theme.
var my_theme = preload("res://my_theme.tres")

# Apply the theme to the TextureRect.
texture_rect.theme = my_theme

Applying a theme ensures that all UI elements adhere to a common set of stylistic guidelines, making your game’s user interface more cohesive and visually appealing.

We’ve come a long way with TextureRect, and by now, you should have a pretty good handle on its basics, as well as some of the more advanced features. These skills will be invaluable as you continue to design interfaces that not only look great but also engage your players through intuitive interactivity and feedback. Keep experimenting and remember that practice is key to mastering these concepts.

Moving forward with our exploration of TextureRect in Godot 4, let’s focus on integrating animation and dynamic content changes which can further enhance the interactivity and liveliness of your UI elements.

To introduce animation to TextureRect, you might want to change textures in a sequence to create a frame-by-frame animation. This can be done by using a Timer node alongside TextureRect:

var frame_1 = preload("res://frame_1.png")
var frame_2 = preload("res://frame_2.png")
var frame_3 = preload("res://frame_3.png")
var frames = [frame_1, frame_2, frame_3]
var current_frame = 0

# Assuming you have a Timer node named "AnimationTimer" as a child
$AnimationTimer.wait_time = 0.3  # Set the desired interval between frames
$AnimationTimer.autostart = true
$AnimationTimer.connect("timeout", self, "_on_AnimationTimer_timeout")

func _on_AnimationTimer_timeout():
    texture_rect.texture = frames[current_frame]
    current_frame = (current_frame + 1) % frames.size()

The code above will cycle through the defined frames, displaying each texture on the TextureRect, and creating a simple animation. The beauty of this method is the flexibility it gives you in manipulating frame rate and sequence.

TextureRect can also have its texture updated based on game logic. Consider displaying different character portraits based on the player’s actions:

var happy_portrait = preload("res://happy_portrait.png")
var sad_portrait = preload("res://sad_portrait.png")

func set_character_mood(is_happy):
    texture_rect.texture = happy_portrait if is_happy else sad_portrait

By changing the texture based on in-game variables, you contextualize the UI within the game world, delivering a richer, more immersive experience.

Another vital aspect of UI design is localization. Let’s take an example of changing textures based on language settings:

var english_button = preload("res://english_button.png")
var spanish_button = preload("res://spanish_button.png")

func update_button_language(language):
    texture_rect.texture = english_button if language == "English" else spanish_button

In this scenario, the TextureRect displays different textures based on the player’s language preference, showcasing how a UI element can adapt to localization requirements.

There may be situations where you need to react to changes in the environment or game state. Consider a scenario where you have a texture that should change color based on the in-game time of day:

var day_texture = preload("res://day_texture.png")
var night_texture = preload("res://night_texture.png")

func update_environment_time(is_daytime):
    texture_rect.modulate = Color(1, 1, 1, 1) if is_daytime else Color(0.5, 0.5, 0.5, 1)
    texture_rect.texture = day_texture if is_daytime else night_texture

The code above modulates the texture based on whether it’s day or night in the game. When it’s daytime, the normal texture is shown in full brightness; when it’s nighttime, the texture is modulated to be darker.

Finally, incorporating user input into your UI elements can add an extra layer of interaction. You could change the texture of a button when it’s clicked:

var default_button_texture = preload("res://default_button_texture.png")
var clicked_button_texture = preload("res://clicked_button_texture.png")

func _on_Button_mouse_entered():
    texture_rect.texture = default_button_texture

func _on_Button_mouse_exited():
    texture_rect.texture = clicked_button_texture

func _input(event):
    if event is InputEventMouseButton and event.pressed and texture_rect.get_rect().has_point(event.position):
        emit_signal("button_clicked")  # Signal to handle the button click event.

Here, the UI reacts to mouse button input, changing the button texture on click, and allowing you to then handle the actual button logic via a custom signal. This gives your buttons a tactile feel.

TextureRect’s flexibility allows you to create UI elements that are not only visually striking but also reactive and dynamic, providing players with immediate visual feedback and keeping the UI an active part of the gameplay experience. We strongly encourage you to try out these examples and see how they can enrich the functionality and aesthetic of your game’s user interface.

Continuing Your Game Development Journey

Well done on taking the first steps into mastering TextureRect in Godot 4! As you continue to push the boundaries of your game development skills, remember that the learning journey never truly ends. If you’re keen to expand your expertise and take your Godot prowess to new heights, we at Zenva Academy would be thrilled to guide you further.

Our comprehensive Godot Game Development Mini-Degree is designed to provide you with a robust education in the realm of game creation. Whether you want to delve deeper into the Godot engine, master GDScript, or get hands-on experience with developing different game genres, this curriculum is tailored for both beginners and seasoned developers. Furthermore, to explore even more exciting Godot courses and build a diverse portfolio, check out our broad selection of Godot courses.

Embrace the journey, construct engaging worlds, and bring your game ideas to life with Zenva. Continue learning, experimenting, and growing—after all, every great game starts with the willingness to explore and the passion to create.

Conclusion

In this in-depth exploration, we’ve unveiled the many facets and possibilities that TextureRect brings to the Godot 4 engine. With its capabilities spanning from simple static displays to dynamic, responsive UI elements, you now possess the knowledge to make your game’s interface as engaging and interactive as the gameplay itself. Remember, these core concepts are just the beginning. The real magic happens when you apply your creativity and coding prowess to craft unique gaming experiences for players around the world.

Take your Godot skills further with Zenva’s Godot Game Development Mini-Degree, where you’ll gain the proficiency to turn your game development dreams into reality. Step up to the challenge, immerse yourself in learning, and join our thriving community of developers. With each lesson, tutorial, and project, you’re building more than just a game; you’re crafting your future in the game industry. Let’s continue the journey together, one node at a time.

FREE COURSES
Python Blog Image

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