Player:Move() - Is there any way to cancel it if the player gets stopped by a wall?

Hi!
So I’ve been experimenting with the ControlModule scripts to add some additional functionality to the default character’s movement options. One bit of difficulty I’ve run into is this:
When you call Player:Move(), you pass in the direction you want the player to move in as a vector3, and it will continually move in this direction forever. However, sometimes the player will run into a wall and despite not moving any farther will continue to try moving in that direction with no success.

My question is this: Is there any clean ways of detecting when this happens, so I can manually set the move vector to (0,0,0)? I suppose I could do a position check between render steps but it seems kind of hacky and might not always work.

2 Likes

Try raycasting in the direction of the player from their feet to their heads and/or checking if their average velocity over a few frames seems to get lower (indicating that they are walking slowly for some time).

Is there any reason you can’t use the .Touched event?

Is there any reason you can’t use the .Touched event?

Touched event fires when the player touches a part. Touching a part does not always stop the player from moving (e.g. when the player is traveling over a floor, or the part is a stair step.)

Try raycasting in the direction of the player from their feet to their heads and/or checking if their average velocity over a few frames seems to get lower (indicating that they are walking slowly for some time).

I take it that means there isn’t an official way to do this then. That’s a shame.
I’ll see what I can do with this technique but if anyone knows of a better method I’m all ears.

I mean, you could set the player’s walkspeed to 0 and just have a script check for it to touch the set parts. But then you’ve got to make sure it gets set back to 16 whenever you move the player or you let them walk again. But it is a somewhat hacky way and sloppy.

You could use the CollectionService to tag the walls which would stop the players’ movement and then on the .Touched event you can check if the part touched has the tag and then set the movement vector to (0,0,0)

You could use pathFiding. This is the most ‘offical’ way you could do it. :Move() is meant to go infinitely, it does not use pathfinding or ray casting.

1 Like

You could raycast from where the player is, to the location where the player wants to get moved to. If the raycast hits something, then don’t use Player:Move() (or move them to the place that the raycast hit). If the raycast doesn’t hit anything then move them.

Yes the only thing is that you better be doing this on the client otherwise the server may end up suffering.

1 Like

Not necessarily. The server doesn’t “suffer” because of inexpensive equations like this, it’ll simply be desynchronised by a bit (as evident by stuttering when placing certain effects on the server). You also don’t want to unnecessarily put server memory towards operations that can be handled from the client.

Rays are expensive when you start applying long lengths to them. Short rays aren’t much and you can create hundreds of them per frame without any major or noticeable performance hits.

1 Like