godotengine / godotengine/godot

Single bad frame with AnimationPlayer + PathFollow2D + callback_mode_process=physics

Open
#95,416 1 comment 0 reactions 0 assignees View on GitHub
bug confirmed topic:2d topic:animation
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### Tested versions

Reproduces in 4.2.2 and 4.3 RC3

### System information

Fedora Linux, Intel GPU, Compatibility renderer

### Issue description

I put a Sprite2D inside a PathFollow2D being driven by an AnimationPlayer. The animation is supposed to "stand still" for 1.5 seconds, then drive the sprite along the path in 0.5 seconds. The result is

https://github.com/user-attachments/assets/d223a65f-446f-4d3f-98f5-5c6898516317

The first frame as the sprite starts to move shows it "jumping" to the end. Then the animation continues as expected.

This only reproduces if the AnimationPlayer's callback_mode_process is physics. It is also sensitive to the time that the motion starts. If the keyframe is moved to 0.3 seconds, it no longer reproduces.

### Steps to reproduce

Add this scene to a project and run it.

```
[gd_scene load_steps=6 format=3 uid="uid://so4a5fmgcrjy"]

[ext_resource type="Texture2D" uid="uid://bn446da160m5t" path="res://icon.svg" id="1_0hj8s"]

[sub_resource type="Curve2D" id="Curve2D_jck48"]
_data = {
"points": PackedVector2Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0)
}
point_count = 2

[sub_resource type="Animation" id="Animation_7d1jt"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Path2D/PathFollow2D:progress_ratio")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}

[sub_resource type="Animation" id="Animation_el4gs"]
resource_name = "walk"
step = 0.1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Path2D/PathFollow2D:progress_ratio")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.3, 1),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [0.0, 0.0, 1.0]
}

[sub_resource type="AnimationLibrary" id="AnimationLibrary_mke75"]
_data = {
"RESET": SubResource("Animation_7d1jt"),
"walk": SubResource("Animation_el4gs")
}

[node name="Main" type="Node2D"]

[node name="Path2D" type="Path2D" parent="."]
curve = SubResource("Curve2D_jck48")

[node name="PathFollow2D" type="PathFollow2D" parent="Path2D"]

[node name="Sprite2D" type="Sprite2D" parent="Path2D/PathFollow2D"]
texture = ExtResource("1_0hj8s")

[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
callback_mode_process = 0
libraries = {
"": SubResource("AnimationLibrary_mke75")
}
autoplay = "walk"
```

### Minimal reproduction project (MRP)

[repro.zip](https://github.com/user-attachments/files/16578286/repro.zip)

Contributor guide

Open the contributing guide

Research direction

Start by running the linked repro.zip with the supplied scene and inspect the AnimationPlayer callback_mode_process setting, the PathFollow2D progress_ratio track, and the physics-process timing around the first movement frame. Done means the sprite no longer jumps to the path endpoint on that first frame while the animation still behaves correctly in physics mode and continues to reproduce the expected movement.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.