Backport new methods for KinematicBody and KinematicCollision

For both 2D and 3D, three methods are added:

- `get_floor_angle` on `KinematicBody` to get the floor angle.
- `get_angle` on `KinematicCollision` to get the collision angle.
- `get_last_slide_collision` to quickly get the latest collision of `move_and_slide`.
This commit is contained in:
Haoyu Qiu 2021-08-26 12:16:40 +08:00
parent 46ad2560a1
commit 5183c473f7
8 changed files with 96 additions and 0 deletions

View File

@ -23,6 +23,13 @@
Returns [code]true[/code] if the specified [code]axis[/code] is locked. See also [member move_lock_x], [member move_lock_y] and [member move_lock_z].
</description>
</method>
<method name="get_floor_angle" qualifiers="const">
<return type="float" />
<argument index="0" name="up_direction" type="Vector3" default="Vector3( 0, 1, 0 )" />
<description>
Returns the floor's collision angle at the last collision point according to [code]up_direction[/code], which is [code]Vector3.UP[/code] by default. This value is always positive and only valid after calling [method move_and_slide] and when [method is_on_floor] returns [code]true[/code].
</description>
</method>
<method name="get_floor_normal" qualifiers="const">
<return type="Vector3" />
<description>
@ -35,6 +42,12 @@
Returns the linear velocity of the floor at the last collision point. Only valid after calling [method move_and_slide] or [method move_and_slide_with_snap] and when [method is_on_floor] returns [code]true[/code].
</description>
</method>
<method name="get_last_slide_collision">
<return type="KinematicCollision" />
<description>
Returns a [KinematicCollision], which contains information about the latest collision that occurred during the last call to [method move_and_slide].
</description>
</method>
<method name="get_slide_collision">
<return type="KinematicCollision" />
<argument index="0" name="slide_idx" type="int" />

View File

@ -15,6 +15,13 @@
<link title="2D Platformer Demo">https://godotengine.org/asset-library/asset/120</link>
</tutorials>
<methods>
<method name="get_floor_angle" qualifiers="const">
<return type="float" />
<argument index="0" name="up_direction" type="Vector2" default="Vector2( 0, -1 )" />
<description>
Returns the floor's collision angle at the last collision point according to [code]up_direction[/code], which is [code]Vector2.UP[/code] by default. This value is always positive and only valid after calling [method move_and_slide] and when [method is_on_floor] returns [code]true[/code].
</description>
</method>
<method name="get_floor_normal" qualifiers="const">
<return type="Vector2" />
<description>
@ -27,6 +34,12 @@
Returns the linear velocity of the floor at the last collision point. Only valid after calling [method move_and_slide] or [method move_and_slide_with_snap] and when [method is_on_floor] returns [code]true[/code].
</description>
</method>
<method name="get_last_slide_collision">
<return type="KinematicCollision2D" />
<description>
Returns a [KinematicCollision2D], which contains information about the latest collision that occurred during the last call to [method move_and_slide].
</description>
</method>
<method name="get_slide_collision">
<return type="KinematicCollision2D" />
<argument index="0" name="slide_idx" type="int" />

View File

@ -10,6 +10,13 @@
<tutorials>
</tutorials>
<methods>
<method name="get_angle" qualifiers="const">
<return type="float" />
<argument index="0" name="up_direction" type="Vector3" default="Vector3( 0, 1, 0 )" />
<description>
The collision angle according to [code]up_direction[/code], which is [code]Vector3.UP[/code] by default. This value is always positive.
</description>
</method>
</methods>
<members>
<member name="collider" type="Object" setter="" getter="get_collider">

View File

@ -10,6 +10,13 @@
<tutorials>
</tutorials>
<methods>
<method name="get_angle" qualifiers="const">
<return type="float" />
<argument index="0" name="up_direction" type="Vector2" default="Vector2( 0, -1 )" />
<description>
The collision angle according to [code]up_direction[/code], which is [code]Vector2.UP[/code] by default. This value is always positive.
</description>
</method>
</methods>
<members>
<member name="collider" type="Object" setter="" getter="get_collider">

View File

@ -1281,6 +1281,11 @@ Vector2 KinematicBody2D::get_floor_normal() const {
return floor_normal;
}
real_t KinematicBody2D::get_floor_angle(const Vector2 &p_up_direction) const {
ERR_FAIL_COND_V(p_up_direction == Vector2(), 0);
return Math::acos(floor_normal.dot(p_up_direction));
}
Vector2 KinematicBody2D::get_floor_velocity() const {
return floor_velocity;
}
@ -1323,6 +1328,13 @@ Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) {
return slide_colliders[p_bounce];
}
Ref<KinematicCollision2D> KinematicBody2D::_get_last_slide_collision() {
if (colliders.size() == 0) {
return Ref<KinematicCollision2D>();
}
return _get_slide_collision(colliders.size() - 1);
}
void KinematicBody2D::set_sync_to_physics(bool p_enable) {
if (sync_to_physics == p_enable) {
return;
@ -1396,6 +1408,7 @@ void KinematicBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody2D::is_on_ceiling);
ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody2D::is_on_wall);
ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody2D::get_floor_normal);
ClassDB::bind_method(D_METHOD("get_floor_angle", "up_direction"), &KinematicBody2D::get_floor_angle, DEFVAL(Vector2(0.0, -1.0)));
ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody2D::get_floor_velocity);
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody2D::set_safe_margin);
@ -1403,6 +1416,7 @@ void KinematicBody2D::_bind_methods() {
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);
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);
@ -1448,6 +1462,12 @@ Vector2 KinematicCollision2D::get_travel() const {
Vector2 KinematicCollision2D::get_remainder() const {
return collision.remainder;
}
real_t KinematicCollision2D::get_angle(const Vector2 &p_up_direction) const {
ERR_FAIL_COND_V(p_up_direction == Vector2(), 0);
return collision.get_angle(p_up_direction);
}
Object *KinematicCollision2D::get_local_shape() const {
if (!owner) {
return nullptr;
@ -1496,6 +1516,7 @@ void KinematicCollision2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision2D::get_normal);
ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision2D::get_travel);
ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision2D::get_remainder);
ClassDB::bind_method(D_METHOD("get_angle", "up_direction"), &KinematicCollision2D::get_angle, DEFVAL(Vector2(0.0, -1.0)));
ClassDB::bind_method(D_METHOD("get_local_shape"), &KinematicCollision2D::get_local_shape);
ClassDB::bind_method(D_METHOD("get_collider"), &KinematicCollision2D::get_collider);
ClassDB::bind_method(D_METHOD("get_collider_id"), &KinematicCollision2D::get_collider_id);

View File

@ -280,6 +280,10 @@ public:
Vector2 remainder;
Vector2 travel;
int local_shape;
real_t get_angle(const Vector2 &p_up_direction) const {
return Math::acos(normal.dot(p_up_direction));
}
};
private:
@ -299,6 +303,7 @@ private:
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_last_slide_collision();
Transform2D last_valid_transform;
void _direct_state_changed(Object *p_state);
@ -325,6 +330,7 @@ public:
bool is_on_wall() const;
bool is_on_ceiling() const;
Vector2 get_floor_normal() const;
real_t get_floor_angle(const Vector2 &p_up_direction = Vector2(0.0, -1.0)) const;
Vector2 get_floor_velocity() const;
int get_slide_count() const;
@ -352,6 +358,7 @@ public:
Vector2 get_normal() const;
Vector2 get_travel() const;
Vector2 get_remainder() const;
real_t get_angle(const Vector2 &p_up_direction = Vector2(0.0, -1.0)) const;
Object *get_local_shape() const;
Object *get_collider() const;
ObjectID get_collider_id() const;

View File

@ -1242,6 +1242,11 @@ Vector3 KinematicBody::get_floor_normal() const {
return floor_normal;
}
real_t KinematicBody::get_floor_angle(const Vector3 &p_up_direction) const {
ERR_FAIL_COND_V(p_up_direction == Vector3(), 0);
return Math::acos(floor_normal.dot(p_up_direction));
}
Vector3 KinematicBody::get_floor_velocity() const {
return floor_velocity;
}
@ -1328,6 +1333,13 @@ Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) {
return slide_colliders[p_bounce];
}
Ref<KinematicCollision> KinematicBody::_get_last_slide_collision() {
if (colliders.size() == 0) {
return Ref<KinematicCollision>();
}
return _get_slide_collision(colliders.size() - 1);
}
void KinematicBody::set_sync_to_physics(bool p_enable) {
if (sync_to_physics == p_enable) {
return;
@ -1404,6 +1416,7 @@ void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody::is_on_ceiling);
ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall);
ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody::get_floor_normal);
ClassDB::bind_method(D_METHOD("get_floor_angle", "up_direction"), &KinematicBody::get_floor_angle, DEFVAL(Vector3(0.0, 1.0, 0.0)));
ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity);
ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &KinematicBody::set_axis_lock);
@ -1414,6 +1427,7 @@ void KinematicBody::_bind_methods() {
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);
ClassDB::bind_method(D_METHOD("set_sync_to_physics", "enable"), &KinematicBody::set_sync_to_physics);
ClassDB::bind_method(D_METHOD("is_sync_to_physics_enabled"), &KinematicBody::is_sync_to_physics_enabled);
@ -1463,6 +1477,12 @@ Vector3 KinematicCollision::get_travel() const {
Vector3 KinematicCollision::get_remainder() const {
return collision.remainder;
}
real_t KinematicCollision::get_angle(const Vector3 &p_up_direction) const {
ERR_FAIL_COND_V(p_up_direction == Vector3(), 0);
return collision.get_angle(p_up_direction);
}
Object *KinematicCollision::get_local_shape() const {
if (!owner) {
return nullptr;
@ -1511,6 +1531,7 @@ void KinematicCollision::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision::get_normal);
ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision::get_travel);
ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision::get_remainder);
ClassDB::bind_method(D_METHOD("get_angle", "up_direction"), &KinematicCollision::get_angle, DEFVAL(Vector3(0.0, 1.0, 0.0)));
ClassDB::bind_method(D_METHOD("get_local_shape"), &KinematicCollision::get_local_shape);
ClassDB::bind_method(D_METHOD("get_collider"), &KinematicCollision::get_collider);
ClassDB::bind_method(D_METHOD("get_collider_id"), &KinematicCollision::get_collider_id);

View File

@ -275,6 +275,10 @@ public:
Vector3 remainder;
Vector3 travel;
int local_shape;
real_t get_angle(const Vector3 &p_up_direction) const {
return Math::acos(normal.dot(p_up_direction));
}
};
private:
@ -295,6 +299,7 @@ private:
Ref<KinematicCollision> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
Ref<KinematicCollision> _get_slide_collision(int p_bounce);
Ref<KinematicCollision> _get_last_slide_collision();
Transform last_valid_transform;
void _direct_state_changed(Object *p_state);
@ -324,6 +329,7 @@ public:
bool is_on_wall() const;
bool is_on_ceiling() const;
Vector3 get_floor_normal() const;
real_t get_floor_angle(const Vector3 &p_up_direction = Vector3(0.0, 1.0, 0.0)) const;
Vector3 get_floor_velocity() const;
int get_slide_count() const;
@ -351,6 +357,7 @@ public:
Vector3 get_normal() const;
Vector3 get_travel() const;
Vector3 get_remainder() const;
real_t get_angle(const Vector3 &p_up_direction = Vector3(0.0, 1.0, 0.0)) const;
Object *get_local_shape() const;
Object *get_collider() const;
ObjectID get_collider_id() const;