Further fixes to KinematicBody2D API, support for sync motion in moving objects
This commit is contained in:
parent
95d99cb2ac
commit
13a801430b
6 changed files with 142 additions and 24 deletions
|
@ -38,10 +38,14 @@ void CollisionObject2D::_notification(int p_what) {
|
||||||
|
|
||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
|
|
||||||
|
Transform2D global_transform = get_global_transform();
|
||||||
|
|
||||||
if (area)
|
if (area)
|
||||||
Physics2DServer::get_singleton()->area_set_transform(rid, get_global_transform());
|
Physics2DServer::get_singleton()->area_set_transform(rid, global_transform);
|
||||||
else
|
else
|
||||||
Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, get_global_transform());
|
Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, global_transform);
|
||||||
|
|
||||||
|
last_transform = global_transform;
|
||||||
|
|
||||||
RID space = get_world_2d()->get_space();
|
RID space = get_world_2d()->get_space();
|
||||||
if (area) {
|
if (area) {
|
||||||
|
@ -60,10 +64,18 @@ void CollisionObject2D::_notification(int p_what) {
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||||
|
|
||||||
|
Transform2D global_transform = get_global_transform();
|
||||||
|
|
||||||
|
if (only_update_transform_changes && global_transform == last_transform) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (area)
|
if (area)
|
||||||
Physics2DServer::get_singleton()->area_set_transform(rid, get_global_transform());
|
Physics2DServer::get_singleton()->area_set_transform(rid, global_transform);
|
||||||
else
|
else
|
||||||
Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, get_global_transform());
|
Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, global_transform);
|
||||||
|
|
||||||
|
last_transform = global_transform;
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_EXIT_TREE: {
|
case NOTIFICATION_EXIT_TREE: {
|
||||||
|
@ -318,6 +330,10 @@ void CollisionObject2D::_mouse_exit() {
|
||||||
emit_signal(SceneStringNames::get_singleton()->mouse_exited);
|
emit_signal(SceneStringNames::get_singleton()->mouse_exited);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CollisionObject2D::set_only_update_transform_changes(bool p_enable) {
|
||||||
|
only_update_transform_changes = p_enable;
|
||||||
|
}
|
||||||
|
|
||||||
void CollisionObject2D::_update_pickable() {
|
void CollisionObject2D::_update_pickable() {
|
||||||
if (!is_inside_tree())
|
if (!is_inside_tree())
|
||||||
return;
|
return;
|
||||||
|
@ -384,6 +400,7 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {
|
||||||
pickable = true;
|
pickable = true;
|
||||||
set_notify_transform(true);
|
set_notify_transform(true);
|
||||||
total_subshapes = 0;
|
total_subshapes = 0;
|
||||||
|
only_update_transform_changes = false;
|
||||||
|
|
||||||
if (p_area) {
|
if (p_area) {
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,8 @@ class CollisionObject2D : public Node2D {
|
||||||
int total_subshapes;
|
int total_subshapes;
|
||||||
|
|
||||||
Map<uint32_t, ShapeData> shapes;
|
Map<uint32_t, ShapeData> shapes;
|
||||||
|
Transform2D last_transform;
|
||||||
|
bool only_update_transform_changes; //this is used for sync physics in KinematicBody
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CollisionObject2D(RID p_rid, bool p_area);
|
CollisionObject2D(RID p_rid, bool p_area);
|
||||||
|
@ -78,6 +80,8 @@ protected:
|
||||||
void _mouse_enter();
|
void _mouse_enter();
|
||||||
void _mouse_exit();
|
void _mouse_exit();
|
||||||
|
|
||||||
|
void set_only_update_transform_changes(bool p_enable);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uint32_t create_shape_owner(Object *p_owner);
|
uint32_t create_shape_owner(Object *p_owner);
|
||||||
void remove_shape_owner(uint32_t owner);
|
void remove_shape_owner(uint32_t owner);
|
||||||
|
|
|
@ -130,7 +130,6 @@ void Node2D::_update_xform_values() {
|
||||||
|
|
||||||
void Node2D::_update_transform() {
|
void Node2D::_update_transform() {
|
||||||
|
|
||||||
Transform2D mat(angle, pos);
|
|
||||||
_mat.set_rotation_and_scale(angle, _scale);
|
_mat.set_rotation_and_scale(angle, _scale);
|
||||||
_mat.elements[2] = pos;
|
_mat.elements[2] = pos;
|
||||||
|
|
||||||
|
|
|
@ -971,11 +971,11 @@ RigidBody2D::~RigidBody2D() {
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes) {
|
Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) {
|
||||||
|
|
||||||
Collision col;
|
Collision col;
|
||||||
|
|
||||||
if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes)) {
|
if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) {
|
||||||
if (motion_cache.is_null()) {
|
if (motion_cache.is_null()) {
|
||||||
motion_cache.instance();
|
motion_cache.instance();
|
||||||
motion_cache->owner = this;
|
motion_cache->owner = this;
|
||||||
|
@ -1026,7 +1026,7 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes) {
|
bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) {
|
||||||
|
|
||||||
Transform2D gt = get_global_transform();
|
Transform2D gt = get_global_transform();
|
||||||
Physics2DServer::MotionResult result;
|
Physics2DServer::MotionResult result;
|
||||||
|
@ -1039,23 +1039,36 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
|
||||||
r_collision.collision = result.collision_point;
|
r_collision.collision = result.collision_point;
|
||||||
r_collision.normal = result.collision_normal;
|
r_collision.normal = result.collision_normal;
|
||||||
r_collision.collider = result.collider_id;
|
r_collision.collider = result.collider_id;
|
||||||
|
r_collision.collider_rid = result.collider;
|
||||||
r_collision.travel = result.motion;
|
r_collision.travel = result.motion;
|
||||||
r_collision.remainder = result.remainder;
|
r_collision.remainder = result.remainder;
|
||||||
r_collision.local_shape = result.collision_local_shape;
|
r_collision.local_shape = result.collision_local_shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
gt.elements[2] += result.motion;
|
if (!p_test_only) {
|
||||||
set_global_transform(gt);
|
gt.elements[2] += result.motion;
|
||||||
|
set_global_transform(gt);
|
||||||
|
}
|
||||||
|
|
||||||
return colliding;
|
return colliding;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
|
Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
|
||||||
|
|
||||||
Vector2 motion = (floor_velocity + p_linear_velocity) * get_physics_process_delta_time();
|
Vector2 floor_motion = floor_velocity;
|
||||||
|
if (on_floor && on_floor_body.is_valid()) {
|
||||||
|
//this approach makes sure there is less delay between the actual body velocity and the one we saved
|
||||||
|
Physics2DDirectBodyState *bs = Physics2DServer::get_singleton()->body_get_direct_state(on_floor_body);
|
||||||
|
if (bs) {
|
||||||
|
floor_motion = bs->get_linear_velocity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 motion = (floor_motion + p_linear_velocity) * get_physics_process_delta_time();
|
||||||
Vector2 lv = p_linear_velocity;
|
Vector2 lv = p_linear_velocity;
|
||||||
|
|
||||||
on_floor = false;
|
on_floor = false;
|
||||||
|
on_floor_body = RID();
|
||||||
on_ceiling = false;
|
on_ceiling = false;
|
||||||
on_wall = false;
|
on_wall = false;
|
||||||
colliders.clear();
|
colliders.clear();
|
||||||
|
@ -1096,6 +1109,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
|
||||||
if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
|
if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
|
||||||
|
|
||||||
on_floor = true;
|
on_floor = true;
|
||||||
|
on_floor_body = collision.collider_rid;
|
||||||
floor_velocity = collision.collider_vel;
|
floor_velocity = collision.collider_vel;
|
||||||
|
|
||||||
Vector2 rel_v = lv - floor_velocity;
|
Vector2 rel_v = lv - floor_velocity;
|
||||||
|
@ -1133,20 +1147,29 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KinematicBody2D::snap_to_floor(const Vector2 &p_direction, float p_floor_max_angle) {
|
Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
|
||||||
|
|
||||||
|
bool was_on_floor = on_floor;
|
||||||
|
|
||||||
|
Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_infinite_inertia, p_slope_stop_min_velocity, p_max_slides, p_floor_max_angle);
|
||||||
|
if (!was_on_floor || p_snap == Vector2()) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collision col;
|
||||||
Transform2D gt = get_global_transform();
|
Transform2D gt = get_global_transform();
|
||||||
Physics2DServer::MotionResult result;
|
|
||||||
bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_direction, false, margin, &result, false);
|
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
|
||||||
if (colliding) {
|
gt.elements[2] += col.travel;
|
||||||
gt.elements[2] += result.motion;
|
if (p_floor_direction != Vector2() && Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
|
||||||
if (Math::acos(p_direction.normalized().dot(-result.collision_normal)) < p_floor_max_angle) {
|
|
||||||
on_floor = true;
|
on_floor = true;
|
||||||
|
on_floor_body = col.collider_rid;
|
||||||
|
floor_velocity = col.collider_vel;
|
||||||
}
|
}
|
||||||
set_global_transform(gt);
|
set_global_transform(gt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return colliding;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KinematicBody2D::is_on_floor() const {
|
bool KinematicBody2D::is_on_floor() const {
|
||||||
|
@ -1210,11 +1233,60 @@ Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) {
|
||||||
return slide_colliders[p_bounce];
|
return slide_colliders[p_bounce];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KinematicBody2D::set_sync_to_physics(bool p_enable) {
|
||||||
|
|
||||||
|
if (sync_to_physics == p_enable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sync_to_physics = p_enable;
|
||||||
|
if (p_enable) {
|
||||||
|
Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
|
||||||
|
set_only_update_transform_changes(true);
|
||||||
|
set_notify_local_transform(true);
|
||||||
|
} else {
|
||||||
|
Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, "");
|
||||||
|
set_only_update_transform_changes(false);
|
||||||
|
set_notify_local_transform(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KinematicBody2D::is_sync_to_physics_enabled() const {
|
||||||
|
return sync_to_physics;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KinematicBody2D::_direct_state_changed(Object *p_state) {
|
||||||
|
|
||||||
|
if (!sync_to_physics)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Physics2DDirectBodyState *state = Object::cast_to<Physics2DDirectBodyState>(p_state);
|
||||||
|
|
||||||
|
last_valid_transform = state->get_transform();
|
||||||
|
set_notify_local_transform(false);
|
||||||
|
set_global_transform(last_valid_transform);
|
||||||
|
set_notify_local_transform(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KinematicBody2D::_notification(int p_what) {
|
||||||
|
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||||
|
last_valid_transform = get_global_transform();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
|
||||||
|
//used by sync to physics, send the new transform to the physics
|
||||||
|
Transform2D new_transform = get_global_transform();
|
||||||
|
Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_TRANSFORM, new_transform);
|
||||||
|
//but then revert changes
|
||||||
|
set_notify_local_transform(false);
|
||||||
|
set_global_transform(last_valid_transform);
|
||||||
|
set_notify_local_transform(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
void KinematicBody2D::_bind_methods() {
|
void KinematicBody2D::_bind_methods() {
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true));
|
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
|
||||||
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
|
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
|
||||||
ClassDB::bind_method(D_METHOD("snap_to_floor", "motion", "max_floor_angle"), &KinematicBody2D::snap_to_floor, DEFVAL(Math::deg2rad(45.0)));
|
ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move);
|
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move);
|
||||||
|
|
||||||
|
@ -1229,7 +1301,13 @@ void KinematicBody2D::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody2D::get_slide_count);
|
ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody2D::get_slide_count);
|
||||||
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody2D::_get_slide_collision);
|
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody2D::_get_slide_collision);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_sync_to_physics", "enable"), &KinematicBody2D::set_sync_to_physics);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_sync_to_physics_enabled"), &KinematicBody2D::is_sync_to_physics_enabled);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody2D::_direct_state_changed);
|
||||||
|
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "motion/sync_to_physics"), "set_sync_to_physics", "is_sync_to_physics_enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
KinematicBody2D::KinematicBody2D() :
|
KinematicBody2D::KinematicBody2D() :
|
||||||
|
@ -1240,6 +1318,7 @@ KinematicBody2D::KinematicBody2D() :
|
||||||
on_floor = false;
|
on_floor = false;
|
||||||
on_ceiling = false;
|
on_ceiling = false;
|
||||||
on_wall = false;
|
on_wall = false;
|
||||||
|
sync_to_physics = false;
|
||||||
}
|
}
|
||||||
KinematicBody2D::~KinematicBody2D() {
|
KinematicBody2D::~KinematicBody2D() {
|
||||||
if (motion_cache.is_valid()) {
|
if (motion_cache.is_valid()) {
|
||||||
|
|
|
@ -276,6 +276,7 @@ public:
|
||||||
Vector2 normal;
|
Vector2 normal;
|
||||||
Vector2 collider_vel;
|
Vector2 collider_vel;
|
||||||
ObjectID collider;
|
ObjectID collider;
|
||||||
|
RID collider_rid;
|
||||||
int collider_shape;
|
int collider_shape;
|
||||||
Variant collider_metadata;
|
Variant collider_metadata;
|
||||||
Vector2 remainder;
|
Vector2 remainder;
|
||||||
|
@ -287,9 +288,11 @@ private:
|
||||||
float margin;
|
float margin;
|
||||||
|
|
||||||
Vector2 floor_velocity;
|
Vector2 floor_velocity;
|
||||||
|
RID on_floor_body;
|
||||||
bool on_floor;
|
bool on_floor;
|
||||||
bool on_ceiling;
|
bool on_ceiling;
|
||||||
bool on_wall;
|
bool on_wall;
|
||||||
|
bool sync_to_physics;
|
||||||
|
|
||||||
Vector<Collision> colliders;
|
Vector<Collision> colliders;
|
||||||
Vector<Ref<KinematicCollision2D> > slide_colliders;
|
Vector<Ref<KinematicCollision2D> > slide_colliders;
|
||||||
|
@ -297,15 +300,19 @@ private:
|
||||||
|
|
||||||
_FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const;
|
_FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const;
|
||||||
|
|
||||||
Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true);
|
Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
|
||||||
Ref<KinematicCollision2D> _get_slide_collision(int p_bounce);
|
Ref<KinematicCollision2D> _get_slide_collision(int p_bounce);
|
||||||
|
|
||||||
|
Transform2D last_valid_transform;
|
||||||
|
void _direct_state_changed(Object *p_state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void _notification(int p_what);
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true);
|
bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
|
||||||
bool snap_to_floor(const Vector2 &p_direction, float p_floor_max_angle = Math::deg2rad((float)45));
|
|
||||||
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia);
|
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia);
|
||||||
|
|
||||||
bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision);
|
bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision);
|
||||||
|
@ -314,6 +321,7 @@ public:
|
||||||
float get_safe_margin() const;
|
float get_safe_margin() const;
|
||||||
|
|
||||||
Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
|
Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
|
||||||
|
Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
|
||||||
bool is_on_floor() const;
|
bool is_on_floor() const;
|
||||||
bool is_on_wall() const;
|
bool is_on_wall() const;
|
||||||
bool is_on_ceiling() const;
|
bool is_on_ceiling() const;
|
||||||
|
@ -322,6 +330,9 @@ public:
|
||||||
int get_slide_count() const;
|
int get_slide_count() const;
|
||||||
Collision get_slide_collision(int p_bounce) const;
|
Collision get_slide_collision(int p_bounce) const;
|
||||||
|
|
||||||
|
void set_sync_to_physics(bool p_enable);
|
||||||
|
bool is_sync_to_physics_enabled() const;
|
||||||
|
|
||||||
KinematicBody2D();
|
KinematicBody2D();
|
||||||
~KinematicBody2D();
|
~KinematicBody2D();
|
||||||
};
|
};
|
||||||
|
|
|
@ -984,10 +984,18 @@ int Physics2DServerSW::body_test_ray_separation(RID p_body, const Transform2D &p
|
||||||
|
|
||||||
Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) {
|
Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) {
|
||||||
|
|
||||||
|
if ((using_threads && !doing_sync)) {
|
||||||
|
ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
|
||||||
|
ERR_FAIL_V(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!body_owner.owns(p_body))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
Body2DSW *body = body_owner.get(p_body);
|
Body2DSW *body = body_owner.get(p_body);
|
||||||
ERR_FAIL_COND_V(!body, NULL);
|
ERR_FAIL_COND_V(!body, NULL);
|
||||||
|
|
||||||
if ((using_threads && !doing_sync) || body->get_space()->is_locked()) {
|
if (body->get_space()->is_locked()) {
|
||||||
|
|
||||||
ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
|
ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
|
||||||
ERR_FAIL_V(NULL);
|
ERR_FAIL_V(NULL);
|
||||||
|
|
Loading…
Reference in a new issue