-
Notifications
You must be signed in to change notification settings - Fork 24
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
Allow the character to be affected by the external physical world even when the acceleration is high #30
Comments
Hi any workaround? I think I have the same problem when I want to push back the character after getting hit |
Not yet. I have direction for an idea how to implement this, but I don't have all the details ironed out and I want to create a demo environment first so that I can create it (which I plan to do after #59). Either way it wouldn't be a workaround - my idea can only be done as a proper feature. I'll write the idea here (probably should have wrote it down long ago, but there's no time like the present): Basically, I want to maintain a perceived velocity. Unlike the true velocity, which is read from physics backend, the perceived velocity will be updated by Tnua every frame based on:
As long as there are no external forces (other than the expected ones, aka gravity) the perceived velocity should be the same as the true velocity, so the third factor will not affect it and it'll behave the same as now. Once there is an external force - e.g. an impact from an attack - there will be a difference between the two. If the EMA was set with |
Still need to decide if this should be controlled by the basis or by the controller directly. |
Okay, I have a demo level for testing this: https://idanarye.github.io/bevy-tnua/demos/platformer_3d-avian?level=Pushback Now to work on the actual feature... |
So... I have it in the Peek.2024-08-14.19-06.mp4My main issues:
I'll keep that branch for now, but I'm going to try and think a different solution for this problem. |
New approach - "boundary pushing"The idea is to maintain a "boundary" in the velocity space. When the character gets pushed and due to that has a velocity of - let's say - 20 units west, then the boundary is at
The big question here is - how to create the boundary in the first place? Maybe something similar to the pushover mechanism but without the EMA? Instead, I'll always "predict" the new boundary location (maybe do it in the basis itself? |
I'd also like to somehow automatically "dissolve" boundaries over time. If the character runs in the same direction it was pushed the boundary will not get pushed back - or at least it won't get pushed back all the way to zero. Say the character's speed is 10 and it gets pushed to a speed of 20. It'll slow down (with the boundary pushing acceleration, which is lower than its regular acceleration) from 20 to 10 because of the boundary, and then continue to run west at that speed. As long as it runs, the speed will not fall below 10 - which means that the boundary will not be pushed below 10. That would mean that if the character keeps running for a while, the barrier will still be there when it finally brakes. We don't want that - if the character keeps running, it should eventually (a word which sounds like a lot of time, but in practice it'll usually be less than 10 seconds - maybe even less than 5) become a normal run that uses the normal brake acceleration. I can think of two possible solutions:
I kind of like the third option, but it would mean the barrier will have to be act differently than just acceleration limiter (or maybe the acceleration limit should slowly progress toward the regular acceleration?). Also, if I do that, I probably should do it with a linear dissolution? Another option - detect when the barrier is not being pushed, and set a (relatively short) timer on that. |
Instead of removing the barrier when it gets to It's true that with the timer it'll eventually stop pushing, but I don't think it'd feel right to trust the timer on this. On the other hand, if the character gets pushed west while running east and continues to run. It makes no sense if it has to push the barrier all the way back to its original position - that would mean that after passing the zero it'll have to keep pushing the barrier, causing a slower acceleration that if it'd start from rest. So maybe if the actual and predicted velocities are on the different sides of the zero, I'll terminate the barrier once it passes the zero? I'm not sure which option is better. But then again - Tnua's philosophy is that every game should be able to configure how it feel, so maybe I should make an |
I feel sorry I can’t help you much with it since I don’t know the domain. Anyway I think that letting the developer decide is better. Anyway have you considered nullifying the moving velocity while being hit? Then restore it after a timer? It probably wouldn’t allow some use cases but it could be an option |
Not sure I like how it turned out: Peek.2024-08-17.02-15.mp4Maybe if I get the boundary's strength to fade over time? (or over velocity recovered?) |
I've added a diminishing factor. At first it was linear by percentage of "boundary penetration" (actually - how much velocity has been recovered) which didn't feel very good, but when I made it a power function it became much better: Peek.2024-08-18.22-43.mp4I still don't think it's good enough though. I'm not sure if it's because I haven't tweaked enough with the numbers, because I didn't add a dedicated animation, or because something in my math is lacking. |
Tweaking with the numbers improved quite a lot. Changing Peek.2024-08-20.18-30.mp4When I increase the bullet strength the change becomes more apparent: Peek.2024-08-20.18-32.mp4 |
I'm trying a logarithmic function: Peek.2024-09-03.17-59.mp4I'm not sure if I like it more or less... |
I'll think I go with the logarithmic function |
Or maybe not. I'm getting weird results because using I'll stick with the old function. |
And of course I wouldn't think to try it in the regular level before merging it to Peek.2024-09-11.03-20.mp4In retrospect, I should have seen it coming. Hitting a wall, after all, is also an impulse... I'll need to figure out how to distinguish between these impulses. I may end up having to make the user code tell the controller about the impulse instead of detecting it automatically... |
Since user code will have to manually trigger it anyway (otherwise I can't differentiate between "hitting an obstacle" and "getting hit by an attack"), I'm thinking of maybe just making a This does mean I'll have to devise a way to prioritize actions so that it won't get overwritten by a user action in the same frame. We don't want to create a glitch that allows cancelling a knockback with a perfectly timed crouch... |
|
If the character is pushed, Tnua will apply the maximum acceleration it can to reset its velocity. If we want the controls to be snappy, the acceleration is usually pretty high - which means that Tnua can easily negate these external forces.
I need to figure out a way to let the character be manipulated by such forces, without compromising on having a high acceleration for regular movement.
The text was updated successfully, but these errors were encountered: