- Home /
Question by
Aladine · Oct 21, 2013 at 12:03 AM ·
raycastcollision detection
weird Skin width problem with raycast collision
Hello everyone, am trying to check for collision using raycast but am facing a very weird problem and i don't know how to solve it, the collision works perfectly when the skin width (distance between ray origin and hit point) is bigger than 0.5 but in that case the object stops before it actually hit something, and when i reduce the distance i had this very strange behavior, sometimes it works and sometimes it didn't i uploaded a youtube video here i also uploaded the game package here
and finally here is all the code i use to make the box move and collide :
using UnityEngine;
using System.Collections;
public class J2PlayerMovement : MonoBehaviour
{
public float speed ; // speed
public float ySpeed, yDir; // Y direction & x speed
public float xSpeed, xDir; // X direction & x speed
public float maxDist ; // max distance between ray origin and hit point
private RaycastHit hit ;
private Transform myTransform;
float tmpYdir,tmpXdir;
[HideInInspector]
public Vector3 myPos;
void Start ()
{
myTransform = transform;
myPos = myTransform.position;
ySpeed = xSpeed = speed;
tmpYdir=tmpXdir=0;
}
void Update ()
{
//set the directions
xDir = Input.GetAxisRaw ("Horizontal");
yDir = Input.GetAxisRaw ("Vertical");
//save the last direction
if(yDir!=0){
tmpYdir=yDir;
}
if(xDir!=0){
tmpXdir=xDir;
}
//check for collision
collision ();
//move up down
myPos.y += (ySpeed * yDir) * Time.deltaTime;
//move left right
myPos.x += (xSpeed * xDir) * Time.deltaTime;
//apply
myTransform.position = myPos;
/**Note : i changed the order and the resulst is always the same **/
}
//check for collision
void collision ()
{
//set the Y speed to the default speed value
ySpeed = speed;
//make 3 rays upon/under the object
for (int i = -1; i<2; i++) {
//set ray setting
Ray ray = new Ray (
new Vector3 (
myTransform.position.x + myTransform.localScale.x / 2 * i,
myTransform.position.y + (1 * Mathf.Sign (tmpYdir) * myTransform.localScale.y / 2), 0),
new Vector3 (0, Mathf.Sign (tmpYdir), 0)
);
//check if one of those rays hit something
if (Physics.Raycast (ray, out hit, Mathf.Abs (tmpYdir) + maxDist)) {
//calculate the distance between ray origin and the hit point
float dist = Vector3.Distance (ray.origin, hit.point);
Debug.DrawRay (ray.origin, ray.direction, Color.yellow);
//if distance reach the limit
if (dist <= maxDist) {
//stop moving
ySpeed = 0;
Debug.DrawRay (ray.origin, ray.direction, Color.red);
}
}
//if you're not touching anything
else {
Debug.DrawRay (ray.origin, ray.direction, Color.green);
}
}
/*********************************/
/*SAME ABOVE PRINCIPLE FOR THE 2 OTHER DIRECTIONS*/
/*********************************/
xSpeed = speed;
for (int i = -1; i<2; i++) {
Ray ray = new Ray (
new Vector3 (
myTransform.position.x + (1 * Mathf.Sign (tmpXdir) * myTransform.localScale.x / 2),
myTransform.position.y + myTransform.localScale.y / 2 * i, 0),
new Vector3 (Mathf.Sign (tmpXdir), 0, 0)
);
if (Physics.Raycast (ray, out hit, Mathf.Abs (tmpXdir) + maxDist)) {
float dist = Vector3.Distance (ray.origin, hit.point);
Debug.DrawRay (ray.origin, ray.direction, Color.yellow);
if (dist <= maxDist) {
xSpeed = 0;
print ("xx");
Debug.DrawRay (ray.origin, ray.direction, Color.red);
}
} else {
Debug.DrawRay (ray.origin, ray.direction, Color.green);
}
}
}
}
Comment