idanarye / bevy-tnua

A floating character controller for Bevy
https://crates.io/crates/bevy-tnua
Apache License 2.0
235 stars 16 forks source link

Add an example / best practices for climbing (ladder / ivy) #54

Open ethereumdegen opened 4 months ago

ethereumdegen commented 4 months ago

Add an example / best practices for climbing (ladder / ivy)

idanarye commented 4 months ago

It's not supported yet (though I do plan to support it). One could hack it with a custom Basis/Action, of course, but they'd pretty much be implementing the whole thing from scratch, which is not something I want to put in an official example.

Once I support the feature I'll create an example.

ethereumdegen commented 4 months ago

I am trying to implement this custom Climbing basis myself (forking the Walk one), and i also want to implement NoClip flying like in SourceEngine games.

However, to do this, I would like my custom basis to be able to have a trait that lets me turn off collision and turn off gravity some how for this particular entity while they are in that basis. This would be nice for Swimming too. Does that make sense? How can i do that? (is there a hacky work around for now ?)

ethereumdegen commented 4 months ago

Okay i realized i can use Avian3d GravityScale component to do the gravity scaling. However how can I

1) control VELOCITY of climbing a ladder, not only acceleration as it seems i can only do now in the basis?
2) disable collision for my character while i am climbing the ladder? (or otherwise lock all XZ direction movement no matter what i collide with ?)

ethereumdegen commented 4 months ago

Oh i think i can use LinearDamping and LockedAxes ... will report back :P

ethereumdegen commented 4 months ago

YAY! I was able to implement climbing by hacking up the Walk basis to contain very very little (like 10% of what it used to contain) and then by using GravityScale =0, LinearDamping = 5.0, and LockedAxes (all locked except for Y axis movement) and it is Source engine like ladder movement :D

Kind of interesting that i have to use a mixture of avian and tnua code here to accomplish this but its actually very clean and nice overall

idanarye commented 4 months ago

TnuaVelChange (which TnuaMotor uses for both linear and angular movement) has both boost and acceleration fields. You can use boost to cancel existing velocity and acceleration to offset the gravity - and then add on top of that the boost and/or acceleration you actually want the character to have.

As for determining what you need to cancel - TnuaBasisContext (which you get as a parameter in apply) has a tracker field with that information.

ethereumdegen commented 3 months ago

ahh okay. I think it is a bit weird that i have to cancel out gravity in the basis code and that it is automatically applied. Since i am making a NoClip basis and Floating basis and Swimming basis, it is super annoying to have to deal with the fact that gravity is implicitly applied and then having to cancel it out. I would rather gravity NOT be implicitly applied and then i would just need to apply it myself in the basis that use gravity like Walk and Crouch and what not ... hmm ..

ethereumdegen commented 3 months ago

IM trying to counteract gravity like you describe but it isnt working ..

 let grav =  ctx.tracker
                        .gravity ;

        let anti_gravity = -1.0  * grav;

        motor.lin =   TnuaVelChange {
            boost: vertical_velocity_boost,
            acceleration: anti_gravity
        } ; //+ upward_impulse;
idanarye commented 3 months ago

Weird. I'll have to look into it.

idanarye commented 3 months ago

Since i am making a NoClip basis

Not sure this is possible with just Tnua. A no-clip requires interfering with the physics backend's collision configuration, which Tnua doesn't do. This is part of the root of many of the limitations you encounter - I'm trying to limit the surface area between Tnua and the physics backend, to reduce the effort it requires to support all the different backends.