AtlasTexture in Godot – Complete Guide

AtlasTexture is a powerful feature within the Godot 4 engine that allows developers to use a portion of a larger texture, called an atlas. This not only optimizes video memory usage but can also decrease the number of render calls your game needs, which is essential for performance, especially on lower-end devices. If you’re looking to boost performance and make your game’s graphics more efficient, understanding how to use AtlasTexture is a must.

What is AtlasTexture?

An AtlasTexture is essentially a way to crop and utilize just a part of a larger texture, known as an atlas, in your Godot 4 projects. By defining a region within the atlas, you can draw only the portions you need without having to load multiple individual textures into memory.

What is it for?

Using an AtlasTexture allows you to:

– Group multiple images into a single file, reducing the number of image resources your game needs to load.
– Optimize performance due to fewer render calls and lower memory usage.

Why Should You Learn It?

For game developers, it’s crucial to maintain an optimal balance between visual quality and performance. AtlasTexture is one of those features in Godot 4 that helps you achieve just that. Learning how to use AtlasTexture could mean the difference between a game that runs smoothly on all platforms and one that suffers from lag and stuttering on lower-end devices. Plus, it’s a commonly used technique in 2D game art that is valuable to master for any aspiring game developer.

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

Creating AtlasTexture in Godot 4

First, you need to create an atlas in Godot 4. This process compiles multiple textures into a single image that your game can reference.

var atlas = AtlasTexture.new()
var atlas_image = Image.new()
atlas_image.load("res://path_to_your_atlas.png")
var atlas_texture = ImageTexture.new()
atlas_texture.create_from_image(atlas_image)

atlas.atlas = atlas_texture

Once the atlas is created, you can define a region of the texture to use for a particular sprite.

var region = Rect2(Vector2(0, 0), Vector2(64, 64))  // Specify the x, y, width, and height
atlas.region = region

var sprite = Sprite.new()
sprite.texture = atlas
add_child(sprite)

Setting Up Sprites with AtlasTexture

When you have multiple sprites that will use different parts of the same atlas, setting them up with AtlasTexture can be very efficient.

For example, if you have a character sprite sheet where each character frame is 64×64 pixels, you can set up each frame like this:

var frame_1 = atlas.duplicate()
frame_1.region = Rect2(Vector2(0, 0), Vector2(64, 64))

var frame_2 = atlas.duplicate()
frame_2.region = Rect2(Vector2(64, 0), Vector2(64, 64))

var frame_3 = atlas.duplicate()
frame_3.region = Rect2(Vector2(128, 0), Vector2(64, 64))

This process can be repeated for all the frames your character has on the sprite sheet.

Handling Animation with AtlasTexture

To handle animation in Godot 4 using AtlasTexture, you use the AnimationPlayer node.

First, create an AnimationPlayer node and then programmatically create a new animation:

var animation_player = AnimationPlayer.new()
add_child(animation_player)

var animation = Animation.new()
animation_player.add_animation("run", animation)

Next, configure the animation by adding tracks for the different frames:

animation.add_track(Animation.TYPE_VALUE)
animation.track_set_path(0, "Sprite:texture:region")
animation.track_insert_key(0, 0.0, Rect2(Vector2(0, 0), Vector2(64, 64)))
animation.track_insert_key(0, 0.1, Rect2(Vector2(64, 0), Vector2(64, 64)))
animation.track_insert_key(0, 0.2, Rect2(Vector2(128, 0), Vector2(64, 64)))

With the tracks set up, you can play the animation:

animation_player.play("run")

Dynamically Changing Atlas Regions

In some cases, you might need to change the atlas region at runtime. Here’s an example of how to change the region based on user input, such as moving right or left:

func _input(event):
    if event is InputEventKey:
        if event.pressed and event.scancode == KEY_RIGHT:
            atlas.region = Rect2(Vector2(64, 0), Vector2(64, 64))
        if event.pressed and event.scancode == KEY_LEFT:
            atlas.region = Rect2(Vector2(128, 0), Vector2(64, 64))

Remember, each piece of code you write should call methods and assign variables according to your project’s actual structure. This ensures that the AtlasTexture and the regions you want to use are properly referred to and manipulated within your game’s codebase.AtlasTextures are extremely flexible and can be utilized in numerous ways within your Godot 4 projects. Below are additional ways to work with AtlasTexture, giving you a broader scope of their potential.

Updating Atlas Regions in Real-Time

Suppose you want to change the texture region of a sprite in real-time based on game conditions, like picking up an item or changing outfits. This is how you could dynamically update the AtlasTexture region:

func update_texture_region(new_region: Rect2):
    var sprite = get_node("Sprite")
    var atlas_texture = sprite.texture as AtlasTexture
    atlas_texture.region = new_region

In this case, the `update_texture_region` function would be called with the new region you want your sprite to display.

AtlasTexture and TileMaps

If you are developing a game with a tile-based system, AtlasTexture can help you efficiently manage your tiles. Here’s an example of how to change a tile in a TileMap using an AtlasTexture:

var tilemap = get_node("TileMap")
var atlas_texture = preload("res://path_to_your_atlas.tres")

tilemap.set_cell(0, 0, atlas_texture, false, false, false, Rect2(Vector2(0, 0), Vector2(64, 64)))
tilemap.update_bitmask_region()  # This updates the tilemap’s bitmapping

In the above code snippet, we’re setting the tile at grid coordinates (0,0) to the specified region of the AtlasTexture.

Combining AtlasTexture with Shaders

Shaders can further enhance the potential of AtlasTextures. Here’s a basic example of setting up a shader that works with an AtlasTexture:

var material = ShaderMaterial.new()

var shader_code = """
shader_type canvas_item;

void fragment() {
	COLOR = texture(AtlasTexture,UV);
}
"""

material.shader = Shader.new()
material.shader.code = shader_code

sprite.material = material

This simple shader will draw the currently selected region of the AtlasTexture on the Sprite node.

Batching Sprites with an AtlasTexture

When dealing with a lot of sprites, Godot’s rendering engine will benefit from texture batching. Here’s how to configurate multiple sprites to use parts of the same atlas:

for i in range(amount_of_sprites):
    var new_sprite = Sprite.new()
    var frame_region = Rect2(Vector2(i * 64, 0), Vector2(64, 64))
    var sprite_atlas_texture = atlas.duplicate()
    sprite_atlas_texture.region = frame_region
    
    new_sprite.texture = sprite_atlas_texture
    add_child(new_sprite)

Batching like this will significantly improve your game’s drawing performance, reducing the load on the GPU.

Loading AtlasTexture Regions from a Configuration File

If you have an external configuration file that defines the regions, such as JSON, here’s how you might load and apply those settings to your AtlasTexture:

var regions_data = parse_json(load("res://atlas_regions.json").get_as_text())

for sprite_name, region_data in regions_data:
    var sprite = get_node(sprite_name)
    var atlas_texture = preload(region_data.atlas_file).duplicate()

    var region_rect = Rect2(
        Vector2(region_data.x, region_data.y),
        Vector2(region_data.width, region_data.height)
    )
    
    atlas_texture.region = region_rect
    sprite.texture = atlas_texture

These are just a few examples that demonstrate how AtlasTexture can be a powerful tool in your Godot development toolkit. By understanding and utilizing these principles, you can enhance your games with efficient graphics handling and performance optimizations.Let’s delve deeper into some more advanced use-cases and functionalities of AtlasTextures in Godot 4 that can give you a competitive edge in game development.

If you’re working on a project that requires a dynamic world, like a farming game where crops change over time, you might want to update the texture region of plants as they grow. Consider this example where we update the crop sprite based on its growth stage:

func update_crop_growth(crop_sprite, growth_stage):
    var stages = {
        0: Rect2(Vector2(0, 0), Vector2(64, 64)),   // Seedling
        1: Rect2(Vector2(64, 0), Vector2(64, 64)),  // Growing
        2: Rect2(Vector2(128, 0), Vector2(64, 64))  // Mature
    }

    var atlas_texture = crop_sprite.texture as AtlasTexture
    atlas_texture.region = stages[growth_stage]

In games with custom character creation, you might layer multiple AtlasTexture objects for different character parts. Here is an example of how to change the character’s hair texture using an AtlasTexture without affecting the rest of the character:

func change_hair_style(character, hair_style_index):
    var hair_styles = {
        0: Rect2(Vector2(0, 0), Vector2(64, 64)), 
        1: Rect2(Vector2(64, 0), Vector2(64, 64)), 
        2: Rect2(Vector2(128, 0), Vector2(64, 64))
    }

    var hair_sprite = character.get_node("HairSprite")
    var hair_atlas_texture = hair_sprite.texture as AtlasTexture
    hair_atlas_texture.region = hair_styles[hair_style_index]

Sometimes, you want to create a dynamic UI element that changes based on the user’s actions, like a health bar. The following code snippet demonstrates changing the region of a texture for a health bar based on the player’s current health:

func update_health_bar(current_health, max_health):
    var health_percentage = float(current_health) / max_health
    var health_bar_sprite = get_node("HealthBarSprite")
    var health_bar_atlas = health_bar_sprite.texture as AtlasTexture
    
    var max_width = 128  # Assuming 128 pixels is the full width of the health bar
    var current_width = int(max_width * health_percentage)

    health_bar_atlas.region = Rect2(Vector2(0, 0), Vector2(current_width, 16))

For a game with a day-night cycle, you might want to show different textures based on the time of day. You can swap out different regions of the atlas to reflect the changing environment:

func update_environment_time_of_day(time_of_day):
    var time_of_day_regions = {
        "morning": Rect2(Vector2(0, 0), Vector2(256, 256)),
        "afternoon": Rect2(Vector2(256, 0), Vector2(256, 256)),
        "evening": Rect2(Vector2(512, 0), Vector2(256, 256)),
        "night": Rect2(Vector2(768, 0), Vector2(256, 256))
    }

    var environment_sprite = get_node("EnvironmentSprite")
    var environment_atlas_texture = environment_sprite.texture as AtlasTexture
    environment_atlas_texture.region = time_of_day_regions[time_of_day]

Imagine a game with interchangeable weapon skins or decals. AtlasTextures make it easy to swap out these images on-the-fly:

func change_weapon_skin(weapon_sprite, skin_index):
    var weapon_skins = {
        0: Rect2(Vector2(0, 0), Vector2(128, 64)), 
        1: Rect2(Vector2(128, 0), Vector2(128, 64)), 
        2: Rect2(Vector2(256, 0), Vector2(128, 64))
    }

    var weapon_atlas_texture = weapon_sprite.texture as AtlasTexture
    weapon_atlas_texture.region = weapon_skins[skin_index]

These examples highlight the versatility of AtlasTextures in a variety of game development scenarios. Understanding how to use and manipulate AtlasTexture effectively can result in a more dynamic, efficient, and visually appealing game experience. Whether for characters, UI, environments, or any other sprite-based element, mastering AtlasTextures in Godot 4 can significantly improve your game’s performance and your workflow as a developer.

Where to Go Next in Your Godot Journey

Understanding and implementing AtlasTexture in Godot 4 is just a small part of the vast world that game development encompasses. To continue expanding your knowledge and skills, we invite you to take the next step with us here at Zenva. Our Godot Game Development Mini-Degree provides a comprehensive journey through the ins and outs of game creation with Godot 4.

Whether you’re just starting or looking to level up your skills, our tailored courses will guide you through various aspects of Godot 4. You’ll work through creating diverse game types and master the engine’s capabilities. We’ll equip you with practical experience, constructing a portfolio of projects that showcase your talents.

For more focused learning paths and an extensive range of topics, explore our full collection of Godot courses. Dive into GDScript, gameplay mechanics, and more at your own pace, building a foundation that will support your goals whether you dream of making your game or advancing your career in the burgeoning games industry. Your future in game development awaits, and we at Zenva are excited to be a part of your journey.

Conclusion

Harnessing the power of AtlasTexture in Godot 4 can truly elevate your game development practice, offering efficiency and performance gains that are crucial in today’s competitive market. As you implement these techniques, you’ll notice how your projects become more streamlined and visually coherent. Remember, these are just the building blocks upon which you can construct complex and optimized gaming experiences.

We at Zenva understand that game development is a journey — one that is both challenging and deeply fulfilling. To continue learning and growing, we encourage you to check out our Godot Game Development Mini-Degree. Join us to unlock your potential and bring your most imaginative game ideas to life. Let’s code, create, and conquer the game dev world together!

FREE COURSES
Python Blog Image

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