# Raycast inconsisten data.

Hello, I am trying to calculate the characters angle difference from 90 so i can structure a RotateFromTo to make him transfer from standing on the floor to standing on the wall. For some reason the data returned from each raycast is differnt making th angle finding process impossible.

If the character is standing up on the floor at 90 to the floor then the distance that both 45 degree raycasts should return the same value. but they are always different and sometimes one is zero. Any thoughts?

``````var hitDownDistance : float;
var hitRightDistance : float;
var hitLeftDistance : float;
var hitRight45Distance : float;
var hitLeft45Distance : float;
var leftAngle : float;
var rightAngle : float;

function Update(){
var hitDown : RaycastHit;
var hitRight : RaycastHit;
var hitLeft : RaycastHit;
var hitRight45 : RaycastHit;
var hitLeft45 : RaycastHit;

if(Physics.Raycast(transform.position, transform.position + Vector3(0,-1,-1), hitLeft45)){
hitLeft45Distance = hitLeft45.distance;
Debug.DrawLine(transform.position, transform.position + Vector3(0,-1,-1));
}

if(Physics.Raycast(transform.position, transform.position + Vector3(0,-1,1), hitRight45)){
hitRight45Distance = hitRight45.distance;
Debug.DrawLine(transform.position, transform.position + Vector3(0,-1,1));
}

if(Physics.Raycast(transform.position, transform.position + Vector3(0,-1,0), hitDown)){
hitDownDistance = hitDown.distance;
Debug.DrawLine(transform.position, transform.position + Vector3(0,-1,0));
}

if(Physics.Raycast(transform.position, transform.position + Vector3(0,0,1), hitRight)){
hitRightDistance = hitRight.distance;
Debug.DrawLine(transform.position, transform.position + Vector3(0,0,1));
}

if(Physics.Raycast(transform.position, transform.position + Vector3(0,0,-1), hitLeft)){
hitLeftDistance = hitLeft.distance;
Debug.DrawLine(transform.position, transform.position + Vector3(0,0,-1));
}

leftAngle = ((Mathf.Sin(hitLeft45.distance/hitDown.distance) * 180)/Mathf.PI);
rightAngle = ((Mathf.Sin(hitRight.distance/hitDown.distance) * 180)/Mathf.PI);
}
``````

There are two things of relative importance here. The origin of the raycast must be at the center of your object for this to work. So if your origin is at transform.position, and transform.position is at the character’s feet, this is not going to reflect accurately.

Secondly, you are collecting alot of data, and not using it.

Lets borrow some info out of a bezier curve book. You have 5 distances, and 5 directions. Each of those directions should have an associated value with it and a direction. Cast 5 rays, each of those rays gives you a distance response, or nothing. If it is nothing, then the distance is too great to have any affect on the direction.

So your math would be something like:

var direction=((1 - distanceX/maxDistance) * directionX) + ((1- distanceXY/maxDistnace) * directionXY) +…

What you first will do is satisfy all the directions and make them relative to the orientation of the player. so

``````directionX=transform.transformDirection(Vector3(1,0,0));
directionXY=transform.transformDirection(Vector3(1,-1,0));
directionXY.Normalize();
directionY=transform.transformDirection(Vector3(0,-1,0));
directionxY=transform.transformDirection(Vector3(-1,-1,0));//note the lower case x
directionxY.Normalize();
directionx=transform.transformDirection(Vector3(-1,0,0));
``````

Then you have to calculate the ray distance.

``````var center=transform.renderer.bounds.center;
var maxDistance=5.0;
var direction=Vector3.zero;
var hit=RaycastHit;
if(Physics.Raycast(center, center + directionX, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionX;
}
if(Physics.Raycast(center, center + directionXY, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionXY;
}
if(Physics.Raycast(center, center + directionY, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionY;
}
if(Physics.Raycast(center, center + directionxY, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionxY;
}
if(Physics.Raycast(center, center + directionx, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionx;
}

direction.Normalize();
``````

This gives you a weighted direction to normalize too. This then gives you a down vector for gravity, and an up vector for LookAts

Not sure why but your code isnt working for me. I made modifications to it to get it to work but I am still getting random errors and it will not compile.

``````private var directionX : Vector3 = transform.TransformDirection(Vector3(1,0,0));

private var directionXY : Vector3 = transform.TransformDirection(Vector3(1,-1,0));

directionXY.Normalize();

private var directionY : Vector3 = transform.TransformDirection(Vector3(0,-1,0));

private var directionxY : Vector3 = transform.TransformDirection(Vector3(-1,-1,0));//note the lower case x

directionxY.Normalize();

private var directionx : Vector3 = transform.TransformDirection(Vector3(-1,0,0));

var center : Vector3;
var maxDistance : float;
var direction : Vector3;
var hit : RaycastHit;

function Start(){
center = transform.renderer.bounds.center;
maxDistance = 5.0;
direction = Vector3.zero;
}

function FixedUpdate(){

if(Physics.Raycast(center, center + directionX, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionX;
}
if(Physics.Raycast(center, center + directionXY, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionXY;
}
if(Physics.Raycast(center, center + directionY, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionY;
}
if(Physics.Raycast(center, center + directionxY, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionxY;
}
if(Physics.Raycast(center, center + directionx, hit, maxDistance)){
direction+=(1-hit.distance / maxDistance) * directionx;
}

direction.Normalize();
}
``````

OK, it took me an hour to figure this out… And it has absolutely nothing to do with the rays other than the normals that they hit.

UnityGymnastics.html

So take the rays, add all the normals that hit together and divide them by the number that hit and you get an average normal. Calculate that normal against the Up vector of your model. Do a Vector3.Dot against the Right vector of your model to get if the angle is positive or negative. Then Mathf.Lerp the Z rotation of your model. This will rotate it towards the average normal direction. Apply some gravity to the Down vector and it will. fall towards the facing you want it to.

Remember to use rays about 5 times the height of your model. Except the left and right rays, those have to be about 4 times less than that. You get some pretty bad results from long side rays.

In my case, I used a momentum variable to manage left, right and jump movement. Making sure to multiply that times 0.9 every frame so that you don’t continuously move.

It’s not perfect. When you get to an edge, it flickers between the two normals that it hits. But it is incredibly smooth.

My mistake in pointing you in a bad direction. The raycasts should be somehting like this:

if(Physics.Raycast(center, directionXY, hit, maxDistance)){
}