- Home /
If my character's raycast collides with an object in front of it (such as a wall), how can I temporarily disable any movement going forward?
Hi everyone,
I'm making a 3D platforming game in Unity and I need help in trying to figure out how to disable my character from moving forward when its raycast collides into an object in front of it. The "W" key or the 'UP' arrow key moves my character forward (either the WASD control setup OR the UP, DOWN, LEFT, RIGHT arrow control setup can be used to control the character). The reason why I want to disable those two keys is because I want to prevent any attempt at my character moving forward if the raycast in front of the character has a collision with any object, such as a wall.
However, I should also point out that I don't want to disable my characters movement completely because I still want my character to be able to move backwards even when the raycast detects a collision (The "S" letter key or the 'DOWN' arrow key will move the character backwards). How can I accomplish this? I tried doing this with a Boolean but I had no luck. I provided a screenshot image of my code showing what I have so far, but if for any reason you aren't able to see the screenshot, I also copied and pasted a slightly shorter version of that same code below. Please help if you can. Thanks :)
bool enable = Input.GetKeyDown(KeyCode.W);
//added this bool in hopes of helping me disable the movement key
if (hit_info.collider != null)
{
print("Raycast collided!");
enable = false;
// My 'enable' bool method did not work
// However, I know something is suppose to go here, but not sure what
}
else
{
print("Raycast is no longer colliding");
enable = true;
// enable method did not work at all
}
Have you considered using rigid bodies, and allowing unity physics to handle this? The advantage to doing this is seen when collision are not perpendicular: What if the wall i front of your player is at 45 degrees? In this case, should the character move along the edge of the wall when pressing forward?
Yes of course I'm using rigid bodies, in fact it would be impossible to have a player character (or any moving object within my game) without a rigid body. From what I learned before, the only things that dont need a rigid body are stationary objects that don't move.
And the way I have my raycast set up is that it shoots out directly to the front of the character. Its positioned in the middle of my character (in the torso area), so if the player bumps into a wall from the side then it can still keep moving forward. Its only when the player crosses paths directly with a wall in front of it that I want to disable the forward key. Thats what I have trouble figuring out.
Like Gurth, I would also suggest letting Unity's built in physics do the heavy lifting here. Simply set the physics in the Edit > Project Settings > Physics menu, and let Unity handle the rest. ($$anonymous$$ake sure to set up the GameObjects on the proper layers as needed.)
Oh ok, but you're saying that by doing that method I can disable the forward key if the raycast in front of my character collides with an object in front of it? How exactly would that work?
Because I dont want to disable any movement going forward unless that raycast has a collision (I only have 1 raycast on my character).
The Colliders: Like answered already by Otaku_Riisu, simply add Collider's to your GameObject's and Player. After that set up the Physics through the methods I described above.
The Controller: Now that the Collision part is set up, add a CharacterController Component to your Player.
Inputing Commands: Then, make a script 'PlayerControls' and add that to your Player GameObject. In PlayerControls, get the CharacterController with .GetComponent(), then using the Update() callback, get input from the user and feed it to the CharacterController using the .$$anonymous$$ove() method.
Unity will automatically look for collisions through the .$$anonymous$$ove() input. This way you can get rid of that Raycast, and let the pre-built Components do the work for you.
Answer by Otaku_Riisu · Jun 03, 2016 at 06:16 AM
It would probably be a lot easier to use colliders instead of scripting everything.
Let unity do all the heavy lifting for you
Yes, I already do have a Box Collider and a rigid body on my character. All I'm trying to figure out is how to disable the forward movement key when the raycast that shoots out in front of my characters torso (shooting in a forward direction) collides with an object directly in front of it but I cant figure it out.
Because if for example my character jumps against a wall and the raycast is colliding with the wall, I want to disable the forward movement (if the user presses any of the forward keys) so that the character slides down smoothly to the ground ins$$anonymous$$d of getting stuck on the wall.
I'm trying to find out how to accomplish this but I can't :(
Two questions
Are you using root motion?
Is your character controlled by a rigidbody or a character controller?
1) Not sure what root motion is, so I am going to say no to that question.
2) And looking through my code, there is a line that says " rb = GetComponent();" so I'm pretty sure my character is controlled by a rigid body. Not sure how a character controller would work, so I will say that yes its being controlled by a rigid body.
Any further help will be greatly appreciated :)
So actually the core problem we're trying to tackle here is that the player gets stuck on the wall ins$$anonymous$$d of sliding down when you're "pressing against the wall" in the middle of the jump?
You kinda should've opened with that :D
This is easily solved. $$anonymous$$ake a new Physic $$anonymous$$aterial asset, and assign all friction values to zero. Assign it to your wall colliders (not player or floors, you want to slide to a halt there). No amount of force will now keep the player stuck because there's no friction taking place.
@ Eudaimonium, Thanks! Your suggestion definitely worked! But before I was able to get it to work, there was 1 last thing that I had to do. The thing is, I realized that my characters movement speed value was much greater than the gravity value, so there was not enough gravity force to pull my character down to the ground which made it get stuck on walls when it jumped against them (the higher speed value was overriding the lower gravity value)
What I first did before applying your technique, was adding an "if" statement saying:
if (character is jumping) { gravity = -100; }
else { gravity = -25; }
Now when my character jumps (especially against a wall), the gravity value will be much greater than its speed so it will pull the character down and make it slide smoothly if its against a wall. So ins$$anonymous$$d of the higher speed overriding the lower gravity, now the higher gravity overrides the lower speed.
Additionally, adding the Physic $$anonymous$$aterial as you suggested made the character slide down more smoothly and controlling the character felt much more fluid.
Thanks for your help! I really appreciate it :)
Your answer
Follow this Question
Related Questions
How to disable halo when it is already enabled via script C# 0 Answers
Disable shooting whilst reloading? 1 Answer
How do I disable a key on the keyboard when it enters its fuction? 1 Answer
If your pressing one key, how to disable another? 3 Answers
if collider is disabled can i check click event on that gameobject? 1 Answer