Hello,
i am creating a ball rolling game where the ball should never leave the ground.
so i tried to do that with raycasting, but it doesn’t seem to work, the ball is still coming off the ground without a problem, so it seems that my script doesn’t affect my player.
A useful trick to troubleshoot raycasts is to use Debug.DrawRay or Debug.DrawLine.
It draws a line in the editor so you can see what the raycast is doing:
It should put the ball right where the raycast hit the ground.
Also, you need to make sure the the raycast is not actually hitting the ball if the ball has a collider. Other wise, the ball would move to its own position;
You could use pass in a layerMask to Physics.Raycast to ignore the layer that the ball is on. http://docs.unity3d.com/Manual/Layers.html
Do searches on the forum for examples of using creating a layerMask to pass into Raycast
Another way, is to start the raycast out so it starts BELOW the ball, so it doesnt collide with the ball.
example: Debug.DrawRay(transform.position + 2.0f * Vector3.down, Vector3.down * 200, Color.green);
The approach I use to to put the ball on it’s own layer, and have the raycast ignore that layer.
here is an example:
int mask = Physics.DefaultRaycastLayers;
int customMask1 = 0x1 << BALL_LAYER; //Example: BALL_LAYER = 8;
mask = mask & ~(customMask1);
bool hit = Physics.Raycast (ray, out hitInfo, distanceToCheck, mask);
Or for now, just put the ball on the IgnoreRaycast layer, and then don’t worry about creating a mask. Because the ball is on the IgnoreRaycast layer, Unity will automatically ignore raycast collisions with the ball.
Personally, i would ignore this method for now, and just try to start the raycast out in a position so it doesn’t hit the ball. (only required if the ball has a collider).
Get that working first. Then you can expirament with the layer method.
alright, my ball does have a collision, and i have setup the raycast like you said, it should ignore the ball since the ball has no layer, and the floor is the only on the layer named floor.
even when i remove the ball collider it doesn’t work i noticed, what could cause this, the debug.raycast shows that it does hit the floor tho.
I would suggest start printing debug statements to the log file to console see what is happening.
Do print statements like:
Debug.Log("The raycast hit: "+hit.collider.name);
Debug.Log("The point of impact is: "+hit.point.y);
To verify what the raycast is hitting and where it is hitting.
Maybe something else is moving the ball?
Is the script attached to the ball?
In the script attached to the ball, put the code in the update function:
void Update()
{
StayOnGround();
}
You could try forcing the ball to a constant y value to see if that works.
void Update()
{
transform.position = new Vector3(transform.position.x, 0.0f, transform.position.z);
}
if the ball has a rigidbody, you need to move the position of the rigidbody instead of the transform position.
so far it says that the point of imapact is 0, no matter where the character is at, so i assume it still hits the ball collider
About the collision name, i get an error: NullReferenceException: Object reference not set to an instance of an object.
not sure what’s causing this.
i also forgot to mention that it’s a 2D game, but i am not working with Physics2D, can this cause the problem?
i’ve debugged for a bit, and i created an emtpy game object with just one script, with only the raycasting in it.
and it just doesn’t seem it hit anything.
im going to try using Physics2D now.
I kinda got it working!
It is hitting the player itself now, and when i remove the collider from the player it hits the ground and then it works!
but i can’t seem to get the layer mask working, i have implemented the layermask, but it still hits the player, this is what i’ve got now:
int layerMask = 1 << 8;
void OpDeGrondBlijven()
{
RaycastHit2D hit = Physics2D.Raycast(transform.position, -Vector2.up, layerMask);
if (hit.collider != null)
{
transform.position = new Vector2(transform.position.x, hit.point.y);
Debug.Log(hit.distance);
}
//Debug.Log("you hit " + hit.collider.gameObject.name);
}