You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-20 14:45:44 +00:00
Add one-way collision to tile-set/tile-map
This commit is contained in:
@@ -89,6 +89,9 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
|
|||||||
Vector<Ref<Shape2D> > collisions;
|
Vector<Ref<Shape2D> > collisions;
|
||||||
Ref<NavigationPolygon> nav_poly;
|
Ref<NavigationPolygon> nav_poly;
|
||||||
Ref<OccluderPolygon2D> occluder;
|
Ref<OccluderPolygon2D> occluder;
|
||||||
|
bool one_way_ok = true;
|
||||||
|
Variant one_way_dir;
|
||||||
|
float one_way_max_depth = 0.0f;
|
||||||
|
|
||||||
for (int j = 0; j < mi->get_child_count(); j++) {
|
for (int j = 0; j < mi->get_child_count(); j++) {
|
||||||
|
|
||||||
@@ -114,12 +117,30 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
phys_offset -= sb->get_pos();
|
phys_offset -= sb->get_pos();
|
||||||
|
|
||||||
|
if (one_way_ok) {
|
||||||
|
Vector2 curr_dir = sb->get_one_way_collision_direction();
|
||||||
|
float curr_max_depth = sb->get_one_way_collision_max_depth();
|
||||||
|
if (one_way_dir == Variant()) {
|
||||||
|
one_way_dir = curr_dir;
|
||||||
|
one_way_max_depth = curr_max_depth;
|
||||||
|
} else {
|
||||||
|
if (curr_dir != one_way_dir || curr_max_depth != one_way_max_depth) {
|
||||||
|
one_way_ok = false;
|
||||||
|
WARN_PRINT(String("Mismatch in one-way collision parameters for " + child->get_name()).utf8().get_data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collisions.size()) {
|
if (collisions.size()) {
|
||||||
|
|
||||||
p_library->tile_set_shapes(id, collisions);
|
p_library->tile_set_shapes(id, collisions);
|
||||||
p_library->tile_set_shape_offset(id, -phys_offset);
|
p_library->tile_set_shape_offset(id, -phys_offset);
|
||||||
|
if (one_way_ok && one_way_dir != Variant()) {
|
||||||
|
p_library->tile_set_one_way_collision_direction(id, one_way_dir);
|
||||||
|
p_library->tile_set_one_way_collision_max_depth(id, one_way_max_depth);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
p_library->tile_set_shape_offset(id, Vector2());
|
p_library->tile_set_shape_offset(id, Vector2());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,7 +102,9 @@ void TileMap::_update_quadrant_space(const RID &p_space) {
|
|||||||
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
||||||
|
|
||||||
Quadrant &q = E->get();
|
Quadrant &q = E->get();
|
||||||
Physics2DServer::get_singleton()->body_set_space(q.body, p_space);
|
for (int i = q.bodies.size() - 1; i >= 0; i--) {
|
||||||
|
Physics2DServer::get_singleton()->body_set_space(q.bodies[i], p_space);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +125,9 @@ void TileMap::_update_quadrant_transform() {
|
|||||||
Matrix32 xform;
|
Matrix32 xform;
|
||||||
xform.set_origin(q.pos);
|
xform.set_origin(q.pos);
|
||||||
xform = global_transform * xform;
|
xform = global_transform * xform;
|
||||||
Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform);
|
for (int i = q.bodies.size() - 1; i >= 0; i--) {
|
||||||
|
Physics2DServer::get_singleton()->body_set_state(q.bodies[i], Physics2DServer::BODY_STATE_TRANSFORM, xform);
|
||||||
|
}
|
||||||
|
|
||||||
if (navigation) {
|
if (navigation) {
|
||||||
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
|
||||||
@@ -252,6 +256,22 @@ void TileMap::_fix_cell_transform(Matrix32 &xform, const Cell &p_cell, const Vec
|
|||||||
xform.elements[2].y += offset.y;
|
xform.elements[2].y += offset.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct _BodyParams {
|
||||||
|
Vector2 one_way_direction;
|
||||||
|
float one_way_max_depth;
|
||||||
|
|
||||||
|
bool operator<(const _BodyParams &p_rhs) const {
|
||||||
|
return p_rhs.one_way_direction < one_way_direction || p_rhs.one_way_max_depth < one_way_max_depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const _BodyParams &p_rhs) const {
|
||||||
|
return p_rhs.one_way_direction == one_way_direction && p_rhs.one_way_max_depth == one_way_max_depth;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void TileMap::_update_dirty_quadrants() {
|
void TileMap::_update_dirty_quadrants() {
|
||||||
|
|
||||||
if (!pending_update)
|
if (!pending_update)
|
||||||
@@ -290,8 +310,8 @@ void TileMap::_update_dirty_quadrants() {
|
|||||||
|
|
||||||
q.canvas_items.clear();
|
q.canvas_items.clear();
|
||||||
|
|
||||||
ps->body_clear_shapes(q.body);
|
Map<_BodyParams, int> params_bodies;
|
||||||
int shape_idx = 0;
|
int num_bodies_used = 0;
|
||||||
|
|
||||||
if (navigation) {
|
if (navigation) {
|
||||||
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
|
||||||
@@ -448,8 +468,47 @@ void TileMap::_update_dirty_quadrants() {
|
|||||||
tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose);
|
tex->draw_rect_region(canvas_item, rect, r, modulate, c.transpose);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RID body;
|
||||||
|
_BodyParams params = { tile_set->tile_get_one_way_collision_direction(c.id), tile_set->tile_get_one_way_collision_max_depth(c.id) };
|
||||||
|
Map<_BodyParams, int>::Element *B = params_bodies.find(params);
|
||||||
|
if (!B) {
|
||||||
|
if (q.bodies.size() > num_bodies_used) {
|
||||||
|
// recycle one already existent
|
||||||
|
body = q.bodies[num_bodies_used];
|
||||||
|
// reset it
|
||||||
|
ps->body_clear_shapes(body);
|
||||||
|
} else {
|
||||||
|
// create a new one
|
||||||
|
body = Physics2DServer::get_singleton()->body_create(use_kinematic ? Physics2DServer::BODY_MODE_KINEMATIC : Physics2DServer::BODY_MODE_STATIC);
|
||||||
|
Physics2DServer::get_singleton()->body_attach_object_instance_ID(body, get_instance_ID());
|
||||||
|
Physics2DServer::get_singleton()->body_set_layer_mask(body, collision_layer);
|
||||||
|
Physics2DServer::get_singleton()->body_set_collision_mask(body, collision_mask);
|
||||||
|
Physics2DServer::get_singleton()->body_set_param(body, Physics2DServer::BODY_PARAM_FRICTION, friction);
|
||||||
|
Physics2DServer::get_singleton()->body_set_param(body, Physics2DServer::BODY_PARAM_BOUNCE, bounce);
|
||||||
|
q.bodies.push_back(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialize to match current quadrant
|
||||||
|
Matrix32 xform;
|
||||||
|
xform.set_origin(q.pos);
|
||||||
|
if (is_inside_tree()) {
|
||||||
|
xform = get_global_transform() * xform;
|
||||||
|
RID space = get_world_2d()->get_space();
|
||||||
|
Physics2DServer::get_singleton()->body_set_space(body, space);
|
||||||
|
}
|
||||||
|
Physics2DServer::get_singleton()->body_set_state(body, Physics2DServer::BODY_STATE_TRANSFORM, xform);
|
||||||
|
|
||||||
|
// bookkeep
|
||||||
|
params_bodies[params] = num_bodies_used;
|
||||||
|
num_bodies_used++;
|
||||||
|
} else {
|
||||||
|
// take the one already set up for this tile's parameters
|
||||||
|
body = q.bodies[B->get()];
|
||||||
|
}
|
||||||
|
|
||||||
Vector<Ref<Shape2D> > shapes = tile_set->tile_get_shapes(c.id);
|
Vector<Ref<Shape2D> > shapes = tile_set->tile_get_shapes(c.id);
|
||||||
|
|
||||||
|
int shape_idx = ps->body_get_shape_count(body);
|
||||||
for (int i = 0; i < shapes.size(); i++) {
|
for (int i = 0; i < shapes.size(); i++) {
|
||||||
|
|
||||||
Ref<Shape2D> shape = shapes[i];
|
Ref<Shape2D> shape = shapes[i];
|
||||||
@@ -465,8 +524,10 @@ void TileMap::_update_dirty_quadrants() {
|
|||||||
vs->canvas_item_add_set_transform(debug_canvas_item, xform);
|
vs->canvas_item_add_set_transform(debug_canvas_item, xform);
|
||||||
shape->draw(debug_canvas_item, debug_collision_color);
|
shape->draw(debug_canvas_item, debug_collision_color);
|
||||||
}
|
}
|
||||||
ps->body_add_shape(q.body, shape->get_rid(), xform);
|
ps->body_add_shape(body, shape->get_rid(), xform);
|
||||||
ps->body_set_shape_metadata(q.body, shape_idx++, Vector2(E->key().x, E->key().y));
|
ps->body_set_shape_metadata(body, shape_idx++, Vector2(E->key().x, E->key().y));
|
||||||
|
ps->body_set_one_way_collision_direction(body, params.one_way_direction);
|
||||||
|
ps->body_set_one_way_collision_max_depth(body, params.one_way_max_depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,6 +572,14 @@ void TileMap::_update_dirty_quadrants() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keep just as many bodies as needed
|
||||||
|
for (int i = num_bodies_used; i < q.bodies.size(); i++) {
|
||||||
|
ps->free(q.bodies[i]);
|
||||||
|
}
|
||||||
|
q.bodies.resize(params_bodies.size());
|
||||||
|
|
||||||
|
//OS::get_singleton()->print("body count: %d (%d)\n", q.bodies.size(), params_bodies.size());
|
||||||
|
|
||||||
dirty_quadrant_list.remove(dirty_quadrant_list.first());
|
dirty_quadrant_list.remove(dirty_quadrant_list.first());
|
||||||
quadrant_order_dirty = true;
|
quadrant_order_dirty = true;
|
||||||
}
|
}
|
||||||
@@ -577,8 +646,6 @@ void TileMap::_recompute_rect_cache() {
|
|||||||
|
|
||||||
Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(const PosKey &p_qk) {
|
Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(const PosKey &p_qk) {
|
||||||
|
|
||||||
Matrix32 xform;
|
|
||||||
//xform.set_origin(Point2(p_qk.x,p_qk.y)*cell_size*quadrant_size);
|
|
||||||
Quadrant q;
|
Quadrant q;
|
||||||
q.pos = _map_to_world(p_qk.x * _get_quadrant_size(), p_qk.y * _get_quadrant_size());
|
q.pos = _map_to_world(p_qk.x * _get_quadrant_size(), p_qk.y * _get_quadrant_size());
|
||||||
q.pos += get_cell_draw_offset();
|
q.pos += get_cell_draw_offset();
|
||||||
@@ -587,22 +654,7 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons
|
|||||||
else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT)
|
else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT)
|
||||||
q.pos.y += cell_size.y;
|
q.pos.y += cell_size.y;
|
||||||
|
|
||||||
xform.set_origin(q.pos);
|
|
||||||
// q.canvas_item = VisualServer::get_singleton()->canvas_item_create();
|
// q.canvas_item = VisualServer::get_singleton()->canvas_item_create();
|
||||||
q.body = Physics2DServer::get_singleton()->body_create(use_kinematic ? Physics2DServer::BODY_MODE_KINEMATIC : Physics2DServer::BODY_MODE_STATIC);
|
|
||||||
Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body, get_instance_ID());
|
|
||||||
Physics2DServer::get_singleton()->body_set_layer_mask(q.body, collision_layer);
|
|
||||||
Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask);
|
|
||||||
Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, friction);
|
|
||||||
Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, bounce);
|
|
||||||
|
|
||||||
if (is_inside_tree()) {
|
|
||||||
xform = get_global_transform() * xform;
|
|
||||||
RID space = get_world_2d()->get_space();
|
|
||||||
Physics2DServer::get_singleton()->body_set_space(q.body, space);
|
|
||||||
}
|
|
||||||
|
|
||||||
Physics2DServer::get_singleton()->body_set_state(q.body, Physics2DServer::BODY_STATE_TRANSFORM, xform);
|
|
||||||
|
|
||||||
rect_cache_dirty = true;
|
rect_cache_dirty = true;
|
||||||
quadrant_order_dirty = true;
|
quadrant_order_dirty = true;
|
||||||
@@ -612,7 +664,11 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons
|
|||||||
void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
|
void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
|
||||||
|
|
||||||
Quadrant &q = Q->get();
|
Quadrant &q = Q->get();
|
||||||
Physics2DServer::get_singleton()->free(q.body);
|
for (int i = 0; i < q.bodies.size(); i++) {
|
||||||
|
Physics2DServer::get_singleton()->free(q.bodies[i]);
|
||||||
|
}
|
||||||
|
q.bodies.clear();
|
||||||
|
|
||||||
for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
|
for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
|
||||||
|
|
||||||
VisualServer::get_singleton()->free(E->get());
|
VisualServer::get_singleton()->free(E->get());
|
||||||
@@ -865,7 +921,9 @@ void TileMap::set_collision_layer(uint32_t p_layer) {
|
|||||||
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
||||||
|
|
||||||
Quadrant &q = E->get();
|
Quadrant &q = E->get();
|
||||||
Physics2DServer::get_singleton()->body_set_layer_mask(q.body, collision_layer);
|
for (int i = q.bodies.size() - 1; i >= 0; i--) {
|
||||||
|
Physics2DServer::get_singleton()->body_set_layer_mask(q.bodies[i], collision_layer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -875,7 +933,9 @@ void TileMap::set_collision_mask(uint32_t p_mask) {
|
|||||||
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
||||||
|
|
||||||
Quadrant &q = E->get();
|
Quadrant &q = E->get();
|
||||||
Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask);
|
for (int i = q.bodies.size() - 1; i >= 0; i--) {
|
||||||
|
Physics2DServer::get_singleton()->body_set_collision_mask(q.bodies[i], collision_mask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,7 +977,9 @@ void TileMap::set_collision_friction(float p_friction) {
|
|||||||
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
||||||
|
|
||||||
Quadrant &q = E->get();
|
Quadrant &q = E->get();
|
||||||
Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, p_friction);
|
for (int i = q.bodies.size() - 1; i >= 0; i--) {
|
||||||
|
Physics2DServer::get_singleton()->body_set_param(q.bodies[i], Physics2DServer::BODY_PARAM_FRICTION, p_friction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -932,7 +994,9 @@ void TileMap::set_collision_bounce(float p_bounce) {
|
|||||||
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
|
||||||
|
|
||||||
Quadrant &q = E->get();
|
Quadrant &q = E->get();
|
||||||
Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, p_bounce);
|
for (int i = q.bodies.size() - 1; i >= 0; i--) {
|
||||||
|
Physics2DServer::get_singleton()->body_set_param(q.bodies[i], Physics2DServer::BODY_PARAM_BOUNCE, p_bounce);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float TileMap::get_collision_bounce() const {
|
float TileMap::get_collision_bounce() const {
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ private:
|
|||||||
|
|
||||||
Vector2 pos;
|
Vector2 pos;
|
||||||
List<RID> canvas_items;
|
List<RID> canvas_items;
|
||||||
RID body;
|
Vector<RID> bodies;
|
||||||
|
|
||||||
SelfList<Quadrant> dirty_list;
|
SelfList<Quadrant> dirty_list;
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ private:
|
|||||||
void operator=(const Quadrant &q) {
|
void operator=(const Quadrant &q) {
|
||||||
pos = q.pos;
|
pos = q.pos;
|
||||||
canvas_items = q.canvas_items;
|
canvas_items = q.canvas_items;
|
||||||
body = q.body;
|
bodies = q.bodies;
|
||||||
cells = q.cells;
|
cells = q.cells;
|
||||||
navpoly_ids = q.navpoly_ids;
|
navpoly_ids = q.navpoly_ids;
|
||||||
occluder_instances = q.occluder_instances;
|
occluder_instances = q.occluder_instances;
|
||||||
@@ -140,7 +140,7 @@ private:
|
|||||||
: dirty_list(this) {
|
: dirty_list(this) {
|
||||||
pos = q.pos;
|
pos = q.pos;
|
||||||
canvas_items = q.canvas_items;
|
canvas_items = q.canvas_items;
|
||||||
body = q.body;
|
bodies = q.bodies;
|
||||||
cells = q.cells;
|
cells = q.cells;
|
||||||
occluder_instances = q.occluder_instances;
|
occluder_instances = q.occluder_instances;
|
||||||
navpoly_ids = q.navpoly_ids;
|
navpoly_ids = q.navpoly_ids;
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
|
|||||||
tile_set_shape(id, p_value);
|
tile_set_shape(id, p_value);
|
||||||
else if (what == "shapes")
|
else if (what == "shapes")
|
||||||
_tile_set_shapes(id, p_value);
|
_tile_set_shapes(id, p_value);
|
||||||
|
else if (what == "one_way_collision_direction")
|
||||||
|
tile_set_one_way_collision_direction(id, p_value);
|
||||||
|
else if (what == "one_way_collision_max_depth")
|
||||||
|
tile_set_one_way_collision_max_depth(id, p_value);
|
||||||
else if (what == "occluder")
|
else if (what == "occluder")
|
||||||
tile_set_light_occluder(id, p_value);
|
tile_set_light_occluder(id, p_value);
|
||||||
else if (what == "occluder_offset")
|
else if (what == "occluder_offset")
|
||||||
@@ -103,6 +107,10 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
|
|||||||
r_ret = tile_get_shape(id);
|
r_ret = tile_get_shape(id);
|
||||||
else if (what == "shapes")
|
else if (what == "shapes")
|
||||||
r_ret = _tile_get_shapes(id);
|
r_ret = _tile_get_shapes(id);
|
||||||
|
else if (what == "one_way_collision_direction")
|
||||||
|
r_ret = tile_get_one_way_collision_direction(id);
|
||||||
|
else if (what == "one_way_collision_max_depth")
|
||||||
|
r_ret = tile_get_one_way_collision_max_depth(id);
|
||||||
else if (what == "occluder")
|
else if (what == "occluder")
|
||||||
r_ret = tile_get_light_occluder(id);
|
r_ret = tile_get_light_occluder(id);
|
||||||
else if (what == "occluder_offset")
|
else if (what == "occluder_offset")
|
||||||
@@ -136,6 +144,8 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||||||
p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_offset"));
|
p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "shape_offset"));
|
||||||
p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D", PROPERTY_USAGE_EDITOR));
|
p_list->push_back(PropertyInfo(Variant::OBJECT, pre + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape2D", PROPERTY_USAGE_EDITOR));
|
||||||
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "shapes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
|
p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "shapes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
|
||||||
|
p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "one_way_collision_direction"));
|
||||||
|
p_list->push_back(PropertyInfo(Variant::REAL, pre + "one_way_collision_max_depth"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,6 +350,30 @@ Array TileSet::_tile_get_shapes(int p_id) const {
|
|||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TileSet::tile_set_one_way_collision_direction(int p_id, Vector2 p_direction) {
|
||||||
|
|
||||||
|
ERR_FAIL_COND(!tile_map.has(p_id));
|
||||||
|
tile_map[p_id].one_way_collision_direction = p_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 TileSet::tile_get_one_way_collision_direction(int p_id) const {
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
|
||||||
|
return tile_map[p_id].one_way_collision_direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileSet::tile_set_one_way_collision_max_depth(int p_id, float p_max_depth) {
|
||||||
|
|
||||||
|
ERR_FAIL_COND(!tile_map.has(p_id));
|
||||||
|
tile_map[p_id].one_way_collision_max_depth = p_max_depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
float TileSet::tile_get_one_way_collision_max_depth(int p_id) const {
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(!tile_map.has(p_id), 0.0f);
|
||||||
|
return tile_map[p_id].one_way_collision_max_depth;
|
||||||
|
}
|
||||||
|
|
||||||
Array TileSet::_get_tiles_ids() const {
|
Array TileSet::_get_tiles_ids() const {
|
||||||
|
|
||||||
Array arr;
|
Array arr;
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ class TileSet : public Resource {
|
|||||||
Vector2 shape_offset;
|
Vector2 shape_offset;
|
||||||
Rect2i region;
|
Rect2i region;
|
||||||
Vector<Ref<Shape2D> > shapes;
|
Vector<Ref<Shape2D> > shapes;
|
||||||
|
Vector2 one_way_collision_direction;
|
||||||
|
float one_way_collision_max_depth;
|
||||||
Vector2 occluder_offset;
|
Vector2 occluder_offset;
|
||||||
Ref<OccluderPolygon2D> occluder;
|
Ref<OccluderPolygon2D> occluder;
|
||||||
Vector2 navigation_polygon_offset;
|
Vector2 navigation_polygon_offset;
|
||||||
@@ -55,9 +57,8 @@ class TileSet : public Resource {
|
|||||||
Ref<CanvasItemMaterial> material;
|
Ref<CanvasItemMaterial> material;
|
||||||
Color modulate;
|
Color modulate;
|
||||||
|
|
||||||
// Default modulate for back-compat
|
|
||||||
explicit Data()
|
explicit Data()
|
||||||
: modulate(1, 1, 1) {}
|
: one_way_collision_max_depth(0.0f), modulate(1, 1, 1) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Map<int, Data> tile_map;
|
Map<int, Data> tile_map;
|
||||||
@@ -114,6 +115,12 @@ public:
|
|||||||
void tile_set_shapes(int p_id, const Vector<Ref<Shape2D> > &p_shapes);
|
void tile_set_shapes(int p_id, const Vector<Ref<Shape2D> > &p_shapes);
|
||||||
Vector<Ref<Shape2D> > tile_get_shapes(int p_id) const;
|
Vector<Ref<Shape2D> > tile_get_shapes(int p_id) const;
|
||||||
|
|
||||||
|
void tile_set_one_way_collision_direction(int p_id, Vector2 p_direction);
|
||||||
|
Vector2 tile_get_one_way_collision_direction(int p_id) const;
|
||||||
|
|
||||||
|
void tile_set_one_way_collision_max_depth(int p_id, float p_max_depth);
|
||||||
|
float tile_get_one_way_collision_max_depth(int p_id) const;
|
||||||
|
|
||||||
void remove_tile(int p_id);
|
void remove_tile(int p_id);
|
||||||
|
|
||||||
bool has_tile(int p_id) const;
|
bool has_tile(int p_id) const;
|
||||||
|
|||||||
Reference in New Issue
Block a user