diff --git a/.runsettings b/.runsettings
index d51fe20a..f1ade62c 100644
--- a/.runsettings
+++ b/.runsettings
@@ -7,7 +7,7 @@
180000
true
- d:\development\Godot_v4.5-stable_mono_win64\Godot_v4.5-stable_mono_win64.exe
+ D:\Godot\Godot_v4.6-stable_mono_win64\Godot_v4.6-stable_mono_win64\Godot_v4.6-stable_mono_win64.exe
diff --git a/gdunit4_testadapter_v5/GdUnit4TestRunnerScene.cs b/gdunit4_testadapter_v5/GdUnit4TestRunnerScene.cs
new file mode 100644
index 00000000..1f7451c8
--- /dev/null
+++ b/gdunit4_testadapter_v5/GdUnit4TestRunnerScene.cs
@@ -0,0 +1,14 @@
+// Copyright (c) 2025 Mike Schulze
+// MIT License - See LICENSE file in the repository root for full license text
+
+// ReSharper disable once CheckNamespace
+namespace GdUnit4.TestRunner;
+
+using Core.Runners;
+
+///
+/// The GdUnit4Net test runner scene.
+///
+public partial class GdUnit4TestRunnerScene : GdUnit4TestRunnerSceneCore
+{
+}
diff --git a/gdunit4_testadapter_v5/GdUnit4TestRunnerScene.cs.uid b/gdunit4_testadapter_v5/GdUnit4TestRunnerScene.cs.uid
new file mode 100644
index 00000000..f909e73a
--- /dev/null
+++ b/gdunit4_testadapter_v5/GdUnit4TestRunnerScene.cs.uid
@@ -0,0 +1 @@
+uid://40hk5xnli78u
diff --git a/tests/ExampleTest.cs b/tests/ExampleTest.cs
deleted file mode 100644
index 527ea6e7..00000000
--- a/tests/ExampleTest.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-namespace Movementtests.tests;
-
-using GdUnit4;
-using static GdUnit4.Assertions;
-
-[TestSuite]
-public class ExampleTest
-{
- [Before]
- public void Setup() {
- // Setup suite-level shared resources, expensive setup
- }
-
- [After]
- public void Cleanup() {
- // Cleanup suite-level shared resources, expensive setup
- }
-
- [TestCase]
- public void StringToLower() {
- AssertString("AbcD".ToLower()).IsEqual("abcd");
- }
-
- [TestCase]
- public void StringToUpper() {
- AssertString("AbcD".ToUpper()).IsEqual("ABCD");
- }
-}
\ No newline at end of file
diff --git a/tests/ExampleTest.cs.uid b/tests/ExampleTest.cs.uid
deleted file mode 100644
index 1842f631..00000000
--- a/tests/ExampleTest.cs.uid
+++ /dev/null
@@ -1 +0,0 @@
-uid://cs8i2bp4wr00u
diff --git a/tests/player_movement/PlayerMovementTest.cs b/tests/player_movement/PlayerMovementTest.cs
new file mode 100644
index 00000000..115ea2b3
--- /dev/null
+++ b/tests/player_movement/PlayerMovementTest.cs
@@ -0,0 +1,98 @@
+using System.Threading.Tasks;
+using Godot;
+
+namespace Movementtests.tests;
+
+using GdUnit4;
+using static GdUnit4.Assertions;
+
+[TestSuite, RequireGodotRuntime]
+public class PlayerMovementTest
+{
+ private ISceneRunner _runner;
+ private Node _scene;
+ private PlayerController _player;
+
+ private readonly float _tolerance = 0.01f;
+ private readonly Vector3 _vectorTolerance = new Vector3(0.01f, 0.01f, 0.01f);
+
+ [Before]
+ public void Setup() {}
+ [After]
+ public void Cleanup() {}
+
+ [BeforeTest]
+ public void SetupTest()
+ {
+ _runner = ISceneRunner.Load("res://tests/player_movement/player_movement_scene.tscn");
+
+ _scene = _runner.Scene()!;
+ var player = _scene.FindChild("Player") as PlayerController;
+ _player = player!;
+ }
+ [AfterTest]
+ public void CleanupTest() {}
+
+ [TestCase("BaseLocation")]
+ public async Task PlayerMoveForward(string markerName)
+ {
+ var marker = _scene.FindChild(markerName) as Marker3D;
+ AssertObject(marker).IsNotNull();
+ _player.GlobalPosition = marker!.GlobalPosition;
+ await _runner.AwaitIdleFrame();
+
+ var startPos = _player.GlobalPosition;
+
+ _runner.SimulateKeyPress(Key.W);
+ await _runner.AwaitMillis(300);
+ _runner.SimulateKeyRelease(Key.W);
+
+ var endPos = _player.GlobalPosition;
+ var direction = startPos.DirectionTo(endPos);
+ AssertVector(direction).IsEqualApprox(Vector3.Forward, _vectorTolerance);
+ }
+
+ [TestCase("BaseLocation")]
+ public async Task PlayerJump(string markerName)
+ {
+ var marker = _scene.FindChild(markerName) as Marker3D;
+ AssertObject(marker).IsNotNull();
+ _player.GlobalPosition = marker!.GlobalPosition;
+ await _runner.AwaitIdleFrame();
+
+ var startPos = _player.GlobalPosition;
+
+ _runner.SimulateKeyPress(Key.Space);
+ await _runner.AwaitMillis(100);
+ _runner.SimulateKeyRelease(Key.Space);
+
+ var endPos = _player.GlobalPosition;
+ var direction = startPos.DirectionTo(endPos);
+ AssertVector(direction).IsEqualApprox(Vector3.Up, _vectorTolerance);
+ AssertVector(_player.Velocity.Normalized()).IsEqualApprox(Vector3.Up, _vectorTolerance);
+
+ await _runner.AwaitMillis(500);
+ endPos = _player.GlobalPosition;
+ AssertVector(endPos - startPos).IsEqualApprox(Vector3.Zero, _vectorTolerance);
+ }
+
+ [TestCase("MantleLocation1")]
+ public async Task PlayerMantle(string markerName)
+ {
+ var marker = _scene.FindChild(markerName) as Marker3D;
+ AssertObject(marker).IsNotNull();
+ _player.GlobalPosition = marker!.GlobalPosition;
+ await _runner.AwaitIdleFrame();
+
+ var startPos = _player.GlobalPosition;
+
+ _runner.SimulateKeyPress(Key.Space);
+ await _runner.AwaitMillis(100);
+ _runner.SimulateKeyRelease(Key.Space);
+ await _runner.AwaitMillis(300);
+
+ var endPos = _player.GlobalPosition;
+ AssertFloat((endPos - startPos).Length()).IsGreater(0.0f);
+ AssertFloat(endPos.Y).IsEqualApprox(1.0f, _tolerance);
+ }
+}
\ No newline at end of file
diff --git a/tests/player_movement/PlayerMovementTest.cs.uid b/tests/player_movement/PlayerMovementTest.cs.uid
new file mode 100644
index 00000000..a5061437
--- /dev/null
+++ b/tests/player_movement/PlayerMovementTest.cs.uid
@@ -0,0 +1 @@
+uid://x5pj2ymam2gg
diff --git a/tests/player_movement/player_movement_scene.tscn b/tests/player_movement/player_movement_scene.tscn
new file mode 100644
index 00000000..e40a34fc
--- /dev/null
+++ b/tests/player_movement/player_movement_scene.tscn
@@ -0,0 +1,35 @@
+[gd_scene format=3 uid="uid://i8kb38q7bdfk"]
+
+[ext_resource type="Material" uid="uid://31aulub2nqov" path="res://assets/materials/greybox/m_greybox.tres" id="1_bdfhg"]
+[ext_resource type="PackedScene" uid="uid://bei4nhkf8lwdo" path="res://scenes/player_controller/PlayerController.tscn" id="1_hg1sy"]
+
+[node name="PlayerMovementScene" type="Node3D" unique_id=231040688]
+
+[node name="CSGCombiner3D" type="CSGCombiner3D" parent="." unique_id=241909240]
+use_collision = true
+collision_layer = 256
+collision_mask = 65553
+
+[node name="Ground" type="CSGBox3D" parent="CSGCombiner3D" unique_id=432200143]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, -0.5, -3.25)
+use_collision = true
+collision_layer = 256
+collision_mask = 65553
+size = Vector3(1000, 1, 1000)
+material = ExtResource("1_bdfhg")
+
+[node name="Ground2" type="CSGBox3D" parent="CSGCombiner3D" unique_id=854660236]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.75, 0.5, -1.75)
+use_collision = true
+collision_layer = 256
+collision_mask = 65553
+size = Vector3(1.5, 1, 1.5)
+material = ExtResource("1_bdfhg")
+
+[node name="Player" parent="." unique_id=709076448 instance=ExtResource("1_hg1sy")]
+TutorialDone = true
+
+[node name="BaseLocation" type="Marker3D" parent="." unique_id=1793710692]
+
+[node name="MantleLocation1" type="Marker3D" parent="." unique_id=550080845]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.75, 0, 0)