- Home /
How can I extend my linecast?
I have a basic idea about how to do this, but I'm having trouble with the math behind it.
Essentially, I have a camera that orbits around the player in a 3rd person view, and I'm implementing a system that moves the camera in closer if something gets in the way. I've figured out how to make this work. However, I want to extend the linecast past my end vector about half a unit so that I can create a little buffer between the camera and the wall to avoid clipping into it.
I can't simply subtract from the linecast distance, because it moves the camera away from the wall. The camera will Lerp back to the default distance, hit the wall, and move away again, creating a very annoying effect.
What I need is the unit vector of the linecast so I can use it to find a position vector 0.5 units from my camera. I want to use this as the endpoint instead, effectively "extending" the linecast behind my camera.
Here's a bit of my code for context:
// Linecast to move the camera closer to the player if something gets in the way
RaycastHit linecastInfo;
if(Physics.Linecast(player.transform.position, Camera.main.transform.position,
out linecastInfo))
{
// Ignore really short linecasts
//(buggy linecasts are constantly detecting hits at extreme close range, why?)
if (linecastInfo.distance > 0.5f)
{
currentDistance = linecastInfo.distance;
}
}
else
{
currentDistance = Mathf.Lerp(currentDistance, defaultDistance, 0.75f);
}
BONUS: If anyone can tell me why my linecast is spazing out and constantly recording hits at extremely short distances (like 0.02 units, 0.004 units etc) even when nothing is obstructing the view, that would be great. Right now I have a pretty ugly hack in place to throw out any linecasts under 0.5 units in distance.
Answer by whydoidoit · Feb 13, 2014 at 03:59 AM
Well it's a pretty good reason to use a Raycast rather than a line cast - in either case you need the vector to the camera...
var toCamera = Camera.main.transform.position - player.transform.position;
var distance = toCamera.magnitude + 0.5f;
var vector = toCamera.normalized;
if(Physics.Raycast(player.transform.position, vector, out raycastHit, distance)) {
}
I would imagine you are currently intersecting the actual player when you get your dodgy results - so perhaps:
if(Physics.Raycast(player.transform.position + vector * 1, vector, out raycastHit, distance -1)) {
}
Which offsets the start point.
Thanks a bunch for the help on that. The first part is spot on. Unfortunately now I have a whole new problem. It looks like you were right about the raycast colliding with the player collider. I still don't understand why it would be so random. However, if I move the start point of the raycast far enough away so that it doesn't collide with the capsule collider at the highest camera angle, it misses walls that are close to the player at a more level camera angle. This wouldn't be an issue if I was using a sphere collider, but I'm not sure what to do about it for the different camera angles.
Is there perhaps a way to ignore the first collision? Although I'm not sure that would even work because the problem is so intermittent, and I'm not entirely convinced that's the root of the problem.
So what I do is raycast from the camera to the centre mass of the player (the other way around to you) and then move the camera if the centre mass is obscured...
I actually check if it hits the players collider in other words.