Description
Tested versions
- Reproducible in Godot 4.4
System information
Godot v4.4.stable - Pop!_OS 22.04 LTS on X11 - X11 display driver, Multi-window, 1 monitor - OpenGL 3 (Compatibility) - NV167 - Intel(R) Core(TM) i5-9300HF CPU @ 2.40GHz (8 threads)
Issue description
CharacterBody2D doesn't include physics for top down moving/rotating platforms.
I expect that if I set "Motion Mode" to "Floating" and match the CharacterBody2D "Floor Layers" with AnimatableBody2D "Collision > Layer" then the AnimatableBody2D is treated as a top down moving platform, but it seems to ignore the setting.
Implementing it with workarounds requires extra nodes, signals, and scripting logic, but still has buggy behaviour. And that's only me trying moving platforms (position), which has very basic math. Rotating will require calculating offset of player from platform, then detecting and applying platform rotation as player movement, because the player needs to change position in a circle based on changing rotation of platform.
Steps to reproduce
-
Create following scene tree:
- Node2D - CharacterBody2D - CollisionShape2D - AnimatableBody2D - CollisionShape2D - AnimationPlayer
-
Add collision shapes.
I chose RectangleShape2D.
I also increased size of AnimatableBody2D > CollisionShape2D.
-
Enable "Visible Collision Shapes" in "Debug" menu (top left).
This setting shows collisions well when running the game, and is required to see anything without adding sprites.
-
On CharacterBody2D, set "Motion Mode" to "Floating".
This setting is meant for top down movement, and changes some physics interactions and settings. It should also affect moving platform physics, but seems to disable it.
-
On AnimatableBody2D, set "Collisions > Layer" to only layer 2. Disable all other layers.
With this setting, CharacterBody2D should not collide with side of AnimatableBody2D, so that it can "stand on top" of it by overlapping (in top down, overlapping means standing on top).
Also, because CharacterBody2D has layer 2 in "Moving Platform > Floor Layers", I expect it to think AnimatableBody2D with collision layer 2 is "floor" in top down, so when it moves, then CharacterBody2D should move with the "floor platform".
-
Create animation to move AnimatableBody2D:
-
In Animation bottom panel, create animation with "Animation > New".
-
In Animation bottom panel, enable "Autoplay on Load" (button near top right of panel).
-
In Animation bottom panel, set Animation Looping to Ping Pong by clicking the loop button twice (below the pin icon in top right of panel). The button should become an arrow pointing left and right to two standing lines.
With this setting, only one direction needs to be set, and Godot will automatically animate it in the opposite direction.
-
In Animation bottom panel, "Add Track > Property Track > AnimatableBody2D > position".
-
In AnimatableBody2D, set "Transform > Position" to prevent overlap with CharacterBody2D and set keyframe (press key icon).
-
In Animation bottom panel, go to last frame.
-
In AnimatableBody2D, change "Transform > Position" and set keyframe (press key icon).
-
-
Add top down movement script to CharacterBody2D (given below).
-
Run project and move CharacterBody2D with arrow keys to touch AnimatableBody2D.
The CharacterBody2D should be moved with the AnimatableBody2D, but it is not affected at all.
Top down movement script
extends CharacterBody2D
const SPEED = 300.0
func _physics_process(_delta: float) -> void:
var direction_x := Input.get_axis("ui_left", "ui_right")
if direction_x:
velocity.x = direction_x * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
var direction_y := Input.get_axis("ui_up", "ui_down")
if direction_y:
velocity.y = direction_y * SPEED
else:
velocity.y = move_toward(velocity.y, 0, SPEED)
move_and_slide()
Minimal reproduction project (MRP)
moving-platform-test.mp4
Player character shows up as rectangle in top left. Move right and down towards moving platform.