diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 65ead7afbc7..6f9d429a669 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -30,6 +30,7 @@ #include "gpu_particles_2d.h" +#include "core/core_string_names.h" #include "scene/resources/particle_process_material.h" #ifdef TOOLS_ENABLED @@ -331,7 +332,15 @@ Rect2 GPUParticles2D::capture_rect() const { } void GPUParticles2D::set_texture(const Ref &p_texture) { + if (texture.is_valid()) { + texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GPUParticles2D::_texture_changed)); + } + texture = p_texture; + + if (texture.is_valid()) { + texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GPUParticles2D::_texture_changed)); + } _update_collision_size(); update(); } @@ -363,6 +372,14 @@ void GPUParticles2D::_attach_sub_emitter() { } } +void GPUParticles2D::_texture_changed() { + // Changes to the texture need to trigger an update to make + // the editor redraw the sprite with the updated texture. + if (texture.is_valid()) { + update(); + } +} + void GPUParticles2D::set_sub_emitter(const NodePath &p_path) { if (is_inside_tree()) { RS::get_singleton()->particles_set_subemitter(particles, RID()); @@ -480,12 +497,21 @@ void GPUParticles2D::_notification(int p_what) { Vector2(-size.x / 2.0, size.y / 2.0) }; - Vector uvs = { - Vector2(0, 0), - Vector2(1, 0), - Vector2(1, 1), - Vector2(0, 1) - }; + Vector uvs; + AtlasTexture *atlas_texure = Object::cast_to(*texture); + if (atlas_texure && atlas_texure->get_atlas().is_valid()) { + Rect2 region_rect = atlas_texure->get_region(); + Size2 atlas_size = atlas_texure->get_atlas()->get_size(); + uvs.push_back(Vector2(region_rect.position.x / atlas_size.x, region_rect.position.y / atlas_size.y)); + uvs.push_back(Vector2((region_rect.position.x + region_rect.size.x) / atlas_size.x, region_rect.position.y / atlas_size.y)); + uvs.push_back(Vector2((region_rect.position.x + region_rect.size.x) / atlas_size.x, (region_rect.position.y + region_rect.size.y) / atlas_size.y)); + uvs.push_back(Vector2(region_rect.position.x / atlas_size.x, (region_rect.position.y + region_rect.size.y) / atlas_size.y)); + } else { + uvs.push_back(Vector2(0, 0)); + uvs.push_back(Vector2(1, 0)); + uvs.push_back(Vector2(1, 1)); + uvs.push_back(Vector2(0, 1)); + } Vector indices = { 0, 1, 2, 0, 2, 3 }; diff --git a/scene/2d/gpu_particles_2d.h b/scene/2d/gpu_particles_2d.h index 7eece328983..10ae91775fa 100644 --- a/scene/2d/gpu_particles_2d.h +++ b/scene/2d/gpu_particles_2d.h @@ -82,6 +82,8 @@ private: void _attach_sub_emitter(); + void _texture_changed(); + protected: static void _bind_methods(); void _validate_property(PropertyInfo &p_property) const;