godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.38k stars 21.26k forks source link

CharacterBody2D without velocity get sticky collision #94928

Open nezvers opened 3 months ago

nezvers commented 3 months ago

Tested versions

Reproducible: v4.3.rc1.official [e343dbbcc] v4.2.2.stable v4.2.1.stable v4.1.1.stable v4.1.stable v4.0.stable v4.0.beta.10

System information

Godot v4.3.rc1 - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 2070 SUPER (NVIDIA; 31.0.15.5186) - Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz (8 Threads)

Issue description

CharcterBody2D with velocity of (0, 0) sticks to other CharacterBody2D which collided with it. CollisionShape2D.shape doesn't matter. motion_mode doesn't matter. platform_on_leave doesn't matter. Static CharacterBody2D receives slide_collisions without moving and receives them while stuck to other body. Requires minimal code to test. For MRP I used AnimationPlayer for dir manipulation.

extends CharacterBody2D

@export var speed_max:float = 60.0
@export var dir:Vector2

func _physics_process(delta: float) -> void:
    velocity = velocity.move_toward(speed_max * dir, delta * 200.0)
    move_and_slide()

https://github.com/user-attachments/assets/f58e10ae-863a-4ddf-ae01-f62fcc6fd329

Steps to reproduce

Minimal reproduction project (MRP)

sticky_collision.zip

JekSun97 commented 3 months ago

To be honest I don't know what the correct behavior should be, but on 4.3 rc1 I have the same thing happening as in the video.

nezvers commented 3 months ago

I'm guessing this is coming from a moving platform logic. In any case this is terrible behavior. I am in a middle of a tutorial video for a simple top-down game. The enemy sticks to a player where enemy is not giving input for a walk direction. Such behavior is super confusing to explain why would something like that happen or how to fix that. The only solution I can see is some hacky workarounds that is not beginner friendly.

https://github.com/user-attachments/assets/a483ce14-f547-4d6e-aee7-51906c13c801

image

nezvers commented 3 months ago

A workaround for my current needs is simple. Don't call move and slide if not moving. Not sure if later that will be enough.

var velocity2:float = velocity.length_squared()
if velocity2 > 0.01:
    move_and_slide()