TwoBonesIK : Block character movement when reaches the max arm extension

Hi, I set up a basic TwoBonesIK system where the player traces towards a surface, and with the E key, I place the right hand of the character on this surface with Two Bones IK.

Now I want the player to be able to move around while the hand is snapped to the surface, but in the limit of the arm extension. When the arm reaches the maximum extension, I want to stop the character movement.

This graph shows how I’ve modified the character movement :

This graph shows the CheckReachability function :

Basically, I check the distance between the hand socket and the hand target, if this distance exceed 10cm, I stop the movement. That means that I still have 10cm to move after it reaches the max extension, but I can never come back to move closer to the surface. It’s totally normal because the movement is stopped, but I can’t figure out a way of blocking the movement, but still being able to get back closer to the surface.

I need your help please :slight_smile:

So, instead of disabling user input add a counter input.

With everything as is, if the player moves backwards and the distance is 10cm or greater, push the player forward by the same value that the controller wants to go back - which can indeed be less then 1 if you use anything but a keyboard, so actually get the speed from the input and reverse it.

You could create this by just overriding the default controller behavior when a Boolean is tripped, so that you can then access the same functionality for other movements?
Like maybe if one of your feet is off into nothingness and the player tries to move that way…

Hi, thanks for responding, your approach is interesting, adding like a reverse force to the movement so that it can’t move furthermore when reaching the max distance.

I’m not sure I see what can be a counter input?

So if I get it right, by pushing the player in the opposite direction, when we reach the maximum distance, we will make him move backward by the same value; and so going back to the last “valid” location, where we can apply movement again, and where the distance is less than 10cm?

And yes, that’s a good Idea to override the default movement behavior. So I can just trigger that behavior to use this functionality every time a movement to somewhere is restricted

You can do with the opposite of the current axis - just shove them back into the wall essentially by multiplying the current axis by -1
using the InputAxis Forward(which handles backwards)
IF Axis == direction backwards AND custom state boolean AND distance from wall > 10 {
#No you don’t
Proceed to movement input.
The way I see it, the more you make that IF statement customized the better it will be as there won’t be much of a chance to accidentally trigger it.

Note that when using controllers and not keys the axis is a fraction of 1, so you want < and > instead of ==
But you get the point i’m sure.

Hi, Your solution worked fine, I can block the character movement when reaching the max extension, and move back again.
But now I get a jittering movement when I reach the Maximum extension.
That’s because when I still press the input key to backward even though I’m at max extension, the input would reversed and the movement would be towards the wall for a frame; then the frame later, I’m not at max extension anymore (since I’ve been brought a little bit towards the wall), so I can go backward again, and the frame later I’m back at max extension, so I’m brought back towards the wall, and so on and so on…
Sometimes, If I press the opposite direction,I can even break the condition If I do so just when it reverse the movement input.

I’ve been banging my head on it to find a smooth solution but I can’t figure out a way of doing so.

The gif is here :

Hum, that is a little different then I imagined. You are essentially climbing…

So is this the maximum range the character can reach or is he expected to be able to move forward?

if it’s a maximum range, then using what you already implemented which currently twitches you can just lock the movement by removing any input (axis value is 0 = no movement).
Now moving above that range is impossible via controller.

If you are making a climbing game this would be the point where you have to press a button to jump, for instance. And the dynamics for that are a little nutty but generally speaking, and stealing some Assassin Creed fashion thinking, jump toward the nearest observed grapple point or jump straight up and auto catch the same ledge to fall back down.

If you still need the character to move and detach you need to rely on axis strength for controllers. And keypresses for keyboard.
meaning using a controller you can tell if the user is pushing forward just a little (the axis is a fracion), if using a keyboard you get a straight up 1.

You have to isolate the axis button, and determine if it is coming from a key or a controller to drive the branches that matter.
this is near impossible when using Axis input configured with keypresses btw. But as a logical hack…

Save the previous axis value , set the axis value to a variable. You now have 2 axis to compare.
if the input before was 0 exactly and the input now is absolute |1| exaclty, chances are the user is at a keyboard. Chances because the controller can be just as fast when you jam it up…

either way, in this case you assume keyboard and lock the movement out when the apex is reached.
this means you are now in the state where input is locked, requiring either a jump or a key press.
This will force the controller user to back down gently and up gently revealing to the code he is on a controller, and moving to the branch where reacing 1 slowly can detach you.
it will also leave the keyboard user in a state where he will need to hit a different key, or let got the up axis.

At this point I would suggest the mesh move back to the middle of the grapple point slowly on it’s own if no controls are pressed. This makes both controller and keyboard users understand that the character couldn’t go that way or that the needed to jump.

Now that I think of it AC did just that anyway. If you edged up and could not jump the character would auto back down to a resting pose…

it may be worth your time to load up any of the AC games you have and break apart their motion system to note how they handled the different states/stages.
a good spot to just see animation might be ac2 in the scenes where Desmond only wears normal clothing so that no cloth simulation and moving parts obscure the view.

All that said, hopefully between setting the input to 0 and blocking their movement altogether and the checking of the axis strength you can concoct as solution to extricate the character from the wall…

Btw, a bonus detaching way… count seconds when at limit using a resetting timer.
if you are at axis 0, input is the detaching direction, and time elapsed is .5 seconds (where the axis is a constant 1) just assume the user wants to detach.
.5 seconds is a guess you’ll have to fine tune that to taste.

Yes I’m making a climbing system, so I think you understand now why I wanted to limit the movement when reaching the maximum arm extension.
I finally succeeded in blocking the movement by comparing the body -> arm direction to the controller input direction, and if the max arm extension is reached and the player is still pushing in the same direction, I block the movement, otherwise I let the movement happen.

Thanks for all those design advice. I’m actually making more of a climbing simulation system than an arcade one, but some ideas are really good and it’s definitely worth it to check out some mechanics in AC or Uncharted,Tomb Raider etc… to see how they made their design.

I like the idea of going back to the resting pose if no controls are pressed or if the grip is not reachable, for example. I may try to implement that.

If you are interested, I’ve just released the system as a community project on the forum : [COMMUNITY PROJECT] Dynamic Climbing System (DCS) - Unreal Engine Forums
The last implementations are not online yet, but I’ll release it when I finish cleaning commenting.