- Home /
Keeping the character controller grounded.Need help completing my code.
I know this question has been asked before. The problem is that the answers don't really help me or I don't understand them. So I'm writing my own code. I need my charactercontroller to stay grounded when it walks down a slope. If I could create a Raycast variable then I could probably finish the code but I'm not sure if that's even possible, I tried but got an error. Anyway, here's my code.
var distToFloor : float = 1.3;
var isFloored : boolean;
function Update()
{
Floored();
print(isFloored);
}
function Floored()
{
if(Physics.Raycast(transform.position, Vector3.down, distToFloor))
{
isFloored = true;
}
else
{
isFloored = false;
}
}
What I want to achieve now is to snap my character to the floor so that he is grounded whenever isFloored is true. I don't want to increase my gravity to achieve this because it'll cause other problems.
I found this code which I think is exactly what I'm looking for. Can someone translate this to unityscript. I understand most of it but there's like 2 lines holding me back.
CharacterController controller = GetComponent<CharacterController>();
float snapDistance = 1.1f; //Adjust this based on the CharacterController's height and the slopes you want to handle - my CharacterController's height is 1.8
RaycastHit hitInfo = new RaycastHit();
if (Physics.Raycast(new Ray(transform.position, Vector3.down), out hitInfo, snapDistance)) {
isGrounded = true;
transform.position = hitInfo.point;
transform.position = new Vector3(hitInfo.point.x, hitInfo.point.y + controller.height / 2, hitInfo.point.z);
} else {
isGrounded = false;
}
I updated my answer to include a translation of this code from C# to Unityscript.
Answer by ncallaway · Jan 08, 2014 at 01:18 AM
You can use the alternate overload of Physics.Raycast that fills out a RaycastHit class for you. Then, you can use this RaycastHit class to determine where that ray intersected the ground. You can use this position as the place to put the character's feet:
void Floored()
{
RaycastHit raycastResult;
if (Physics.Raycast(transform.position, Vector3.down, out raycastResult, distToFloor))
{
// this assumes the character's feet are at transform.position. You might
// need to adjust this up or down to account for where transform.position should
// be relative to the floor...
transform.position = raycastResult.point;
isFloored = true;
}
else
{
isFloored = false;
}
}
Just noticed that your question was in uJS. The relevant section in uJS looks like:
var raycastResult : RaycastHit;
if (Physics.Raycast(transform.position, Vector3.down, raycastResult, distToFloor) {
transform.position = raycastResult.point;
// rest of the code snippet omitted.
The code that's in your comment is very similar to this. Here's the code from your comment translated into unityscript:
var controller : CharacterController = GetComponent(CharacterController);
var snapDistance : float = 1.1f; //Adjust this based on the CharacterController's height and the slopes you want to handle - my CharacterController's height is 1.8
var hitInfo : RaycastHit; // note, you don't need to allocate a new RaycastHit() here. You don't need to do that in the C# code either. It's done automatically by Physics.Raycast().
if (Physics.Raycast(new Ray(transform.position, Vector3.down), hitInfo, snapDistance)) {
isGrounded = true;
transform.position = hitInfo.point; // note: this line seems redundant. It can (and probably should be) deleted.
transform.position = new Vector3(hitInfo.point.x, hitInfo.point.y + controller.height / 2, hitInfo.point.z);
} else {
isGrounded = false;
}
Lol after countless hours of searching and testing I just came across raycasthit on my own like 30 $$anonymous$$utes ago and have been doing more testing. The docs are a little confusing to me sometimes. Anyway now my character is bouncing around like he is having a seizure. Your code will definitely speed things up. Gonna compare your code to $$anonymous$$e and see what I need to change.
if(Physics.Raycast(transform.position, Vector3.down, rayLength, distToFloor))
{
isFloored = true;
transform.position.y = transform.position.y - (controller.height / 2 - rayLength.distance);
}
I was damn close. I even had raycastResult as rayLength
transform.position.y = transform.position.y - rayLength.distance + (controller.height / 2);
I'm co$$anonymous$$g across a problem. $$anonymous$$y character is falling through the ground. I have distToFloor set to 1.3, if I lower it to 1.07 I wont fall through the ground but I don't stay grounded when I walk down a slope. I also noticed that even if I'm way up in the air rayLength is making contact with something, so it's not shooting a ray only to the amount that distToFloor is set to.
Does your character have a Collider on itself? If so, it's possible that your ray is intersecting with the character's own collider, causing it to "drift" down over time.
Are you using the layer$$anonymous$$ask property of Physics.Raycast() to ensure that you're only targeting the ground? If not, you could create a separate layer for the ground, tag the ground with that layer, and pass that in as the layer mask for Physics.Raycast().
Or, if you only have one "ground" object in your world, you can call Collider.Raycast on the ground's collider and skip all the layer stuff.
Im only using the character controllers own collider. Tried transform.position.y = transform.position.y - rayLength.distance + (controller.height / 2); and it works great when I walk downhill, but messes up when I walk on normal ground lol. I'll keep trying and I'll let you know if I find a solution.
Your answer
![](https://koobas.hobune.stream/wayback/20220613125818im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Character controller not grounded at start. 1 Answer
Continuously rotate a gameobject on 1 axis perpendicularly to another gameobject's normal? 1 Answer
Animation through graphics in FPS controller, weird character controller issue, NEED help! 0 Answers
Changing the landing and switch directions of standard assets TPC controller 0 Answers
How to make Ray collide with Character controller ? 1 Answer