I have a question on how to limit an object moving inside the world’s boundaries.
Until now, I was mostly placing colliders around the walkable areas, but it’s pretty long, boring and error prone. I’m sure there’s a much better way to achieve this, but I’m not sure how. I’ve heard using Vector3.Reflect could be a way.
Here’s what I have:
A player that moves with a virtual joystick
A plane that’s actually the walkable area (but could be a more complex form)
What I do:
Fire a raycast from my player’s position to the ground to check if he is grounded
Fire another raycast from my player’s position + my player’s forward, to check if ahead is a floor area or nothing
The behaviour I need:
When the forward raycast return a non walkable area, stops the player from going forward, but can still go on other directions (watch my wonderful drawing). I want my player to kinda “slide” along the walkable area while never going forward. I’ve heard that using Vector3.Reflect to like, apply opposite forward direction and keeping the other directions is the solution. (I’ve tried subtracting playerPosition.forward though, but it’s glitchy and not exactly the result I have in mind.)
I want it to be done with raycasts, not with the NavMesh, not with a lot of colliders around the plane, not with checking if the player is left and calculating the size of my plane etc… because the surface could be something else than a plane or a basic rectangular shape.
Your description above does not sound like a pure math problem but rather a content authorship problem.
Could you use Vector3.Reflect() in your game? Certainly!
But you would still need some way to define the things that go into Vector3.Reflect()
I’ve always done push-on-wall-sliding by either a) letting the physics just take care of it, or b) shortening and/or deflecting the proposed walk direction based on what it hits, sort of “manual” sliding by casting left/right and seeing which side might be more amenable to walking.
You don’t really need Vector3.Reflect. Instead you simply want to do 4 raycast offset in the 4 cardinal directions to see if there’s a floor in that direction or not. Now all you have to do is limiting / setting the individual components of the velocity / movement vector to 0 if there’s no floor in that direction. Of course it could be optimised to only do the relevant raycasts (doing only the right one when moving right, or doing top and left when walking somewhat up and left). Though when using a stick to move around you almost always move in two cardinal directions at once so you would do two raycasts anyways.
Though if you want to stop the movement dead on the edge, this is a bit more difficult. So if you’re looking for the movement mechanic of Minecraft when crouching where you can walk up to the edge without falling off, you would also need to check where the exact edge below you is. For this you really need 8 raycasts (the 4 cardinal directions as well as the 4 diagonal ones). The raycast that’s actually “opposite” your movement direction would tell you the floor you’re actually on. Depending on the geometry of your world, finding the edge of that floor would be quite different. If the floor actually has a side wall where it falls off, you can do a sideways raycast from the outside to find the exact edge. If it’s like minecraft it would be much easier since everything is made up of blocks and boxes anyways. Though getting it right is not that easy. As I said it highly depends on your actual geometry what approach would work and which doesn’t