Is there anyway that i can make it so that the first person controller, when it touches the edge of a cube, it prevents it from moving off of that cube? I cant have just normal cubes at the edge and have the mesh renderer turned off because my worlds are randomly generated in size and shape… Help would be much appreciated… Thanks in advance.
Do you use Colliders? In this case box colliders for your world and mesh or capsule or whatever colliders for your player?
how is the world generated then?
I’m using a "CheckNeighbours()"function to check all cubes for edges in a foreach loop and have walls added. the world is generated only through x and y axii in my case however…
The world is generated with individual cubes, I have a maze generator and im making it into a game, but I dont want the player to just be able to walk off of the world… and my world is only generated in the x and z, then it pushes the wall blocks up, so the CheckNeightbours() function would find unnecesary wholes in the maze, or maybe i could make it check then push everything up?
You could always try using raycasting to tell if there is a cube in the direction they wish to go. If not, don’t allow them to move.
How would one do this?
Not saying this is the best way but I’d set up four empty game objects with a ray cast straight down - arrange them around the player (parented to, but not over the player) in the four directions. Use four on each corner if you want more precise checking. Then in the move script, check the raycast hit each time a player tries to move. If the ray hits nothing, set the move speed for that direction to 0. So if the player is strafing to the right and the ray caster on that side doesn’t hit anything, move speed drops to zero, for that direction only. Then when you move away from the edge and the raycast hits something, it sets the speed back to normal. That’s pretty much all I got without seeing your project and all the code.
I see what you mean… but wouldnt that constant raycast checking drop the framerate quite a bit?
Four shouldn’t. 400 would. I suppose you could also put a long, skinny collider instead of a ray and check for collisions. Just make sure they go through the floor. Then if the collider doesn’t hit anything on that side, you stop the movement that way. But I don’t really think that will be any more efficient than four rays. You could also deactivate any rays (or colliders) that are on the sides that are not in the direction you are moving, so if you are moving back, disable the front, left and right rays/colliders. Might save a little.
how would i stop the movement for the player if the raycast of lets say, var cubeRight hits nothing? Im terrible with RayCasting >.>
That all depends on your movement script. If you are using the keyboard to move, the easiest way would be to do something like:
if (Input.GetKey(“up”) Physics.Raycast(raycasterF.position, -Vector3.up, out hit))
//move forward
RaycastF is a transform so you’ll need to set it like a normal variable:
public transform raycasterF;
and then just drag the forward ray cast object into the variable in the inspector.
This will only work if there is nothing under the cubes for it to hit. If there is anythign down there, you will need to add another compare to make sure “hit” is the cube.
Im just using the default first person controller
I only have access to Unity 3 right now so what I’m saying MIGHT not be relevant to any later versions…
Anyway, there is a script attached to the first person controller called CharacterMotor.js
In that script there is a function called:
function MaxSpeedInDirection (desiredMovementDirection : Vector3) : float
desiredMovementDirection is what you need to check to see what direction you are going. It is a vector 3. When you are going forward it is 0,0,1. Back is 0,0,-1. Left is -1,0,0 and Right is 1,0,0.
You’ll need to add your ray casters to this code as I suggested above (though that is C# so you might have to change some) and instead of checking on the input key, you’ll check on the desiredMovementDirection.
ok cool, thanks
Keep in mind I am totally improvising and have no idea how well this will work.
Alright ![]()
Did a little test of my own. I used this code as the first part of that function:
var hit : RaycastHit;
if (!Physics.Raycast (rayF.position, -Vector3.up, hit))
return 0;
and it does make the player stop before falling off. It just doesn’t allow the player to move again afterward unless you rotate so the ray hits something so you’ll have to play around with it but the theory is sound: it will make the player stop. (don’t forget to declare “rayF” as a transform variable (var rayF : Transform; ) where the other variables are called and assign a transform to it in the inspector.
Alright, ill try that and play around with it
Refined it a bit:
if (!Physics.Raycast (rayF.position, -Vector3.up, hit) desiredMovementDirection.z>0)
return 0;
if (!Physics.Raycast (rayB.position, -Vector3.up, hit) desiredMovementDirection.z<0)
return 0;
if (!Physics.Raycast (rayR.position, -Vector3.up, hit) desiredMovementDirection.x>0)
return 0;
if (!Physics.Raycast (rayL.position, -Vector3.up, hit) desiredMovementDirection.x<0)
return 0;
And I was able to run around the screen and not fall of the edge. You can change the distance it checks to the edge simply by moving the ray caster objects in and out from the player. I haven’t tried anything more complex than a simple plane but it still worked in every direction. I’m not sure how foolproof it is though. It may be possible to hit an edge at a strange angle which allows the player to still fall off.
So the RayF, RayB, RayR, and RayL are variables which hold boxes around the player, with raycasts pointing down?