Bugreport: 2D unit rotating receiving illegal X/Y rotation upon first collision with newly spawned unit

Version:
Pathfinder Pro to version 4.3.40, affected code is part of free version too.

Expected result:
Characters configured as 2D units rotate only along the Z axis, and have X and Y rotation 0.

Observed result:
When a character with an AIPath and RVOController collides with another such character that has never moved, then that character that stands still receives an illegal rotation.
If both characters moved prior to the collision, the rotation is as expected - only along Z axis, even if the rotation is manually set to 0, 0, 0 again.

Video:

Relevant code:
The code creating the ‘illegal rotation’ can be located by simply looking at which lines create the values in question.
It is this line:

AIBase.cs:

// This causes the character to only rotate around the Z axis
if (orientation == OrientationMode.YAxisForward) targetRotation *= Quaternion.Euler(90, 0, 0);

The line of code does what it claims to do for all targetRotation values observed while debugging except Quaternion.Euler(0, 90, 0) and Quaternion.Euler(0, 270, 0):

diff --git a/Packages/com.arongranberg.astar@4.3.40/Core/AI/AIBase.cs b/Packages/com.arongranberg.astar@4.3.40/Core/AI/AIBase.cs
index ca0ee8bb..273ba453 100644
--- a/Packages/com.arongranberg.astar@4.3.40/Core/AI/AIBase.cs
+++ b/Packages/com.arongranberg.astar@4.3.40/Core/AI/AIBase.cs
@@ -706,7 +706,17 @@ namespace Pathfinding {
                        }
 
                        // This causes the character to only rotate around the Z axis
-                       if (orientation == OrientationMode.YAxisForward) targetRotation *= Quaternion.Euler(90, 0, 0);
+                       // TODO: No, it does not for targetRotation == (0, 90, 0) and (0, 270, 0).
+                       // This case occurs when a unit collides with a unit that hasn't moved yet.
+                       // You can observe the circle gizmo rotate incorrectly and unit ending up with non-2D rotation.
+                       if (orientation == OrientationMode.YAxisForward) {
+
+                               targetRotation *= Quaternion.Euler(90, 0, 0);
+
+                               /// Workaround: clamp the values for that case.
+                               targetRotation = Quaternion.Euler(0, 0, targetRotation.eulerAngles.z);
+                       }
+
                        return Quaternion.RotateTowards(simulatedRotation, targetRotation, maxDegreesOffAxis);
                }
 

I have not figured out what the correct fix would be in a justifiable amount of time, so I added the bandaid.

The // Common fast path. case is triggered in our codebase.
We notice the a similarity of the observation condition (newly spawned characters), perhaps it’s related
// That case may be important, especially when the character has just been spawned and does not have a destination yet.

A bugfix for this issue would be welcome.

Thank you for this feature-rich and stable pathfinder library!

1 Like

Thank you for this bug report!