summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/area_2d.cpp5
-rw-r--r--scene/2d/audio_stream_player_2d.cpp6
-rw-r--r--scene/2d/collision_object_2d.cpp20
-rw-r--r--scene/2d/collision_object_2d.h7
-rw-r--r--scene/2d/cpu_particles_2d.cpp4
-rw-r--r--scene/2d/mesh_instance_2d.cpp13
-rw-r--r--scene/2d/mesh_instance_2d.h4
-rw-r--r--scene/2d/multimesh_instance_2d.cpp13
-rw-r--r--scene/2d/multimesh_instance_2d.h4
-rw-r--r--scene/2d/navigation_agent_2d.cpp20
-rw-r--r--scene/2d/navigation_agent_2d.h18
-rw-r--r--scene/2d/navigation_region_2d.cpp16
-rw-r--r--scene/2d/node_2d.cpp8
-rw-r--r--scene/2d/node_2d.h1
-rw-r--r--scene/2d/path_2d.cpp25
-rw-r--r--scene/2d/path_2d.h5
-rw-r--r--scene/2d/physics_body_2d.cpp4
-rw-r--r--scene/2d/tile_map.cpp138
-rw-r--r--scene/2d/tile_map.h5
-rw-r--r--scene/2d/visible_on_screen_notifier_2d.cpp2
20 files changed, 181 insertions, 137 deletions
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 5eb76bdbb5..f80da6e9ab 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -175,6 +175,7 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
return; //does not exist because it was likely removed from the tree
}
+ lock_callback();
locked = true;
if (body_in) {
@@ -224,6 +225,7 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
}
locked = false;
+ unlock_callback();
}
void Area2D::_area_enter_tree(ObjectID p_id) {
@@ -268,6 +270,8 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
if (!area_in && !E) {
return; //likely removed from the tree
}
+
+ lock_callback();
locked = true;
if (area_in) {
@@ -317,6 +321,7 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
}
locked = false;
+ unlock_callback();
}
void Area2D::_clear_monitoring() {
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index c4de3a124b..7b681eac7a 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -391,10 +391,8 @@ bool AudioStreamPlayer2D::get_stream_paused() const {
}
Ref<AudioStreamPlayback> AudioStreamPlayer2D::get_stream_playback() {
- if (!stream_playbacks.is_empty()) {
- return stream_playbacks[stream_playbacks.size() - 1];
- }
- return nullptr;
+ ERR_FAIL_COND_V_MSG(stream_playbacks.is_empty(), Ref<AudioStreamPlayback>(), "Player is inactive. Call play() before requesting get_stream_playback().");
+ return stream_playbacks[stream_playbacks.size() - 1];
}
void AudioStreamPlayer2D::set_max_polyphony(int p_max_polyphony) {
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index b2fee6ad82..caea753d99 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -94,10 +94,14 @@ void CollisionObject2D::_notification(int p_what) {
bool disabled = !is_enabled();
if (!disabled || (disable_mode != DISABLE_MODE_REMOVE)) {
- if (area) {
- PhysicsServer2D::get_singleton()->area_set_space(rid, RID());
+ if (callback_lock > 0) {
+ ERR_PRINT("Removing a CollisionObject node during a physics callback is not allowed and will cause undesired behavior. Remove with call_deferred() instead.");
} else {
- PhysicsServer2D::get_singleton()->body_set_space(rid, RID());
+ if (area) {
+ PhysicsServer2D::get_singleton()->area_set_space(rid, RID());
+ } else {
+ PhysicsServer2D::get_singleton()->body_set_space(rid, RID());
+ }
}
}
@@ -225,10 +229,14 @@ void CollisionObject2D::_apply_disabled() {
switch (disable_mode) {
case DISABLE_MODE_REMOVE: {
if (is_inside_tree()) {
- if (area) {
- PhysicsServer2D::get_singleton()->area_set_space(rid, RID());
+ if (callback_lock > 0) {
+ ERR_PRINT("Disabling a CollisionObject node during a physics callback is not allowed and will cause undesired behavior. Disable with call_deferred() instead.");
} else {
- PhysicsServer2D::get_singleton()->body_set_space(rid, RID());
+ if (area) {
+ PhysicsServer2D::get_singleton()->area_set_space(rid, RID());
+ } else {
+ PhysicsServer2D::get_singleton()->body_set_space(rid, RID());
+ }
}
}
} break;
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index d44e402e96..88429b145d 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -53,6 +53,7 @@ private:
bool area = false;
RID rid;
+ uint32_t callback_lock = 0;
bool pickable = false;
DisableMode disable_mode = DISABLE_MODE_REMOVE;
@@ -83,6 +84,12 @@ private:
void _apply_enabled();
protected:
+ _FORCE_INLINE_ void lock_callback() { callback_lock++; }
+ _FORCE_INLINE_ void unlock_callback() {
+ ERR_FAIL_COND(callback_lock == 0);
+ callback_lock--;
+ }
+
CollisionObject2D(RID p_rid, bool p_area);
void _notification(int p_what);
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 39be51879d..afd4763d74 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -1430,8 +1430,8 @@ void CPUParticles2D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_less"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,1,0.0001"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,1,0.0001"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_OFFSET);
BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY);
diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp
index f69b3728f7..4fc375ff8d 100644
--- a/scene/2d/mesh_instance_2d.cpp
+++ b/scene/2d/mesh_instance_2d.cpp
@@ -49,14 +49,10 @@ void MeshInstance2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &MeshInstance2D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &MeshInstance2D::get_texture);
- ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &MeshInstance2D::set_normal_map);
- ClassDB::bind_method(D_METHOD("get_normal_map"), &MeshInstance2D::get_normal_map);
-
ADD_SIGNAL(MethodInfo("texture_changed"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
}
void MeshInstance2D::set_mesh(const Ref<Mesh> &p_mesh) {
@@ -77,15 +73,6 @@ void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
emit_signal(SceneStringNames::get_singleton()->texture_changed);
}
-void MeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) {
- normal_map = p_texture;
- queue_redraw();
-}
-
-Ref<Texture2D> MeshInstance2D::get_normal_map() const {
- return normal_map;
-}
-
Ref<Texture2D> MeshInstance2D::get_texture() const {
return texture;
}
diff --git a/scene/2d/mesh_instance_2d.h b/scene/2d/mesh_instance_2d.h
index 795b3758e3..c914f13ade 100644
--- a/scene/2d/mesh_instance_2d.h
+++ b/scene/2d/mesh_instance_2d.h
@@ -39,7 +39,6 @@ class MeshInstance2D : public Node2D {
Ref<Mesh> mesh;
Ref<Texture2D> texture;
- Ref<Texture2D> normal_map;
protected:
void _notification(int p_what);
@@ -57,9 +56,6 @@ public:
void set_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_texture() const;
- void set_normal_map(const Ref<Texture2D> &p_texture);
- Ref<Texture2D> get_normal_map() const;
-
MeshInstance2D();
};
diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp
index ac7c350751..f347eb6520 100644
--- a/scene/2d/multimesh_instance_2d.cpp
+++ b/scene/2d/multimesh_instance_2d.cpp
@@ -50,14 +50,10 @@ void MultiMeshInstance2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &MultiMeshInstance2D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &MultiMeshInstance2D::get_texture);
- ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map"), &MultiMeshInstance2D::set_normal_map);
- ClassDB::bind_method(D_METHOD("get_normal_map"), &MultiMeshInstance2D::get_normal_map);
-
ADD_SIGNAL(MethodInfo("texture_changed"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multimesh", PROPERTY_HINT_RESOURCE_TYPE, "MultiMesh"), "set_multimesh", "get_multimesh");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_normal_map", "get_normal_map");
}
void MultiMeshInstance2D::set_multimesh(const Ref<MultiMesh> &p_multimesh) {
@@ -91,15 +87,6 @@ Ref<Texture2D> MultiMeshInstance2D::get_texture() const {
return texture;
}
-void MultiMeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) {
- normal_map = p_texture;
- queue_redraw();
-}
-
-Ref<Texture2D> MultiMeshInstance2D::get_normal_map() const {
- return normal_map;
-}
-
#ifdef TOOLS_ENABLED
Rect2 MultiMeshInstance2D::_edit_get_rect() const {
if (multimesh.is_valid()) {
diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h
index 64ecae6d6c..0647412294 100644
--- a/scene/2d/multimesh_instance_2d.h
+++ b/scene/2d/multimesh_instance_2d.h
@@ -40,7 +40,6 @@ class MultiMeshInstance2D : public Node2D {
Ref<MultiMesh> multimesh;
Ref<Texture2D> texture;
- Ref<Texture2D> normal_map;
protected:
void _notification(int p_what);
@@ -57,9 +56,6 @@ public:
void set_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_texture() const;
- void set_normal_map(const Ref<Texture2D> &p_texture);
- Ref<Texture2D> get_normal_map() const;
-
MultiMeshInstance2D();
~MultiMeshInstance2D();
};
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 4f6ba093cb..6b842e6e6b 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -94,9 +94,9 @@ void NavigationAgent2D::_bind_methods() {
ADD_GROUP("Pathfinding", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "target_location", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_target_location", "get_target_location");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:px"), "set_path_desired_distance", "get_path_desired_distance");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,100,0.01,suffix:px"), "set_target_desired_distance", "get_target_desired_distance");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,100,1,suffix:px"), "set_path_max_distance", "get_path_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,suffix:px"), "set_path_desired_distance", "get_path_desired_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "target_desired_distance", PROPERTY_HINT_RANGE, "0.1,1000,0.01,suffix:px"), "set_target_desired_distance", "get_target_desired_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "10,1000,1,suffix:px"), "set_path_max_distance", "get_path_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "navigation_layers", PROPERTY_HINT_LAYERS_2D_NAVIGATION), "set_navigation_layers", "get_navigation_layers");
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_metadata_flags", PROPERTY_HINT_FLAGS, "Include Types,Include RIDs,Include Owners"), "set_path_metadata_flags", "get_path_metadata_flags");
@@ -105,8 +105,8 @@ void NavigationAgent2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "radius", PROPERTY_HINT_RANGE, "0.1,500,0.01,suffix:px"), "set_radius", "get_radius");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "neighbor_distance", PROPERTY_HINT_RANGE, "0.1,100000,0.01,suffix:px"), "set_neighbor_distance", "get_neighbor_distance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_neighbors", PROPERTY_HINT_RANGE, "1,10000,1"), "set_max_neighbors", "get_max_neighbors");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:s"), "set_time_horizon", "get_time_horizon");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,100000,0.01,suffix:px/s"), "set_max_speed", "get_max_speed");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10,0.01,suffix:s"), "set_time_horizon", "get_time_horizon");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:px/s"), "set_max_speed", "get_max_speed");
ADD_SIGNAL(MethodInfo("path_changed"));
ADD_SIGNAL(MethodInfo("target_reached"));
@@ -182,11 +182,11 @@ void NavigationAgent2D::_notification(int p_what) {
NavigationAgent2D::NavigationAgent2D() {
agent = NavigationServer2D::get_singleton()->agent_create();
- set_neighbor_distance(500.0);
- set_max_neighbors(10);
- set_time_horizon(20.0);
- set_radius(10.0);
- set_max_speed(200.0);
+ set_neighbor_distance(neighbor_distance);
+ set_max_neighbors(max_neighbors);
+ set_time_horizon(time_horizon);
+ set_radius(radius);
+ set_max_speed(max_speed);
// Preallocate query and result objects to improve performance.
navigation_query = Ref<NavigationPathQueryParameters2D>();
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 113b1e9623..190a2fcbda 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -50,15 +50,15 @@ class NavigationAgent2D : public Node {
uint32_t navigation_layers = 1;
BitField<NavigationPathQueryParameters2D::PathMetadataFlags> path_metadata_flags = NavigationPathQueryParameters2D::PathMetadataFlags::PATH_METADATA_INCLUDE_ALL;
- real_t path_desired_distance = 1.0;
- real_t target_desired_distance = 1.0;
- real_t radius = 0.0;
- real_t neighbor_distance = 0.0;
- int max_neighbors = 0;
- real_t time_horizon = 0.0;
- real_t max_speed = 0.0;
-
- real_t path_max_distance = 3.0;
+ real_t path_desired_distance = 20.0;
+ real_t target_desired_distance = 10.0;
+ real_t radius = 10.0;
+ real_t neighbor_distance = 500.0;
+ int max_neighbors = 10;
+ real_t time_horizon = 1.0;
+ real_t max_speed = 100.0;
+
+ real_t path_max_distance = 100.0;
Vector2 target_location;
bool target_position_submitted = false;
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index a205e704ba..fe6af8dad2 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -48,10 +48,10 @@ void NavigationRegion2D::set_enabled(bool p_enabled) {
if (!enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
- NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
} else {
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
- NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
#ifdef DEBUG_ENABLED
@@ -150,7 +150,7 @@ void NavigationRegion2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
if (enabled) {
NavigationServer2D::get_singleton()->region_set_map(region, get_world_2d()->get_navigation_map());
- NavigationServer2D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
} break;
@@ -161,7 +161,7 @@ void NavigationRegion2D::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
NavigationServer2D::get_singleton()->region_set_map(region, RID());
if (enabled) {
- NavigationServer2D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer2D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
}
} break;
@@ -337,8 +337,8 @@ NavigationRegion2D::NavigationRegion2D() {
NavigationServer2D::get_singleton()->region_set_travel_cost(region, get_travel_cost());
#ifdef DEBUG_ENABLED
- NavigationServer3D::get_singleton_mut()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
- NavigationServer3D::get_singleton_mut()->connect("navigation_debug_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer3D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer3D::get_singleton()->connect("navigation_debug_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
#endif // DEBUG_ENABLED
}
@@ -347,7 +347,7 @@ NavigationRegion2D::~NavigationRegion2D() {
NavigationServer2D::get_singleton()->free(region);
#ifdef DEBUG_ENABLED
- NavigationServer3D::get_singleton_mut()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
- NavigationServer3D::get_singleton_mut()->disconnect("navigation_debug_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer3D::get_singleton()->disconnect("map_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
+ NavigationServer3D::get_singleton()->disconnect("navigation_debug_changed", callable_mp(this, &NavigationRegion2D::_map_changed));
#endif // DEBUG_ENABLED
}
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index 0b7cdafdef..1c0efe773f 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -133,6 +133,14 @@ void Node2D::_update_transform() {
_notify_transform();
}
+void Node2D::reparent(Node *p_parent, bool p_keep_global_transform) {
+ Transform2D temp = get_global_transform();
+ Node::reparent(p_parent);
+ if (p_keep_global_transform) {
+ set_global_transform(temp);
+ }
+}
+
void Node2D::set_position(const Point2 &p_pos) {
if (_xform_dirty) {
const_cast<Node2D *>(this)->_update_xform_values();
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index e332745da5..119e23cd98 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -70,6 +70,7 @@ public:
virtual void _edit_set_rect(const Rect2 &p_edit_rect) override;
#endif
+ virtual void reparent(Node *p_parent, bool p_keep_global_transform = true) override;
void set_position(const Point2 &p_pos);
void set_rotation(real_t p_radians);
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index 09f4406ffe..5036dd30b1 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -31,6 +31,7 @@
#include "path_2d.h"
#include "core/math/geometry_2d.h"
+#include "scene/main/timer.h"
#ifdef TOOLS_ENABLED
#include "editor/editor_scale.h"
@@ -171,6 +172,12 @@ void Path2D::_curve_changed() {
}
queue_redraw();
+ for (int i = 0; i < get_child_count(); i++) {
+ PathFollow2D *follow = Object::cast_to<PathFollow2D>(get_child(i));
+ if (follow) {
+ follow->path_changed();
+ }
+ }
}
void Path2D::set_curve(const Ref<Curve2D> &p_curve) {
@@ -200,6 +207,14 @@ void Path2D::_bind_methods() {
/////////////////////////////////////////////////////////////////////////////////
+void PathFollow2D::path_changed() {
+ if (update_timer && !update_timer->is_stopped()) {
+ update_timer->start();
+ } else {
+ _update_transform();
+ }
+}
+
void PathFollow2D::_update_transform() {
if (!path) {
return;
@@ -230,6 +245,16 @@ void PathFollow2D::_update_transform() {
void PathFollow2D::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_READY: {
+ if (Engine::get_singleton()->is_editor_hint()) {
+ update_timer = memnew(Timer);
+ update_timer->set_wait_time(0.2);
+ update_timer->set_one_shot(true);
+ update_timer->connect("timeout", callable_mp(this, &PathFollow2D::_update_transform));
+ add_child(update_timer, false, Node::INTERNAL_MODE_BACK);
+ }
+ } break;
+
case NOTIFICATION_ENTER_TREE: {
path = Object::cast_to<Path2D>(get_parent());
if (path) {
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 884743dd2a..89c77c49eb 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -34,6 +34,8 @@
#include "scene/2d/node_2d.h"
#include "scene/resources/curve.h"
+class Timer;
+
class Path2D : public Node2D {
GDCLASS(Path2D, Node2D);
@@ -65,6 +67,7 @@ public:
private:
Path2D *path = nullptr;
real_t progress = 0.0;
+ Timer *update_timer = nullptr;
real_t h_offset = 0.0;
real_t v_offset = 0.0;
real_t lookahead = 4.0;
@@ -81,6 +84,8 @@ protected:
static void _bind_methods();
public:
+ void path_changed();
+
void set_progress(real_t p_progress);
real_t get_progress() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 9fee99c6a7..1721bcde3b 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -434,6 +434,8 @@ struct _RigidBody2DInOut {
};
void RigidBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) {
+ lock_callback();
+
set_block_transform_notify(true); // don't want notify (would feedback loop)
if (!freeze || freeze_mode != FREEZE_MODE_KINEMATIC) {
set_global_transform(p_state->get_transform());
@@ -527,6 +529,8 @@ void RigidBody2D::_body_state_changed(PhysicsDirectBodyState2D *p_state) {
contact_monitor->locked = false;
}
+
+ unlock_callback();
}
void RigidBody2D::_apply_body_mode() {
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index ed07d5d11e..8c5aab4c80 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -482,7 +482,11 @@ void TileMap::set_selected_layer(int p_layer_id) {
ERR_FAIL_COND(p_layer_id < -1 || p_layer_id >= (int)layers.size());
selected_layer = p_layer_id;
emit_signal(SNAME("changed"));
- _make_all_quadrants_dirty();
+
+ // Update the layers modulation.
+ for (unsigned int layer = 0; layer < layers.size(); layer++) {
+ _rendering_update_layer(layer);
+ }
}
int TileMap::get_selected_layer() const {
@@ -653,8 +657,7 @@ void TileMap::set_layer_modulate(int p_layer, Color p_modulate) {
}
ERR_FAIL_INDEX(p_layer, (int)layers.size());
layers[p_layer].modulate = p_modulate;
- _clear_layer_internals(p_layer);
- _recreate_layer_internals(p_layer);
+ _rendering_update_layer(p_layer);
emit_signal(SNAME("changed"));
}
@@ -703,8 +706,7 @@ void TileMap::set_layer_z_index(int p_layer, int p_z_index) {
}
ERR_FAIL_INDEX(p_layer, (int)layers.size());
layers[p_layer].z_index = p_z_index;
- _clear_layer_internals(p_layer);
- _recreate_layer_internals(p_layer);
+ _rendering_update_layer(p_layer);
emit_signal(SNAME("changed"));
update_configuration_warnings();
@@ -801,10 +803,10 @@ void TileMap::_make_quadrant_dirty(HashMap<Vector2i, TileMapQuadrant>::Iterator
void TileMap::_make_all_quadrants_dirty() {
// Make all quandrants dirty, then trigger an update later.
- for (unsigned int layer = 0; layer < layers.size(); layer++) {
- for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ for (TileMapLayer &layer : layers) {
+ for (KeyValue<Vector2i, TileMapQuadrant> &E : layer.quadrant_map) {
if (!E.value.dirty_list_element.in_list()) {
- layers[layer].dirty_quadrant_list.add(&E.value.dirty_list_element);
+ layer.dirty_quadrant_list.add(&E.value.dirty_list_element);
}
}
}
@@ -1012,8 +1014,8 @@ void TileMap::_rendering_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_CANVAS: {
bool node_visible = is_visible_in_tree();
- for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) {
+ for (TileMapLayer &layer : layers) {
+ for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layer.quadrant_map) {
TileMapQuadrant &q = E_quadrant.value;
for (const KeyValue<Vector2i, RID> &kv : q.occluders) {
Transform2D xform;
@@ -1028,8 +1030,8 @@ void TileMap::_rendering_notification(int p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
bool node_visible = is_visible_in_tree();
- for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) {
+ for (TileMapLayer &layer : layers) {
+ for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layer.quadrant_map) {
TileMapQuadrant &q = E_quadrant.value;
// Update occluders transform.
@@ -1048,8 +1050,8 @@ void TileMap::_rendering_notification(int p_what) {
if (!is_inside_tree()) {
return;
}
- for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) {
+ for (TileMapLayer &layer : layers) {
+ for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layer.quadrant_map) {
TileMapQuadrant &q = E_quadrant.value;
// Update occluders transform.
@@ -1069,8 +1071,8 @@ void TileMap::_rendering_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_CANVAS: {
- for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) {
+ for (TileMapLayer &layer : layers) {
+ for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layer.quadrant_map) {
TileMapQuadrant &q = E_quadrant.value;
for (const KeyValue<Vector2i, RID> &kv : q.occluders) {
RS::get_singleton()->canvas_light_occluder_attach_to_canvas(kv.value, RID());
@@ -1103,6 +1105,19 @@ void TileMap::_rendering_update_layer(int p_layer) {
rs->canvas_item_set_default_texture_filter(ci, RS::CanvasItemTextureFilter(get_texture_filter_in_tree()));
rs->canvas_item_set_default_texture_repeat(ci, RS::CanvasItemTextureRepeat(get_texture_repeat_in_tree()));
rs->canvas_item_set_light_mask(ci, get_light_mask());
+
+ Color layer_modulate = get_layer_modulate(p_layer);
+ if (selected_layer >= 0 && p_layer != selected_layer) {
+ int z1 = get_layer_z_index(p_layer);
+ int z2 = get_layer_z_index(selected_layer);
+ if (z1 < z2 || (z1 == z2 && p_layer < selected_layer)) {
+ layer_modulate = layer_modulate.darkened(0.5);
+ } else if (z1 > z2 || (z1 == z2 && p_layer > selected_layer)) {
+ layer_modulate = layer_modulate.darkened(0.5);
+ layer_modulate.a *= 0.3;
+ }
+ }
+ rs->canvas_item_set_modulate(ci, layer_modulate);
}
void TileMap::_rendering_cleanup_layer(int p_layer) {
@@ -1145,19 +1160,6 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
int prev_z_index = 0;
RID prev_ci;
- Color tile_modulate = get_self_modulate();
- tile_modulate *= get_layer_modulate(q.layer);
- if (selected_layer >= 0) {
- int z1 = get_layer_z_index(q.layer);
- int z2 = get_layer_z_index(selected_layer);
- if (z1 < z2 || (z1 == z2 && q.layer < selected_layer)) {
- tile_modulate = tile_modulate.darkened(0.5);
- } else if (z1 > z2 || (z1 == z2 && q.layer > selected_layer)) {
- tile_modulate = tile_modulate.darkened(0.5);
- tile_modulate.a *= 0.3;
- }
- }
-
// Iterate over the cells of the quadrant.
for (const KeyValue<Vector2i, Vector2i> &E_cell : q.local_to_map) {
TileMapCell c = get_cell(q.layer, E_cell.value, true);
@@ -1227,7 +1229,7 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
}
// Drawing the tile in the canvas item.
- draw_tile(ci, E_cell.key - tile_position, tile_set, c.source_id, c.get_atlas_coords(), c.alternative_tile, -1, tile_modulate, tile_data);
+ draw_tile(ci, E_cell.key - tile_position, tile_set, c.source_id, c.get_atlas_coords(), c.alternative_tile, -1, get_self_modulate(), tile_data);
// --- Occluders ---
for (int i = 0; i < tile_set->get_occlusion_layers_count(); i++) {
@@ -1255,16 +1257,16 @@ void TileMap::_rendering_update_dirty_quadrants(SelfList<TileMapQuadrant>::List
if (_rendering_quadrant_order_dirty) {
int index = -(int64_t)0x80000000; //always must be drawn below children.
- for (int layer = 0; layer < (int)layers.size(); layer++) {
+ for (TileMapLayer &layer : layers) {
// Sort the quadrants coords per local coordinates.
RBMap<Vector2i, Vector2i, TileMapQuadrant::CoordsWorldComparator> local_to_map;
- for (const KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ for (const KeyValue<Vector2i, TileMapQuadrant> &E : layer.quadrant_map) {
local_to_map[map_to_local(E.key)] = E.key;
}
// Sort the quadrants.
for (const KeyValue<Vector2i, Vector2i> &E : local_to_map) {
- TileMapQuadrant &q = layers[layer].quadrant_map[E.value];
+ TileMapQuadrant &q = layer.quadrant_map[E.value];
for (const RID &ci : q.canvas_items) {
RS::get_singleton()->canvas_item_set_draw_index(ci, index++);
}
@@ -1451,8 +1453,8 @@ void TileMap::_physics_notification(int p_what) {
if (is_inside_tree() && (!collision_animatable || in_editor)) {
// Update the new transform directly if we are not in animatable mode.
Transform2D gl_transform = get_global_transform();
- for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ for (TileMapLayer &layer : layers) {
+ for (KeyValue<Vector2i, TileMapQuadrant> &E : layer.quadrant_map) {
TileMapQuadrant &q = E.value;
for (RID body : q.bodies) {
@@ -1474,8 +1476,8 @@ void TileMap::_physics_notification(int p_what) {
if (is_inside_tree() && !in_editor && collision_animatable) {
// Only active when animatable. Send the new transform to the physics...
new_transform = get_global_transform();
- for (int layer = 0; layer < (int)layers.size(); layer++) {
- for (KeyValue<Vector2i, TileMapQuadrant> &E : layers[layer].quadrant_map) {
+ for (TileMapLayer &layer : layers) {
+ for (KeyValue<Vector2i, TileMapQuadrant> &E : layer.quadrant_map) {
TileMapQuadrant &q = E.value;
for (RID body : q.bodies) {
@@ -1665,13 +1667,12 @@ void TileMap::_navigation_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_TRANSFORM_CHANGED: {
if (is_inside_tree()) {
- for (int layer = 0; layer < (int)layers.size(); layer++) {
+ for (TileMapLayer &layer : layers) {
Transform2D tilemap_xform = get_global_transform();
- for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layers[layer].quadrant_map) {
+ for (KeyValue<Vector2i, TileMapQuadrant> &E_quadrant : layer.quadrant_map) {
TileMapQuadrant &q = E_quadrant.value;
for (const KeyValue<Vector2i, Vector<RID>> &E_region : q.navigation_regions) {
- for (int layer_index = 0; layer_index < E_region.value.size(); layer_index++) {
- RID region = E_region.value[layer_index];
+ for (const RID &region : E_region.value) {
if (!region.is_valid()) {
continue;
}
@@ -2071,7 +2072,7 @@ void TileMap::erase_cell(int p_layer, const Vector2i &p_coords) {
int TileMap::get_cell_source_id(int p_layer, const Vector2i &p_coords, bool p_use_proxies) const {
ERR_FAIL_INDEX_V(p_layer, (int)layers.size(), TileSet::INVALID_SOURCE);
- // Get a cell source id from position
+ // Get a cell source id from position.
const HashMap<Vector2i, TileMapCell> &tile_map = layers[p_layer].tile_map;
HashMap<Vector2i, TileMapCell>::ConstIterator E = tile_map.find(p_coords);
@@ -2127,7 +2128,9 @@ int TileMap::get_cell_alternative_tile(int p_layer, const Vector2i &p_coords, bo
TileData *TileMap::get_cell_tile_data(int p_layer, const Vector2i &p_coords, bool p_use_proxies) const {
int source_id = get_cell_source_id(p_layer, p_coords, p_use_proxies);
- ERR_FAIL_COND_V_MSG(source_id == TileSet::INVALID_SOURCE, nullptr, vformat("Invalid TileSetSource at cell %s. Make sure a tile exists at this cell.", p_coords));
+ if (source_id == TileSet::INVALID_SOURCE) {
+ return nullptr;
+ }
Ref<TileSetAtlasSource> source = tile_set->get_source(source_id);
if (source.is_valid()) {
@@ -2565,7 +2568,7 @@ HashMap<Vector2i, TileSet::TerrainsPattern> TileMap::terrain_fill_path(int p_lay
}
}
}
- ERR_FAIL_COND_V_MSG(found_bit == TileSet::CELL_NEIGHBOR_MAX, output, vformat("Invalid terrain path, %s is not a neighbouring tile of %s", p_path[i + 1], p_path[i]));
+ ERR_FAIL_COND_V_MSG(found_bit == TileSet::CELL_NEIGHBOR_MAX, output, vformat("Invalid terrain path, %s is not a neighboring tile of %s", p_path[i + 1], p_path[i]));
neighbor_list.push_back(found_bit);
}
@@ -2811,8 +2814,8 @@ void TileMap::clear_layer(int p_layer) {
void TileMap::clear() {
// Remove all tiles.
_clear_internals();
- for (unsigned int i = 0; i < layers.size(); i++) {
- layers[i].tile_map.clear();
+ for (TileMapLayer &layer : layers) {
+ layer.tile_map.clear();
}
_recreate_internals();
used_rect_cache_dirty = true;
@@ -2839,7 +2842,7 @@ void TileMap::_set_tile_data(int p_layer, const Vector<int> &p_data) {
const int *r = p_data.ptr();
int offset = (format >= FORMAT_2) ? 3 : 2;
- ERR_FAIL_COND_MSG(c % offset != 0, "Corrupted tile data.");
+ ERR_FAIL_COND_MSG(c % offset != 0, vformat("Corrupted tile data. Got size: %s. Expected modulo: %s", offset));
clear_layer(p_layer);
@@ -2979,11 +2982,7 @@ void TileMap::_build_runtime_update_tile_data(SelfList<TileMapQuadrant>::List &r
#ifdef TOOLS_ENABLED
Rect2 TileMap::_edit_get_rect() const {
// Return the visible rect of the tilemap
- if (pending_update) {
- const_cast<TileMap *>(this)->_update_dirty_quadrants();
- } else {
- const_cast<TileMap *>(this)->_recompute_rect_cache();
- }
+ const_cast<TileMap *>(this)->_recompute_rect_cache();
return rect_cache;
}
#endif
@@ -3221,7 +3220,7 @@ Vector2i TileMap::local_to_map(const Vector2 &p_local_position) const {
ret = ret.floor();
}
- // Compute the tile offset, and if we might the output for a neighbour top tile
+ // Compute the tile offset, and if we might the output for a neighbor top tile
Vector2 in_tile_pos = raw_pos - ret;
bool in_top_left_triangle = (in_tile_pos - Vector2(0.5, 0.0)).cross(Vector2(-0.5, 1.0 / overlapping_ratio - 1)) <= 0;
bool in_top_right_triangle = (in_tile_pos - Vector2(0.5, 0.0)).cross(Vector2(0.5, 1.0 / overlapping_ratio - 1)) > 0;
@@ -3285,7 +3284,7 @@ Vector2i TileMap::local_to_map(const Vector2 &p_local_position) const {
ret = ret.floor();
}
- // Compute the tile offset, and if we might the output for a neighbour top tile
+ // Compute the tile offset, and if we might the output for a neighbor top tile
Vector2 in_tile_pos = raw_pos - ret;
bool in_top_left_triangle = (in_tile_pos - Vector2(0.0, 0.5)).cross(Vector2(1.0 / overlapping_ratio - 1, -0.5)) > 0;
bool in_bottom_left_triangle = (in_tile_pos - Vector2(0.0, 0.5)).cross(Vector2(1.0 / overlapping_ratio - 1, 0.5)) <= 0;
@@ -3738,6 +3737,22 @@ TypedArray<Vector2i> TileMap::get_used_cells(int p_layer) const {
return a;
}
+TypedArray<Vector2i> TileMap::get_used_cells_by_id(int p_layer, int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile) const {
+ ERR_FAIL_INDEX_V(p_layer, (int)layers.size(), TypedArray<Vector2i>());
+
+ // Returns the cells used in the tilemap.
+ TypedArray<Vector2i> a;
+ for (const KeyValue<Vector2i, TileMapCell> &E : layers[p_layer].tile_map) {
+ if ((p_source_id == TileSet::INVALID_SOURCE || p_source_id == E.value.source_id) &&
+ (p_atlas_coords == TileSetSource::INVALID_ATLAS_COORDS || p_atlas_coords == E.value.get_atlas_coords()) &&
+ (p_alternative_tile == TileSetSource::INVALID_TILE_ALTERNATIVE || p_alternative_tile == E.value.alternative_tile)) {
+ a.push_back(E.key);
+ }
+ }
+
+ return a;
+}
+
Rect2i TileMap::get_used_rect() { // Not const because of cache
// Return the rect of the currently used area
if (used_rect_cache_dirty) {
@@ -3940,15 +3955,15 @@ PackedStringArray TileMap::get_configuration_warnings() const {
// Retrieve the set of Z index values with a Y-sorted layer.
RBSet<int> y_sorted_z_index;
- for (int layer = 0; layer < (int)layers.size(); layer++) {
- if (layers[layer].y_sort_enabled) {
- y_sorted_z_index.insert(layers[layer].z_index);
+ for (const TileMapLayer &layer : layers) {
+ if (layer.y_sort_enabled) {
+ y_sorted_z_index.insert(layer.z_index);
}
}
// Check if we have a non-sorted layer in a Z-index with a Y-sorted layer.
- for (int layer = 0; layer < (int)layers.size(); layer++) {
- if (!layers[layer].y_sort_enabled && y_sorted_z_index.has(layers[layer].z_index)) {
+ for (const TileMapLayer &layer : layers) {
+ if (!layer.y_sort_enabled && y_sorted_z_index.has(layer.z_index)) {
warnings.push_back(RTR("A Y-sorted layer has the same Z-index value as a not Y-sorted layer.\nThis may lead to unwanted behaviors, as a layer that is not Y-sorted will be Y-sorted as a whole with tiles from Y-sorted layers."));
break;
}
@@ -3957,8 +3972,8 @@ PackedStringArray TileMap::get_configuration_warnings() const {
if (tile_set.is_valid() && tile_set->get_tile_shape() == TileSet::TILE_SHAPE_ISOMETRIC) {
bool warn = !is_y_sort_enabled();
if (!warn) {
- for (int layer = 0; layer < (int)layers.size(); layer++) {
- if (!layers[layer].y_sort_enabled) {
+ for (const TileMapLayer &layer : layers) {
+ if (!layer.y_sort_enabled) {
warn = true;
break;
}
@@ -4030,6 +4045,7 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_surrounding_cells", "coords"), &TileMap::get_surrounding_cells);
ClassDB::bind_method(D_METHOD("get_used_cells", "layer"), &TileMap::get_used_cells);
+ ClassDB::bind_method(D_METHOD("get_used_cells_by_id", "layer", "source_id", "atlas_coords", "alternative_tile"), &TileMap::get_used_cells_by_id, DEFVAL(TileSet::INVALID_SOURCE), DEFVAL(TileSetSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetSource::INVALID_TILE_ALTERNATIVE));
ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect);
ClassDB::bind_method(D_METHOD("map_to_local", "map_position"), &TileMap::map_to_local);
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index d187a917b5..7cf2a2eded 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -179,7 +179,7 @@ private:
FORMAT_2,
FORMAT_3
};
- mutable DataFormat format = FORMAT_1; // Assume lowest possible format if none is present;
+ mutable DataFormat format = FORMAT_3;
static constexpr float FP_ADJUST = 0.00001;
@@ -340,7 +340,7 @@ public:
VisibilityMode get_navigation_visibility_mode();
// Cells accessors.
- void set_cell(int p_layer, const Vector2i &p_coords, int p_source_id = -1, const Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = 0);
+ void set_cell(int p_layer, const Vector2i &p_coords, int p_source_id = TileSet::INVALID_SOURCE, const Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = 0);
void erase_cell(int p_layer, const Vector2i &p_coords);
int get_cell_source_id(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const;
Vector2i get_cell_atlas_coords(int p_layer, const Vector2i &p_coords, bool p_use_proxies = false) const;
@@ -377,6 +377,7 @@ public:
Vector2i get_neighbor_cell(const Vector2i &p_coords, TileSet::CellNeighbor p_cell_neighbor) const;
TypedArray<Vector2i> get_used_cells(int p_layer) const;
+ TypedArray<Vector2i> get_used_cells_by_id(int p_layer, int p_source_id = TileSet::INVALID_SOURCE, const Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = TileSetSource::INVALID_TILE_ALTERNATIVE) const;
Rect2i get_used_rect(); // Not const because of cache
// Override some methods of the CanvasItem class to pass the changes to the quadrants CanvasItems
diff --git a/scene/2d/visible_on_screen_notifier_2d.cpp b/scene/2d/visible_on_screen_notifier_2d.cpp
index 9a3fe73be1..237eb3d987 100644
--- a/scene/2d/visible_on_screen_notifier_2d.cpp
+++ b/scene/2d/visible_on_screen_notifier_2d.cpp
@@ -137,7 +137,7 @@ void VisibleOnScreenEnabler2D::set_enable_node_path(NodePath p_path) {
return;
}
enable_node_path = p_path;
- if (is_inside_tree()) {
+ if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) {
node_id = ObjectID();
Node *node = get_node(enable_node_path);
if (node) {