Merge pull request #56569 from fabriceci/platform-leave-backport-3x
This commit is contained in:
commit
0392f254a3
@ -172,7 +172,19 @@
|
|||||||
<member name="move_lock_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
|
<member name="move_lock_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
|
||||||
Lock the body's Z axis movement. Deprecated alias for [member axis_lock_motion_z].
|
Lock the body's Z axis movement. Deprecated alias for [member axis_lock_motion_z].
|
||||||
</member>
|
</member>
|
||||||
|
<member name="moving_platform_apply_velocity_on_leave" type="int" setter="set_moving_platform_apply_velocity_on_leave" getter="get_moving_platform_apply_velocity_on_leave" enum="KinematicBody.MovingPlatformApplyVelocityOnLeave" default="0">
|
||||||
|
Sets the behaviour to apply when you leave a moving platform. By default, to be physically accurate, when you leave the last platform velocity is applied. See [enum MovingPlatformApplyVelocityOnLeave] constants for available behaviour.
|
||||||
|
</member>
|
||||||
</members>
|
</members>
|
||||||
<constants>
|
<constants>
|
||||||
|
<constant name="PLATFORM_VEL_ON_LEAVE_ALWAYS" value="0" enum="MovingPlatformApplyVelocityOnLeave">
|
||||||
|
Add the last platform velocity when you leave a moving platform.
|
||||||
|
</constant>
|
||||||
|
<constant name="PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY" value="1" enum="MovingPlatformApplyVelocityOnLeave">
|
||||||
|
Add the last platform velocity when you leave a moving platform, but any downward motion is ignored. It's useful to keep full jump height even when the platform is moving down.
|
||||||
|
</constant>
|
||||||
|
<constant name="PLATFORM_VEL_ON_LEAVE_NEVER" value="2" enum="MovingPlatformApplyVelocityOnLeave">
|
||||||
|
Do nothing when leaving a platform.
|
||||||
|
</constant>
|
||||||
</constants>
|
</constants>
|
||||||
</class>
|
</class>
|
||||||
|
@ -144,7 +144,19 @@
|
|||||||
<member name="motion/sync_to_physics" type="bool" setter="set_sync_to_physics" getter="is_sync_to_physics_enabled" default="false">
|
<member name="motion/sync_to_physics" type="bool" setter="set_sync_to_physics" getter="is_sync_to_physics_enabled" default="false">
|
||||||
If [code]true[/code], the body's movement will be synchronized to the physics frame. This is useful when animating movement via [AnimationPlayer], for example on moving platforms. Do [b]not[/b] use together with [method move_and_slide] or [method move_and_collide] functions.
|
If [code]true[/code], the body's movement will be synchronized to the physics frame. This is useful when animating movement via [AnimationPlayer], for example on moving platforms. Do [b]not[/b] use together with [method move_and_slide] or [method move_and_collide] functions.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="moving_platform_apply_velocity_on_leave" type="int" setter="set_moving_platform_apply_velocity_on_leave" getter="get_moving_platform_apply_velocity_on_leave" enum="KinematicBody2D.MovingPlatformApplyVelocityOnLeave" default="0">
|
||||||
|
Sets the behaviour to apply when you leave a moving platform. By default, to be physically accurate, when you leave the last platform velocity is applied. See [enum MovingPlatformApplyVelocityOnLeave] constants for available behaviour.
|
||||||
|
</member>
|
||||||
</members>
|
</members>
|
||||||
<constants>
|
<constants>
|
||||||
|
<constant name="PLATFORM_VEL_ON_LEAVE_ALWAYS" value="0" enum="MovingPlatformApplyVelocityOnLeave">
|
||||||
|
Add the last platform velocity when you leave a moving platform.
|
||||||
|
</constant>
|
||||||
|
<constant name="PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY" value="1" enum="MovingPlatformApplyVelocityOnLeave">
|
||||||
|
Add the last platform velocity when you leave a moving platform, but any downward motion is ignored. It's useful to keep full jump height even when the platform is moving down.
|
||||||
|
</constant>
|
||||||
|
<constant name="PLATFORM_VEL_ON_LEAVE_NEVER" value="2" enum="MovingPlatformApplyVelocityOnLeave">
|
||||||
|
Do nothing when leaving a platform.
|
||||||
|
</constant>
|
||||||
</constants>
|
</constants>
|
||||||
</class>
|
</class>
|
||||||
|
@ -1250,9 +1250,14 @@ Vector2 KinematicBody2D::_move_and_slide_internal(const Vector2 &p_linear_veloci
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!on_floor) {
|
if (moving_platform_apply_velocity_on_leave != PLATFORM_VEL_ON_LEAVE_NEVER) {
|
||||||
// Add last platform velocity when just left a moving platform.
|
// Add last platform velocity when just left a moving platform.
|
||||||
return body_velocity + current_floor_velocity;
|
if (!on_floor) {
|
||||||
|
if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_floor_velocity.dot(up_direction) < 0) {
|
||||||
|
current_floor_velocity = current_floor_velocity.slide(up_direction);
|
||||||
|
}
|
||||||
|
return body_velocity + current_floor_velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return body_velocity;
|
return body_velocity;
|
||||||
@ -1307,6 +1312,14 @@ Vector2 KinematicBody2D::get_floor_velocity() const {
|
|||||||
return floor_velocity;
|
return floor_velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KinematicBody2D::set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_apply_velocity) {
|
||||||
|
moving_platform_apply_velocity_on_leave = p_on_leave_apply_velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
KinematicBody2D::MovingPlatformApplyVelocityOnLeave KinematicBody2D::get_moving_platform_apply_velocity_on_leave() const {
|
||||||
|
return moving_platform_apply_velocity_on_leave;
|
||||||
|
}
|
||||||
|
|
||||||
bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia) {
|
bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia) {
|
||||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||||
|
|
||||||
@ -1440,6 +1453,9 @@ void KinematicBody2D::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin);
|
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin);
|
||||||
ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody2D::get_safe_margin);
|
ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody2D::get_safe_margin);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_moving_platform_apply_velocity_on_leave", "on_leave_apply_velocity"), &KinematicBody2D::set_moving_platform_apply_velocity_on_leave);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_moving_platform_apply_velocity_on_leave"), &KinematicBody2D::get_moving_platform_apply_velocity_on_leave);
|
||||||
|
|
||||||
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("get_last_slide_collision"), &KinematicBody2D::_get_last_slide_collision);
|
ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &KinematicBody2D::_get_last_slide_collision);
|
||||||
@ -1451,6 +1467,12 @@ void KinematicBody2D::_bind_methods() {
|
|||||||
|
|
||||||
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");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "motion/sync_to_physics"), "set_sync_to_physics", "is_sync_to_physics_enabled");
|
||||||
|
ADD_GROUP("Moving platform", "moving_platform");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_apply_velocity_on_leave", PROPERTY_HINT_ENUM, "Always,Upward Only,Never", PROPERTY_USAGE_DEFAULT), "set_moving_platform_apply_velocity_on_leave", "get_moving_platform_apply_velocity_on_leave");
|
||||||
|
|
||||||
|
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_ALWAYS);
|
||||||
|
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY);
|
||||||
|
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_NEVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
KinematicBody2D::KinematicBody2D() :
|
KinematicBody2D::KinematicBody2D() :
|
||||||
|
@ -267,6 +267,11 @@ class KinematicBody2D : public PhysicsBody2D {
|
|||||||
GDCLASS(KinematicBody2D, PhysicsBody2D);
|
GDCLASS(KinematicBody2D, PhysicsBody2D);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum MovingPlatformApplyVelocityOnLeave {
|
||||||
|
PLATFORM_VEL_ON_LEAVE_ALWAYS,
|
||||||
|
PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY,
|
||||||
|
PLATFORM_VEL_ON_LEAVE_NEVER,
|
||||||
|
};
|
||||||
struct Collision {
|
struct Collision {
|
||||||
Vector2 collision;
|
Vector2 collision;
|
||||||
Vector2 normal;
|
Vector2 normal;
|
||||||
@ -294,6 +299,7 @@ private:
|
|||||||
bool on_ceiling;
|
bool on_ceiling;
|
||||||
bool on_wall;
|
bool on_wall;
|
||||||
bool sync_to_physics;
|
bool sync_to_physics;
|
||||||
|
MovingPlatformApplyVelocityOnLeave moving_platform_apply_velocity_on_leave = PLATFORM_VEL_ON_LEAVE_ALWAYS;
|
||||||
|
|
||||||
Vector<Collision> colliders;
|
Vector<Collision> colliders;
|
||||||
Vector<Ref<KinematicCollision2D>> slide_colliders;
|
Vector<Ref<KinematicCollision2D>> slide_colliders;
|
||||||
@ -307,6 +313,8 @@ private:
|
|||||||
void _direct_state_changed(Object *p_state);
|
void _direct_state_changed(Object *p_state);
|
||||||
Vector2 _move_and_slide_internal(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
|
Vector2 _move_and_slide_internal(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction = Vector2(0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
|
||||||
void _set_collision_direction(const Collision &p_collision, const Vector2 &p_up_direction, float p_floor_max_angle);
|
void _set_collision_direction(const Collision &p_collision, const Vector2 &p_up_direction, float p_floor_max_angle);
|
||||||
|
void set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity);
|
||||||
|
MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
@ -341,6 +349,8 @@ public:
|
|||||||
~KinematicBody2D();
|
~KinematicBody2D();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VARIANT_ENUM_CAST(KinematicBody2D::MovingPlatformApplyVelocityOnLeave);
|
||||||
|
|
||||||
class KinematicCollision2D : public Reference {
|
class KinematicCollision2D : public Reference {
|
||||||
GDCLASS(KinematicCollision2D, Reference);
|
GDCLASS(KinematicCollision2D, Reference);
|
||||||
|
|
||||||
|
@ -1198,9 +1198,14 @@ Vector3 KinematicBody::_move_and_slide_internal(const Vector3 &p_linear_velocity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!on_floor) {
|
if (moving_platform_apply_velocity_on_leave != PLATFORM_VEL_ON_LEAVE_NEVER) {
|
||||||
// Add last platform velocity when just left a moving platform.
|
// Add last platform velocity when just left a moving platform.
|
||||||
return body_velocity + current_floor_velocity;
|
if (!on_floor) {
|
||||||
|
if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_floor_velocity.dot(up_direction) < 0) {
|
||||||
|
current_floor_velocity = current_floor_velocity.slide(up_direction);
|
||||||
|
}
|
||||||
|
return body_velocity + current_floor_velocity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return body_velocity;
|
return body_velocity;
|
||||||
@ -1256,6 +1261,14 @@ Vector3 KinematicBody::get_floor_velocity() const {
|
|||||||
return floor_velocity;
|
return floor_velocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KinematicBody::set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_apply_velocity) {
|
||||||
|
moving_platform_apply_velocity_on_leave = p_on_leave_apply_velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
KinematicBody::MovingPlatformApplyVelocityOnLeave KinematicBody::get_moving_platform_apply_velocity_on_leave() const {
|
||||||
|
return moving_platform_apply_velocity_on_leave;
|
||||||
|
}
|
||||||
|
|
||||||
bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia) {
|
bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia) {
|
||||||
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
ERR_FAIL_COND_V(!is_inside_tree(), false);
|
||||||
|
|
||||||
@ -1445,6 +1458,9 @@ void KinematicBody::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin);
|
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin);
|
||||||
ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin);
|
ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_moving_platform_apply_velocity_on_leave", "on_leave_apply_velocity"), &KinematicBody::set_moving_platform_apply_velocity_on_leave);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_moving_platform_apply_velocity_on_leave"), &KinematicBody::get_moving_platform_apply_velocity_on_leave);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count);
|
ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count);
|
||||||
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision);
|
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision);
|
||||||
ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &KinematicBody::_get_last_slide_collision);
|
ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &KinematicBody::_get_last_slide_collision);
|
||||||
@ -1464,6 +1480,12 @@ void KinematicBody::_bind_methods() {
|
|||||||
|
|
||||||
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");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "motion/sync_to_physics"), "set_sync_to_physics", "is_sync_to_physics_enabled");
|
||||||
|
ADD_GROUP("Moving platform", "moving_platform");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_apply_velocity_on_leave", PROPERTY_HINT_ENUM, "Always,Upward Only,Never", PROPERTY_USAGE_DEFAULT), "set_moving_platform_apply_velocity_on_leave", "get_moving_platform_apply_velocity_on_leave");
|
||||||
|
|
||||||
|
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_ALWAYS);
|
||||||
|
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY);
|
||||||
|
BIND_ENUM_CONSTANT(PLATFORM_VEL_ON_LEAVE_NEVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
KinematicBody::KinematicBody() :
|
KinematicBody::KinematicBody() :
|
||||||
|
@ -262,6 +262,11 @@ class KinematicBody : public PhysicsBody {
|
|||||||
GDCLASS(KinematicBody, PhysicsBody);
|
GDCLASS(KinematicBody, PhysicsBody);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum MovingPlatformApplyVelocityOnLeave {
|
||||||
|
PLATFORM_VEL_ON_LEAVE_ALWAYS,
|
||||||
|
PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY,
|
||||||
|
PLATFORM_VEL_ON_LEAVE_NEVER,
|
||||||
|
};
|
||||||
struct Collision {
|
struct Collision {
|
||||||
Vector3 collision;
|
Vector3 collision;
|
||||||
Vector3 normal;
|
Vector3 normal;
|
||||||
@ -291,6 +296,8 @@ private:
|
|||||||
bool on_ceiling;
|
bool on_ceiling;
|
||||||
bool on_wall;
|
bool on_wall;
|
||||||
bool sync_to_physics = false;
|
bool sync_to_physics = false;
|
||||||
|
MovingPlatformApplyVelocityOnLeave moving_platform_apply_velocity_on_leave = PLATFORM_VEL_ON_LEAVE_ALWAYS;
|
||||||
|
|
||||||
Vector<Collision> colliders;
|
Vector<Collision> colliders;
|
||||||
Vector<Ref<KinematicCollision>> slide_colliders;
|
Vector<Ref<KinematicCollision>> slide_colliders;
|
||||||
Ref<KinematicCollision> motion_cache;
|
Ref<KinematicCollision> motion_cache;
|
||||||
@ -304,6 +311,8 @@ private:
|
|||||||
|
|
||||||
Vector3 _move_and_slide_internal(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
|
Vector3 _move_and_slide_internal(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45), bool p_infinite_inertia = true);
|
||||||
void _set_collision_direction(const Collision &p_collision, const Vector3 &p_up_direction, float p_floor_max_angle);
|
void _set_collision_direction(const Collision &p_collision, const Vector3 &p_up_direction, float p_floor_max_angle);
|
||||||
|
void set_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity);
|
||||||
|
MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
@ -340,6 +349,8 @@ public:
|
|||||||
~KinematicBody();
|
~KinematicBody();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VARIANT_ENUM_CAST(KinematicBody::MovingPlatformApplyVelocityOnLeave);
|
||||||
|
|
||||||
class KinematicCollision : public Reference {
|
class KinematicCollision : public Reference {
|
||||||
GDCLASS(KinematicCollision, Reference);
|
GDCLASS(KinematicCollision, Reference);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user