Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KinematicBody: backport the setting moving_platform_apply_velocity_on_leave to 3.x #56569

Merged
merged 1 commit into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions doc/classes/KinematicBody.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,19 @@
<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].
</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>
<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>
</class>
12 changes: 12 additions & 0 deletions doc/classes/KinematicBody2D.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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">
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 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>
<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>
</class>
26 changes: 24 additions & 2 deletions scene/2d/physics_body_2d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
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;
Expand Down Expand Up @@ -1307,6 +1312,14 @@ Vector2 KinematicBody2D::get_floor_velocity() const {
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) {
ERR_FAIL_COND_V(!is_inside_tree(), false);

Expand Down Expand Up @@ -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("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_collision", "slide_idx"), &KinematicBody2D::_get_slide_collision);
ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &KinematicBody2D::_get_last_slide_collision);
Expand All @@ -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::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() :
Expand Down
10 changes: 10 additions & 0 deletions scene/2d/physics_body_2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@ class KinematicBody2D : public PhysicsBody2D {
GDCLASS(KinematicBody2D, PhysicsBody2D);

public:
enum MovingPlatformApplyVelocityOnLeave {
PLATFORM_VEL_ON_LEAVE_ALWAYS,
PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY,
PLATFORM_VEL_ON_LEAVE_NEVER,
};
struct Collision {
Vector2 collision;
Vector2 normal;
Expand Down Expand Up @@ -294,6 +299,7 @@ class KinematicBody2D : public PhysicsBody2D {
bool on_ceiling;
bool on_wall;
bool sync_to_physics;
MovingPlatformApplyVelocityOnLeave moving_platform_apply_velocity_on_leave = PLATFORM_VEL_ON_LEAVE_ALWAYS;

Vector<Collision> colliders;
Vector<Ref<KinematicCollision2D>> slide_colliders;
Expand All @@ -307,6 +313,8 @@ class KinematicBody2D : public PhysicsBody2D {
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);
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:
void _notification(int p_what);
Expand Down Expand Up @@ -341,6 +349,8 @@ class KinematicBody2D : public PhysicsBody2D {
~KinematicBody2D();
};

VARIANT_ENUM_CAST(KinematicBody2D::MovingPlatformApplyVelocityOnLeave);

class KinematicCollision2D : public Reference {
GDCLASS(KinematicCollision2D, Reference);

Expand Down
26 changes: 24 additions & 2 deletions scene/3d/physics_body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
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;
Expand Down Expand Up @@ -1256,6 +1261,14 @@ Vector3 KinematicBody::get_floor_velocity() const {
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) {
ERR_FAIL_COND_V(!is_inside_tree(), false);

Expand Down Expand Up @@ -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("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_collision", "slide_idx"), &KinematicBody::_get_slide_collision);
ClassDB::bind_method(D_METHOD("get_last_slide_collision"), &KinematicBody::_get_last_slide_collision);
Expand All @@ -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::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() :
Expand Down
11 changes: 11 additions & 0 deletions scene/3d/physics_body.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,11 @@ class KinematicBody : public PhysicsBody {
GDCLASS(KinematicBody, PhysicsBody);

public:
enum MovingPlatformApplyVelocityOnLeave {
PLATFORM_VEL_ON_LEAVE_ALWAYS,
PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY,
PLATFORM_VEL_ON_LEAVE_NEVER,
};
struct Collision {
Vector3 collision;
Vector3 normal;
Expand Down Expand Up @@ -291,6 +296,8 @@ class KinematicBody : public PhysicsBody {
bool on_ceiling;
bool on_wall;
bool sync_to_physics = false;
MovingPlatformApplyVelocityOnLeave moving_platform_apply_velocity_on_leave = PLATFORM_VEL_ON_LEAVE_ALWAYS;

Vector<Collision> colliders;
Vector<Ref<KinematicCollision>> slide_colliders;
Ref<KinematicCollision> motion_cache;
Expand All @@ -304,6 +311,8 @@ class KinematicBody : public PhysicsBody {

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_moving_platform_apply_velocity_on_leave(MovingPlatformApplyVelocityOnLeave p_on_leave_velocity);
MovingPlatformApplyVelocityOnLeave get_moving_platform_apply_velocity_on_leave() const;

protected:
void _notification(int p_what);
Expand Down Expand Up @@ -340,6 +349,8 @@ class KinematicBody : public PhysicsBody {
~KinematicBody();
};

VARIANT_ENUM_CAST(KinematicBody::MovingPlatformApplyVelocityOnLeave);

class KinematicCollision : public Reference {
GDCLASS(KinematicCollision, Reference);

Expand Down