Merge pull request #98773 from KeyboardDanni/tileset_collision_priority

Add collision priority property to TileSet physics layers
This commit is contained in:
Thaddeus Crews 2024-11-10 12:12:49 -06:00
commit 4f416378a5
No known key found for this signature in database
GPG Key ID: 62181B86FE9E5D84
4 changed files with 52 additions and 2 deletions

View File

@ -218,6 +218,13 @@
Returns the collision mask of bodies on the given TileSet's physics layer.
</description>
</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">
<return type="PhysicsMaterial" />
<param index="0" name="layer_index" type="int" />
@ -547,7 +554,7 @@
<param index="0" name="layer_index" type="int" />
<param index="1" name="layer" type="int" />
<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>
</method>
<method name="set_physics_layer_collision_mask">
@ -555,7 +562,15 @@
<param index="0" name="layer_index" type="int" />
<param index="1" name="mask" type="int" />
<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>
</method>
<method name="set_physics_layer_physics_material">

View File

@ -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);
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);
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];
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_set_collision_layer(body, physics_layer);
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_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));

View File

@ -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;
}
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) {
ERR_FAIL_INDEX(p_layer_index, physics_layers.size());
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);
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") {
Ref<PhysicsMaterial> physics_material = p_value;
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") {
r_ret = get_physics_layer_collision_mask(index);
return true;
} else if (components[1] == "collision_priority") {
r_ret = get_physics_layer_collision_priority(index);
return true;
} else if (components[1] == "physics_material") {
r_ret = get_physics_layer_physics_material(index);
return true;
@ -4176,6 +4197,13 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
}
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
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()) {
@ -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("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("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("get_physics_layer_physics_material", "layer_index"), &TileSet::get_physics_layer_physics_material);

View File

@ -327,6 +327,7 @@ private:
struct PhysicsLayer {
uint32_t collision_layer = 1;
uint32_t collision_mask = 1;
real_t collision_priority = 1.0;
Ref<PhysicsMaterial> physics_material;
};
Vector<PhysicsLayer> physics_layers;
@ -448,6 +449,8 @@ public:
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);
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);
Ref<PhysicsMaterial> get_physics_layer_physics_material(int p_layer_index) const;