diff --git a/doc/classes/AtlasTexture.xml b/doc/classes/AtlasTexture.xml
index 4794c8ef14e..809d983a9d1 100644
--- a/doc/classes/AtlasTexture.xml
+++ b/doc/classes/AtlasTexture.xml
@@ -6,13 +6,13 @@
[Texture2D] resource that draws only part of its [member atlas] texture, as defined by the [member region]. An additional [member margin] can also be set, which is useful for small adjustments.
Multiple [AtlasTexture] resources can be cropped from the same [member atlas]. Packing many smaller textures into a singular large texture helps to optimize video memory costs and render calls.
- [b]Note:[/b] [AtlasTexture] cannot be used in an [AnimatedTexture], and does not work properly if used inside of other [AtlasTexture] resources.
+ [b]Note:[/b] [AtlasTexture] cannot be used in an [AnimatedTexture], and may not tile properly in nodes such as [TextureRect], when inside other [AtlasTexture] resources.
- The texture that contains the atlas. Can be any type inheriting from [Texture2D]. Nesting [AtlasTexture] resources is not supported.
+ The texture that contains the atlas. Can be any type inheriting from [Texture2D], including another [AtlasTexture].
If [code]true[/code], the area outside of the [member region] is clipped to avoid bleeding of the surrounding texture pixels.
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 15678c92812..5a03929f98e 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1489,7 +1489,15 @@ void AtlasTexture::set_atlas(const Ref &p_atlas) {
if (atlas == p_atlas) {
return;
}
+ // Support recursive AtlasTextures.
+ if (Ref(atlas).is_valid()) {
+ atlas->disconnect(CoreStringNames::get_singleton()->changed, callable_mp((Resource *)this, &AtlasTexture::emit_changed));
+ }
atlas = p_atlas;
+ if (Ref(atlas).is_valid()) {
+ atlas->connect(CoreStringNames::get_singleton()->changed, callable_mp((Resource *)this, &AtlasTexture::emit_changed));
+ }
+
emit_changed();
}