Browse Source

Add collision priority property to TileSet physics layers

Danni 9 months ago
parent
commit
3d132076b2

+ 17 - 2
doc/classes/TileSet.xml

@@ -218,6 +218,13 @@
 				Returns the collision mask of bodies on the given TileSet's physics layer.
 				Returns the collision mask of bodies on the given TileSet's physics layer.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="get_physics_layer_collision_priority" qualifiers="const">
+			<return type="float" />
+			<param index="0" name="layer_index" type="int" />
+			<description>
+				Returns the collision priority of bodies on the given TileSet's physics layer.
+			</description>
+		</method>
 		<method name="get_physics_layer_physics_material" qualifiers="const">
 		<method name="get_physics_layer_physics_material" qualifiers="const">
 			<return type="PhysicsMaterial" />
 			<return type="PhysicsMaterial" />
 			<param index="0" name="layer_index" type="int" />
 			<param index="0" name="layer_index" type="int" />
@@ -547,7 +554,7 @@
 			<param index="0" name="layer_index" type="int" />
 			<param index="0" name="layer_index" type="int" />
 			<param index="1" name="layer" type="int" />
 			<param index="1" name="layer" type="int" />
 			<description>
 			<description>
-				Sets the physics layer (as in the physics server) for bodies in the given TileSet physics layer.
+				Sets the collision layer (as in the physics server) for bodies in the given TileSet physics layer.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="set_physics_layer_collision_mask">
 		<method name="set_physics_layer_collision_mask">
@@ -555,7 +562,15 @@
 			<param index="0" name="layer_index" type="int" />
 			<param index="0" name="layer_index" type="int" />
 			<param index="1" name="mask" type="int" />
 			<param index="1" name="mask" type="int" />
 			<description>
 			<description>
-				Sets the physics layer (as in the physics server) for bodies in the given TileSet physics layer.
+				Sets the collision mask for bodies in the given TileSet physics layer.
+			</description>
+		</method>
+		<method name="set_physics_layer_collision_priority">
+			<return type="void" />
+			<param index="0" name="layer_index" type="int" />
+			<param index="1" name="priority" type="float" />
+			<description>
+				Sets the collision priority for bodies in the given TileSet physics layer.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="set_physics_layer_physics_material">
 		<method name="set_physics_layer_physics_material">

+ 2 - 0
scene/2d/tile_map_layer.cpp

@@ -823,6 +823,7 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) {
 					Ref<PhysicsMaterial> physics_material = tile_set->get_physics_layer_physics_material(tile_set_physics_layer);
 					Ref<PhysicsMaterial> physics_material = tile_set->get_physics_layer_physics_material(tile_set_physics_layer);
 					uint32_t physics_layer = tile_set->get_physics_layer_collision_layer(tile_set_physics_layer);
 					uint32_t physics_layer = tile_set->get_physics_layer_collision_layer(tile_set_physics_layer);
 					uint32_t physics_mask = tile_set->get_physics_layer_collision_mask(tile_set_physics_layer);
 					uint32_t physics_mask = tile_set->get_physics_layer_collision_mask(tile_set_physics_layer);
+					real_t physics_priority = tile_set->get_physics_layer_collision_priority(tile_set_physics_layer);
 
 
 					RID body = r_cell_data.bodies[tile_set_physics_layer];
 					RID body = r_cell_data.bodies[tile_set_physics_layer];
 					if (tile_data->get_collision_polygons_count(tile_set_physics_layer) == 0) {
 					if (tile_data->get_collision_polygons_count(tile_set_physics_layer) == 0) {
@@ -849,6 +850,7 @@ void TileMapLayer::_physics_update_cell(CellData &r_cell_data) {
 						ps->body_attach_object_instance_id(body, tile_map_node ? tile_map_node->get_instance_id() : get_instance_id());
 						ps->body_attach_object_instance_id(body, tile_map_node ? tile_map_node->get_instance_id() : get_instance_id());
 						ps->body_set_collision_layer(body, physics_layer);
 						ps->body_set_collision_layer(body, physics_layer);
 						ps->body_set_collision_mask(body, physics_mask);
 						ps->body_set_collision_mask(body, physics_mask);
+						ps->body_set_collision_priority(body, physics_priority);
 						ps->body_set_pickable(body, false);
 						ps->body_set_pickable(body, false);
 						ps->body_set_state(body, PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, tile_data->get_constant_linear_velocity(tile_set_physics_layer));
 						ps->body_set_state(body, PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, tile_data->get_constant_linear_velocity(tile_set_physics_layer));
 						ps->body_set_state(body, PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, tile_data->get_constant_angular_velocity(tile_set_physics_layer));
 						ps->body_set_state(body, PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, tile_data->get_constant_angular_velocity(tile_set_physics_layer));

+ 30 - 0
scene/resources/2d/tile_set.cpp

@@ -699,6 +699,17 @@ uint32_t TileSet::get_physics_layer_collision_mask(int p_layer_index) const {
 	return physics_layers[p_layer_index].collision_mask;
 	return physics_layers[p_layer_index].collision_mask;
 }
 }
 
 
+void TileSet::set_physics_layer_collision_priority(int p_layer_index, real_t p_priority) {
+	ERR_FAIL_INDEX(p_layer_index, physics_layers.size());
+	physics_layers.write[p_layer_index].collision_priority = p_priority;
+	emit_changed();
+}
+
+real_t TileSet::get_physics_layer_collision_priority(int p_layer_index) const {
+	ERR_FAIL_INDEX_V(p_layer_index, physics_layers.size(), 0);
+	return physics_layers[p_layer_index].collision_priority;
+}
+
 void TileSet::set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material) {
 void TileSet::set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material) {
 	ERR_FAIL_INDEX(p_layer_index, physics_layers.size());
 	ERR_FAIL_INDEX(p_layer_index, physics_layers.size());
 	physics_layers.write[p_layer_index].physics_material = p_physics_material;
 	physics_layers.write[p_layer_index].physics_material = p_physics_material;
@@ -3900,6 +3911,13 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
 				}
 				}
 				set_physics_layer_collision_mask(index, p_value);
 				set_physics_layer_collision_mask(index, p_value);
 				return true;
 				return true;
+			} else if (components[1] == "collision_priority") {
+				ERR_FAIL_COND_V(p_value.get_type() != Variant::FLOAT, false);
+				while (index >= physics_layers.size()) {
+					add_physics_layer();
+				}
+				set_physics_layer_collision_priority(index, p_value);
+				return true;
 			} else if (components[1] == "physics_material") {
 			} else if (components[1] == "physics_material") {
 				Ref<PhysicsMaterial> physics_material = p_value;
 				Ref<PhysicsMaterial> physics_material = p_value;
 				while (index >= physics_layers.size()) {
 				while (index >= physics_layers.size()) {
@@ -4051,6 +4069,9 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
 		} else if (components[1] == "collision_mask") {
 		} else if (components[1] == "collision_mask") {
 			r_ret = get_physics_layer_collision_mask(index);
 			r_ret = get_physics_layer_collision_mask(index);
 			return true;
 			return true;
+		} else if (components[1] == "collision_priority") {
+			r_ret = get_physics_layer_collision_priority(index);
+			return true;
 		} else if (components[1] == "physics_material") {
 		} else if (components[1] == "physics_material") {
 			r_ret = get_physics_layer_physics_material(index);
 			r_ret = get_physics_layer_physics_material(index);
 			return true;
 			return true;
@@ -4176,6 +4197,13 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
 		}
 		}
 		p_list->push_back(property_info);
 		p_list->push_back(property_info);
 
 
+		// physics_layer_%d/collision_priority
+		property_info = PropertyInfo(Variant::FLOAT, vformat("physics_layer_%d/collision_priority", i));
+		if (physics_layers[i].collision_priority == 1.0) {
+			property_info.usage ^= PROPERTY_USAGE_STORAGE;
+		}
+		p_list->push_back(property_info);
+
 		// physics_layer_%d/physics_material
 		// physics_layer_%d/physics_material
 		property_info = PropertyInfo(Variant::OBJECT, vformat("physics_layer_%d/physics_material", i), PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial");
 		property_info = PropertyInfo(Variant::OBJECT, vformat("physics_layer_%d/physics_material", i), PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial");
 		if (!physics_layers[i].physics_material.is_valid()) {
 		if (!physics_layers[i].physics_material.is_valid()) {
@@ -4287,6 +4315,8 @@ void TileSet::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_physics_layer_collision_layer", "layer_index"), &TileSet::get_physics_layer_collision_layer);
 	ClassDB::bind_method(D_METHOD("get_physics_layer_collision_layer", "layer_index"), &TileSet::get_physics_layer_collision_layer);
 	ClassDB::bind_method(D_METHOD("set_physics_layer_collision_mask", "layer_index", "mask"), &TileSet::set_physics_layer_collision_mask);
 	ClassDB::bind_method(D_METHOD("set_physics_layer_collision_mask", "layer_index", "mask"), &TileSet::set_physics_layer_collision_mask);
 	ClassDB::bind_method(D_METHOD("get_physics_layer_collision_mask", "layer_index"), &TileSet::get_physics_layer_collision_mask);
 	ClassDB::bind_method(D_METHOD("get_physics_layer_collision_mask", "layer_index"), &TileSet::get_physics_layer_collision_mask);
+	ClassDB::bind_method(D_METHOD("set_physics_layer_collision_priority", "layer_index", "priority"), &TileSet::set_physics_layer_collision_priority);
+	ClassDB::bind_method(D_METHOD("get_physics_layer_collision_priority", "layer_index"), &TileSet::get_physics_layer_collision_priority);
 	ClassDB::bind_method(D_METHOD("set_physics_layer_physics_material", "layer_index", "physics_material"), &TileSet::set_physics_layer_physics_material);
 	ClassDB::bind_method(D_METHOD("set_physics_layer_physics_material", "layer_index", "physics_material"), &TileSet::set_physics_layer_physics_material);
 	ClassDB::bind_method(D_METHOD("get_physics_layer_physics_material", "layer_index"), &TileSet::get_physics_layer_physics_material);
 	ClassDB::bind_method(D_METHOD("get_physics_layer_physics_material", "layer_index"), &TileSet::get_physics_layer_physics_material);
 
 

+ 3 - 0
scene/resources/2d/tile_set.h

@@ -327,6 +327,7 @@ private:
 	struct PhysicsLayer {
 	struct PhysicsLayer {
 		uint32_t collision_layer = 1;
 		uint32_t collision_layer = 1;
 		uint32_t collision_mask = 1;
 		uint32_t collision_mask = 1;
+		real_t collision_priority = 1.0;
 		Ref<PhysicsMaterial> physics_material;
 		Ref<PhysicsMaterial> physics_material;
 	};
 	};
 	Vector<PhysicsLayer> physics_layers;
 	Vector<PhysicsLayer> physics_layers;
@@ -448,6 +449,8 @@ public:
 	uint32_t get_physics_layer_collision_layer(int p_layer_index) const;
 	uint32_t get_physics_layer_collision_layer(int p_layer_index) const;
 	void set_physics_layer_collision_mask(int p_layer_index, uint32_t p_mask);
 	void set_physics_layer_collision_mask(int p_layer_index, uint32_t p_mask);
 	uint32_t get_physics_layer_collision_mask(int p_layer_index) const;
 	uint32_t get_physics_layer_collision_mask(int p_layer_index) const;
+	void set_physics_layer_collision_priority(int p_layer_index, real_t p_priority);
+	real_t get_physics_layer_collision_priority(int p_layer_index) const;
 	void set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material);
 	void set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material);
 	Ref<PhysicsMaterial> get_physics_layer_physics_material(int p_layer_index) const;
 	Ref<PhysicsMaterial> get_physics_layer_physics_material(int p_layer_index) const;