- Home /
Raycast missing moving Collider
Guys, I'm getting desperate here. This question was asked several times before by other people, but either my case is set up incorrectly or I don't understand what I'm actually reading, in any case I do have to resort to wasting your valuable time, which I already did to the poor forum guys, but unfortunately they don't have an answer so far.
I have a car. This car has a Rigidbody which is set to interpolate and continuous dynamic collision detection. The car has wheelchlildren, which as far as I can see ultimately move the Rigidbody in
public class Wheel : MonoBehaviour
{
[...]
void FixedUpdate ()
{
[...]
body.AddForceAtPosition (suspensionForce + roadForce, pos);
}
}
Additionally, the car has a PlayerObject as child. The player also has a rigidbody in case that matters, set to interpolate and kinematic when in car. Also a camera, which has a script that casts forwards from the camera to the center of the screen on buttonUp:
var vDist : float = 200;
var vHitObj : Transform;
function Update ()
{
if(Input.GetButtonUp("Fire2"))
{
Cast();
}
}
function Cast()
{
yield new WaitForFixedUpdate ();
var hit : RaycastHit;
if (Physics.Raycast (this.transform.position, this.transform.forward, hit, vDist))
{
Debug.DrawLine (this.transform.position, hit.point);
vHitObj = hit.collider.transform;
print(vHitObj);
vHitObj.SendMessage ("OnHit");
}
}
Furthermore, the car has multiple cubes that represent switches and such, to be clicked by the player. They aren't moved other than by the fact that they're the car's children. They have only a collider set to trigger, and a script that receives messages and triggers an animation:
function OnHit()
{
if(this.transform.parent.GetComponent(DoorCar).vStatus == 1)
{
this.transform.parent.GetComponent(DoorCar).vStatus = 0;
this.transform.parent.GetComponent(Animation).Play("CarDoorLeftOpen");
print("Door Open");
}
else
{
this.transform.parent.GetComponent(DoorCar).vStatus = 1;
this.transform.parent.GetComponent(Animation).Play("CarDoorLeftClose");
print("Door Closed");
}
}
Now, that works just fine when the car stands still or moves slowly. When I get over 50mph my raysasts start missing the cube and return the terrain behind them 9 out of 10 times. Now, as I said a google search returns multiple cases of this happening, I took care to have colliders where I should, no rigidbodies where I shouldn't, increased and lowered the timestep, as far as I can see I'm doing everything in FixedUpdate, but I have a feeling I missunderstand that somehow, I don't feel like I have control over when the position updates and when the casts trigger. Sometimes when I "lead" the Raycasts I do get the cubes, so that makes me think I'm updating incorrectly. Using layers is often suggested but it doesn't sound like my problem, It's not that I'm hitting colliders in front of what I want to hit, it's that I'm hitting stuff behind it. There was a nice solution that used a polygon library to raycast entirely without colliders, but alas, that doesn't work on moving meshes.
So yeah, please give me any insight you have on this, I just wanna click on multiple small-ish objects that move and trigger their scripts. I'd prefer I did something really stupid since that usually means less work, but really any new information is greatly appreciated.
Thanks for reading.
Edit: Thanks to Sir Reynolds I figured out I forgot I was moving the player position via script. And I wasn't using FixedUpdate where I should have.
I'll post the relevant scripts on the Forums, not that it matters much.
Thanks again guys!
Is there some technical reason why Cast()
waits until the next FixedUpdate? Seems to introduce an unneeded (tiny) lag, and feels more prone to out-of-scynch physics.
This post here made a plausible explanation of why thats preferrable.
"Yes it does make sense, otherwise the collision detection would be lagging a frame against some entities,[...]"-$$anonymous$$ZP
E// Well, that's a reason for why the colliders lag really, not the casts.
That thread is about raycast problems caused by moving inside Update. It seems to suggest that for rigidbody movement, raycasts are perfect in Update (all movement book-keeping has been done.)
But, again, you aren't mixing old and new positions or anything (is the camera moving with the car?) It just feels funny to me.
Just add an answer yourself, and move the relevant information from the comments into it!
Answer by Divinux · Sep 23, 2013 at 12:30 AM
I'm fairly confident it's fixed now.
Owen Reynolds' comment made me remember my "carseat" script that would set vPlayer.transform.position = vSeatpos.transform.position; which was necessary to keep the player in proper position and rotation. That happened in lateUpdate.
After multiple attempts that had an effect for better or worse, I settled on updating the playerposition to the seatposition in FixedUpdate, the car of course still in FixedUpdate, and the raycast mouse input in Update. Now all casts reliably hit the colliders where they should be at any speed, with the car on it's roof and everything.
Here's the sister of this post on the Unity Forums. I'll post all relevant code there since we were throwing around code there anyways.
So basically in the end, I did do something stupid and it was a quick fix codewise. I wasn't doing things in the right order, and I completely forgot about a translate in a different script. Owen's comment reminded me, and I really can not thank him enough, it makes such a huge difference.
Your answer
Follow this Question
Related Questions
Raycast/Non-Physics Collider Discrepancy 0 Answers
How to use a Raycast to see the distance traveled within a collider. 2 Answers
Move player to specific location and avoid obstacle. 2 Answers
Im trying to create a word game with a twist 0 Answers
Raycast not detecting ANY HITS AT ALL when starting inside a collider. 0 Answers