Change platform detection by allowing select layers by type (wall or floor)

This commit is contained in:
fabriceci 2021-08-30 23:47:48 +02:00
parent 7ab78c4cad
commit 1a481c8191
3 changed files with 36 additions and 13 deletions

View File

@ -152,8 +152,11 @@
<member name="motion_mode" type="int" setter="set_motion_mode" getter="get_motion_mode" enum="CharacterBody2D.MotionMode" default="0"> <member name="motion_mode" type="int" setter="set_motion_mode" getter="get_motion_mode" enum="CharacterBody2D.MotionMode" default="0">
Sets the motion mode which defines the behaviour of [method move_and_slide]. See [enum MotionMode] constants for available modes. Sets the motion mode which defines the behaviour of [method move_and_slide]. See [enum MotionMode] constants for available modes.
</member> </member>
<member name="moving_platform_ignore_layers" type="int" setter="set_moving_platform_ignore_layers" getter="get_moving_platform_ignore_layers" default="0"> <member name="moving_platform_floor_layers" type="int" setter="set_moving_platform_floor_layers" getter="get_moving_platform_floor_layers" default="4294967295">
Collision layers that will be excluded for detecting bodies that will act as moving platforms to be followed by the [CharacterBody2D]. By default, all touching bodies are detected and propagate their velocity. You can add excluded layers to ignore bodies that are contained in these layers. Collision layers that will be included for detecting floor bodies that will act as moving platforms to be followed by the [CharacterBody2D]. By default, all floor bodies are detected and propagate their velocity.
</member>
<member name="moving_platform_wall_layers" type="int" setter="set_moving_platform_wall_layers" getter="get_moving_platform_wall_layers" default="0">
Collision layers that will be included for detecting wall bodies that will act as moving platforms to be followed by the [CharacterBody2D]. By default, all wall bodies are ignored.
</member> </member>
<member name="slide_on_ceiling" type="bool" setter="set_slide_on_ceiling_enabled" getter="is_slide_on_ceiling_enabled" default="true"> <member name="slide_on_ceiling" type="bool" setter="set_slide_on_ceiling_enabled" getter="is_slide_on_ceiling_enabled" default="true">
If [code]true[/code], during a jump against the ceiling, the body will slide, if [code]false[/code] it will be stopped and will fall vertically. If [code]true[/code], during a jump against the ceiling, the body will slide, if [code]false[/code] it will be stopped and will fall vertically.

View File

@ -1050,7 +1050,12 @@ bool CharacterBody2D::move_and_slide() {
Vector2 current_platform_velocity = platform_velocity; Vector2 current_platform_velocity = platform_velocity;
if ((on_floor || on_wall) && platform_rid.is_valid()) { if ((on_floor || on_wall) && platform_rid.is_valid()) {
bool excluded = (moving_platform_ignore_layers & platform_layer) != 0; bool excluded = false;
if (on_floor) {
excluded = (moving_platform_floor_layers & platform_layer) == 0;
} else if (on_wall) {
excluded = (moving_platform_wall_layers & platform_layer) == 0;
}
if (!excluded) { if (!excluded) {
// This approach makes sure there is less delay between the actual body velocity and the one we saved. // This approach makes sure there is less delay between the actual body velocity and the one we saved.
PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(platform_rid); PhysicsDirectBodyState2D *bs = PhysicsServer2D::get_singleton()->body_get_direct_state(platform_rid);
@ -1469,12 +1474,20 @@ void CharacterBody2D::set_slide_on_ceiling_enabled(bool p_enabled) {
slide_on_ceiling = p_enabled; slide_on_ceiling = p_enabled;
} }
uint32_t CharacterBody2D::get_moving_platform_ignore_layers() const { uint32_t CharacterBody2D::get_moving_platform_floor_layers() const {
return moving_platform_ignore_layers; return moving_platform_floor_layers;
} }
void CharacterBody2D::set_moving_platform_ignore_layers(uint32_t p_exclude_layers) { void CharacterBody2D::set_moving_platform_floor_layers(uint32_t p_exclude_layers) {
moving_platform_ignore_layers = p_exclude_layers; moving_platform_floor_layers = p_exclude_layers;
}
uint32_t CharacterBody2D::get_moving_platform_wall_layers() const {
return moving_platform_wall_layers;
}
void CharacterBody2D::set_moving_platform_wall_layers(uint32_t p_exclude_layers) {
moving_platform_wall_layers = p_exclude_layers;
} }
void CharacterBody2D::set_motion_mode(MotionMode p_mode) { void CharacterBody2D::set_motion_mode(MotionMode p_mode) {
@ -1559,8 +1572,10 @@ void CharacterBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_slide_on_ceiling_enabled", "enabled"), &CharacterBody2D::set_slide_on_ceiling_enabled); ClassDB::bind_method(D_METHOD("set_slide_on_ceiling_enabled", "enabled"), &CharacterBody2D::set_slide_on_ceiling_enabled);
ClassDB::bind_method(D_METHOD("is_slide_on_ceiling_enabled"), &CharacterBody2D::is_slide_on_ceiling_enabled); ClassDB::bind_method(D_METHOD("is_slide_on_ceiling_enabled"), &CharacterBody2D::is_slide_on_ceiling_enabled);
ClassDB::bind_method(D_METHOD("set_moving_platform_ignore_layers", "exclude_layer"), &CharacterBody2D::set_moving_platform_ignore_layers); ClassDB::bind_method(D_METHOD("set_moving_platform_floor_layers", "exclude_layer"), &CharacterBody2D::set_moving_platform_floor_layers);
ClassDB::bind_method(D_METHOD("get_moving_platform_ignore_layers"), &CharacterBody2D::get_moving_platform_ignore_layers); ClassDB::bind_method(D_METHOD("get_moving_platform_floor_layers"), &CharacterBody2D::get_moving_platform_floor_layers);
ClassDB::bind_method(D_METHOD("set_moving_platform_wall_layers", "exclude_layer"), &CharacterBody2D::set_moving_platform_wall_layers);
ClassDB::bind_method(D_METHOD("get_moving_platform_wall_layers"), &CharacterBody2D::get_moving_platform_wall_layers);
ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody2D::get_max_slides); ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody2D::get_max_slides);
ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody2D::set_max_slides); ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody2D::set_max_slides);
@ -1602,7 +1617,8 @@ void CharacterBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_snap_length", PROPERTY_HINT_RANGE, "0,1000,0.1"), "set_floor_snap_length", "get_floor_snap_length"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_snap_length", PROPERTY_HINT_RANGE, "0,1000,0.1"), "set_floor_snap_length", "get_floor_snap_length");
ADD_GROUP("Moving platform", "moving_platform"); ADD_GROUP("Moving platform", "moving_platform");
ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_ignore_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_ignore_layers", "get_moving_platform_ignore_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_floor_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_floor_layers", "get_moving_platform_floor_layers");
ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_wall_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_wall_layers", "get_moving_platform_wall_layers");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
BIND_ENUM_CONSTANT(MOTION_MODE_GROUNDED); BIND_ENUM_CONSTANT(MOTION_MODE_GROUNDED);

View File

@ -310,7 +310,8 @@ private:
float floor_snap_length = 0; float floor_snap_length = 0;
real_t free_mode_min_slide_angle = Math::deg2rad((real_t)15.0); real_t free_mode_min_slide_angle = Math::deg2rad((real_t)15.0);
Vector2 up_direction = Vector2(0.0, -1.0); Vector2 up_direction = Vector2(0.0, -1.0);
uint32_t moving_platform_ignore_layers = 0; uint32_t moving_platform_floor_layers = UINT32_MAX;
uint32_t moving_platform_wall_layers = 0;
Vector2 linear_velocity; Vector2 linear_velocity;
Vector2 floor_normal; Vector2 floor_normal;
@ -350,8 +351,11 @@ private:
real_t get_free_mode_min_slide_angle() const; real_t get_free_mode_min_slide_angle() const;
void set_free_mode_min_slide_angle(real_t p_radians); void set_free_mode_min_slide_angle(real_t p_radians);
uint32_t get_moving_platform_ignore_layers() const; uint32_t get_moving_platform_floor_layers() const;
void set_moving_platform_ignore_layers(const uint32_t p_exclude_layer); void set_moving_platform_floor_layers(const uint32_t p_exclude_layer);
uint32_t get_moving_platform_wall_layers() const;
void set_moving_platform_wall_layers(const uint32_t p_exclude_layer);
void set_motion_mode(MotionMode p_mode); void set_motion_mode(MotionMode p_mode);
MotionMode get_motion_mode() const; MotionMode get_motion_mode() const;