-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PathFollow2D: rotation isn't consistent #13434
Comments
On the gif may look like if the issue starts after first loop but can happen on any point changing Something else I have noticed is that the transition between last end first point does not trigger the first point "look ahead" rotation. |
There are problems I can see: next tangent look up doesn't take loop into account, rotation angle direction need to be calculated. I'll give it a check in the weekend. But after completing an exact cycle, the object will never be force to it's original orientation, so you'll have "different rotations", that's not a bug, that's the entire point of doing parallel transport. Unless you gain an exact multiple of 2pi by doing parallel transport (you can read about it here if you're not familiar with the concept), you will always get a different angle. |
Looks like a combination of a couple of issues. First a case of difference in expected behaviour. My understanding from the tutorial example was that the PathFollow2D should have it's direction set to the direction of the followed path. The implementation is trying to do something different. I'm not sure which of these behaviours is desired. Second the implementation assumes a low offset delta and it's used to define near points to take the previous and current angles on the path from. |
That is one of the compatibility-breaking changes in 3.0. 3rd party tutorials aren't the same as the official documentation, although I'm not sure if it was documented. If they rely on 2.0 behaviors that were changed in 3.0 beta, they need to be updated. Anyway, like I said, that is the expected behavior in 3.0.
No, it doesn't assume anything. It used to work like that in 2.0, that it asked the user to assume some offset, but now it calculates the exact offset change without relying on any assumptions. BTW using current master, I couldn't reproduce any of the issues @cbscribe mentioned in the issue description, except for the missing rotation at the end of the loop which is easy to fix, using the attached project. There is no unpredicatable behavior, and it works the same way every time I run it. I also don't see anything that resembles to the gif you uploaded when I run it. |
Short version: parallel transport requires a good curve. If traversing the curve has some problems, parallel transport will make those super obvious. Long version: I'm reiterating this probably for the 4th time on the issue tracker, and I hope it will stick this time curves with sharp turns won't work properly with the current implementation of curves. If you use curves with high-torsion, there will always be issues, with or without parallel transport (see #3713 for example). The difference with parallel transport is that, this issue will not just be apparent at single point but it will affect all the rest of the motion once you passed that "bad" point, so it's a lot more difficult to miss this problem. But this is a problem with the Curve, not PathFollow. Interpolation will help you avoid such sharp turns, and I do think curve should offer different polynomials to do that. Also keep in mind that when you skip or "teleport over" a part of the curve, you won't gain the rotation you would have gained if you had walked though that portion of the curve. That's how parallel transport works: you accumulate rotations by following the path you walk over. If you don't walk but teleport over a portion, you simply don't "follow" that portion. With such a sudden 90 rotation in your example project, it's quite easy to teleport over the corner using your code
With such a code, sometimes you'll teleport over it, sometimes you will walk on it. What can help to alleviate is to a) use interpolation and to increase the sampling rate of your curve and rebake it b) use a lower sampling that such that 50 * delta won't ever skip over that single point with 90 degrees of rotation. But again, these are all about the curve. |
In PathFollow2D::_update_transform
The two vectors here are not tangents to the curve, they are straight lines between the current position and positions delta_offset along the curve in either direction. If delta_offset is low, this is close to a tangent, in cases where delta_offset is higher it will be inaccurate to irrelevant. This project demonstrates: And the same with a curved path: |
That is tangent. The thing you call "straight line" is the first-order forward finite-element expression for the gradient operator. delta_offset is low if you are traversing the path properly. Use interpolation or increase the resolution and rebake it if needed. Or better yet, read my previous reply above. Anyway, I really don't like dealing with all this noise, and I certainly don't want to waste any more time by explaining what's going on or explaining elementary math. Feel free to revert the commits I made in PathFollow2D. I'm done. |
I just ran it again and I didn't see the erroneous rotation until the 6th time I re-ran it. It's inconsistent.
This is the official doc tutorial, which is why I'm so concerned about figuring this out. So I changed the code to this instead:
So each step we move halfway around the loop. I would expect to have the same rotation at offset 0.5 as I would at 1.5 or 5.5. However, here's what I get:
Note that if I start with an initial offset of 5.5, the rotation is 180 at that point. So here's the question then: what is Path2D/PathFollow2D for if I can't use it to move a sprite along a loop? It worked this way in 2.1, but the 3.0 behavior is different. That's fine, but what is the "correct" way to use this? We have a lot of people starting to use beta now, so I need to fix the tutorial. |
Given the vastly different behavior, from warping along the path resulting in a different rotation to the start of the curve not setting any rotation, I would say that this would be better off as either a toggle or just reverted back to how it was before, since I think that the old way this worked was completely fine for the majority of people using the node. |
I haven't have time to pay much attention to whathever is going with Path and PathFollow, but if the behavior on 2.1 was good, I don't see the problem with reverting. |
@reduz 2.1 had a problem in the interpolation of the rotation between last and first point (basically, no interpolation) making the transition look really bad. |
I think the smooth rotation on sharp corners may be an artifact rather than intentional, as it comes from the resolution the path is sampled at. A sharp corner between the end and start of a looped path stays sharp because there will always be two samples at that point. You can force a smooth corner by moving the start and end apart a little, rejoining the path to get a diagonal line and then adding a curve with the control points. This is also worth doing this on other corners where you want a smooth rotation, to let you tweak how 'wide' you want the turn to be. Edit: Scratch that, I'm wrong about the why. (The workaround works though) |
I was half right. It's partly due to the sample at that corner being in the perfect position and partly a result of not looping the lookahead. Here's V2.1 with looped lookahead for looping closed paths. The end/start transition is still sharper than other corners, but less noticeably so. Possibly good enough? |
So, basically, either this is fixed or we revert to 2.1 behavior? Not sure what to do here. |
Does anyone have a usecase/example for what the new version needed to do, that I can take a look at? |
Here is the detail of what the new version added to the 3D path #8870 |
Is it only the preserving initial rotation bit that applies to the 2D follower? |
When rotation is enabled, the follower's rotation will be set to that of the tangent to the path at it's current offset. For closed looping paths the lookahead will now wrap around at the end of the path. fixes godotengine#13434
Sorry to react here, but I don't know where to discuss about this issue. I think it was fixed in 3.x at some point, but now that my project have been moved to the newer 4.x version of godot, somewhere I thinks there's a regression on the behavior. has it been reworked inbetween 3.x and 4.x ? I can put my finger on the specific issue, but in one of my projects, the pathfollow2D was consistent, and then in 4.x the path follow seems to create weird rotations on the path itself, or on the sprite follow this path. I think somehow it's related to the "baked points" that have been modified for 4.x right ? |
Yes there have been extensive reworks between 3.x and 4.x, if you have an issue I'd open a new issue |
OK I need to work on that to isolate the issue but I don't know exactly we're the issue is. I just have a weird behavior on my project, but can't create exactly the same issue on a new project. I'll try to do something, thanks for the answer |
Operating system or device, Godot version, GPU Model and driver (if graphics related):
3.0beta d2e05b6
Issue description:
Moving on a looped path doesn't result in the same rotation each time.
In addition, no rotation occurs when completing the loop, resulting in a different initial rotation every time through the loop.
Worse still, when running the attached project, I get a different result each time I run the project. Sometimes the angle strays quite far from orthogonal in the first couple of loops, sometimes it takes several.
This makes it impossible to keep the orientation of a sprite consistent when looping around a path. It also breaks the "Dodge the Creeps" 3.0 tutorial game, where we have a path wrapped around the edge of the screen and use
set_offset( randi() )
to pick a random location along it to spawn a mob. Now the orientation of the PathFollow2D is completely unpredictable.Steps to reproduce:
See attached project for example.
path_test.zip
Link to minimal example project:
The text was updated successfully, but these errors were encountered: