I'm playing around with grappling hooks in a game using BEPUPhysics, and was wondering about the best ways to accomplish it... here's my current set up:
First, trace where the hook hits using a Convex/Ray Cast.
Second, spawn two entities:
--> Both are nonsolid
--> one is at the player's position, the second is at the impact location
Third, Add a BallSocket (free rotation) joint at the second new entity's location, between the new entity and the entity traced into (The wall / roof / whatever)
Third part two, Add a second BallSocket joint at the first new entity's location, between the player and the new entity
Fourth, Add a distance limit between the two new entities -> max = the distance between the entities, min = that distance minus 0.01
Fifth, Add a point-on-line joint between the two new entities -> attaching the center of each entity to the line between them
problem of note: the player rapidly bobs up and down because the distance limit joint is very much the opposite of rigid - it's bouncy as hell, even with
Code: Select all
dl.Bounciness = 0.001f;
dl.MaxCorrectiveVelocity = 0.5f;
Next: if the player presses the RETRACT (go up) button:
First, Reduce the distance limit's length by the current Delta amount
Second, find the normalized direction vector between the player and holding entity... apply a small force to both of them, pushing them towards each other.
Lastly, if the player presses the EXTEND (go down) button:
First, increase the distance limit's length by the current Delta amount
Second, find the normalized direction vector between the player and the holding entity apply a small force to both of them, pushing them away from each other.
Problem of note with the above two: If the grappled entity has a positive mass (is dynamic / not kinematic), the force pulling/pushing it can be way too much and cause weird bugs (Flying entities!) or way too little and cause the push/pull to not sufficiently move the entity, and must wait several seconds for the constraint to force the two entities closer or farther.
So... how can I improve this? If this sounds terrible, how would you do it instead?
here's what that looks like in 2D:
here's what it looks like in first-person 3D: