godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.15k stars 97 forks source link

Some improvements to kinematic body's move_and_slide_with_snap #1217

Open ghsoares opened 4 years ago

ghsoares commented 4 years ago

Describe the project you are working on: 2D Sonic-like mechanics project

Describe the problem or limitation you are having in your project: If we want to re-create sonic's mechanics in Godot, we need to resolve some problems, that I could analyze playing the 2D sonic's games: -The classic sonic can run through walls and ceilings if the speed is maintained; -Even if speed is too high, the character remains attached to ground even if there is a sudden slope angle change; -The player only remains attached to ground if each interpolation step the difference of angle in floor is less that 90º and the Floor height is the same (So sonic will fall instead of attach to a ground just a little bellow or to a wall).

The current move_and_slide_with_snap can resolve just a bit of these problems, but it seens like it was designed for simple platforms, without high-speed movement nor more than 90º slopes. So these problems will occour: -Even if we increase floor_max_angle parameter, seems like the speed is decelerated in horizontal floor normal (on walls). -The function snap a little too much, so if there's a ground one step bellow from current player ground, the function will snap, instead of fall. -If we decrease snap vector length, in a sudden slope change the player will not be snapped to ground. -It seens like that in some cases the position is snapped but the returned speed isn't.

Describe the feature / enhancement and how it helps to overcome the problem or limitation: Some of the features will break the mechanic to simple platforms, so maybe is better to have a separated function, maybe called move_and_slide_with_free_snap (a little too long, i'm not good with names (: ), then the syntax would be something like this: move_and_slide_with_free_snap(Vector2 linear_velocity, int max_slides = 4, float slide_delta = 8f, float max_floor_angle_difference = 1.570796, float max_floor_height_difference = 8, bool infinite_inertia = true), the max_floor_angle_difference is in radians, and the max_floor_height_difference and slide_delta is in pixels.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams: In this function it would slide a small amount per step, compare the previous step ground normal to current step and see some conditionals: -If the angle difference of floor normal, in degrees, from the previous step to this step is less or equal than max_floor_angle_difference, then snap the position and speed. -If the angle difference is larger than max_floor_angle_difference , then don't snap. -Calculates the floor height by using the positions compared by the normals and if the difference is higher than max_floor_height_difference, then don't snap. In each step, it compares the values of the previous step, and if in the previous step the position and speed is not snapped, just move the resultant delta.

If this enhancement will not be used often, can it be worked around with a few lines of script?: If can be worked around but isn't a easy thing to do as it requires significant amount of vector math and requires a significant amount of code lines to create the mechanic.

Is there a reason why this should be core and not an add-on in the asset library?: Because is a valid KinematicBody2D (and 3D) use to make these sonic mechanics instead of other nodes, and engages game developers to create more frenetic action games using Godot.

jonbonazza commented 4 years ago

Personally, I feel that this is far too niche of a problem to merit being incorporated into core. While it might be somewhat complicated, it's perfectly possible to implement in GDScript. It would be a good addition to the assetlib, maybe.

Being "hard" is not a valid enough reason to implement a new feature in the core engine. It needs to solve a common problem (emphasis on "common").

ghsoares commented 4 years ago

@jonbonazza I understand your point, but there's my personal points:

-Can be implemented but needs good vector math knowledge;

-Being "hard to implement" is a good reason to add to the core, because there is functions to resolve programming problems easier, there's nodes built-in because makes easier to create some mechanics like the joints nodes to create openable doors, ropes, attached wheels, the kinematicbody 2d and 3d to create the player movement, etc. In Godot 3.0.x, the move_and_slide_with_snap was a very requested feature because was hard to implement the mechanic, but possible;

-Maybe this isn't a common issue because there isn't developers that would like to try more frenetic games in Godot? As I said, this engages more people to try Godot to more than casual games (I'm not saying that there isn't games in this genre using Godot, I'm saying that are rare).

This is my personal opinion.