- Home /
Detect if object moves between two points
Basically I'm building a catapult (This style: http://www.comparestoreprices.co.uk/images/ev/everythingplay-super-sling-shot-catapult.jpg), you can currently pull it back but it needs to detect when the ball passes through the two points. Any idea how i might go about doing this? The catapult is constantly moving and twisting so I can't just say when it passes x = 100 or whatever.
Thanks in advance!
Answer by boribhi · Aug 03, 2010 at 10:18 PM
Try to place a collider ,say a box collider, at the point you want with its trigger checked, then attach a script to it like this:
function OnTriggerEnter (ball : Collider) {
//do something here
}
Answer by Bampf · Sep 15, 2010 at 07:25 PM
boribhi's solution is a good, straightforward solution, definitely worth trying.
But note the following problem: if the ball moves very fast through the collider then it may sometimes pass completely through the collider between frames. This will happen more often the worse your frame rate is.
There are two simple ways to make this less likely. One is to simply to make the collider very deep, so the ball is less likely to pass through it undetected. The other is to reduce the physics timestep (increase the rate of FixedUpdates) in the project's settings. (This may effect overall performance of your game though.)
If you take care to test the above on slow machines OR don't care about slow machines, then you may not need to do anything else.
Otherwise, here are two ways to detect the ball no matter how bad the framerate is.
1) Use a collider as originally suggested, but add the following safety check. During each Update (or FixedUpdate) do a Linecast from the ball's previous position to the current position, and see if that ray hits the collider.
2) You can use math rather than colliders. First construct the Plane that passes through the catapult arms. Then you can use Plane.SameSide to test if the ball's previous position is on the same side of the plane as the current position. Code would look something like this:
Plane p = new Plane(catapult.transform.Forward, catapult.transform.position);
if (!p.SameSide(ballOldPosition, ballNewPosition))
{
// do something
}
could also make the detection continuous dynamic (assu$$anonymous$$g rigidbodies are used, which i would think they would be.
True. Continuous and Continuous Dynamic options were added in Unity 3, and the documentation for Rigidbody covers them pretty well. Worth a look, though be aware of the performance hit.
Answer by Mike 12 · Sep 15, 2010 at 07:28 PM
Or, you can implement something which probably uses less resources, by casting a call to Physics.Linecast library procedure. Here's what I have in mind:
float x1 = 0.0f;
float y1 = 0.0f;
float z1 = 0.0f;
float x2 = 1.0f;
float y2 = 1.0f;
float z2 = 0.0f;
Vector3 point1 = new Vector3(x1, y1, z1);
Vector3 point2 = new Vector3(x2, y2, z2);
if(Physics.Linecast(point1, point2, MonoBehaviour.kDefaultRaycastLayers))
// Your script has detected that something has passed through it.
Your answer
Follow this Question
Related Questions
Joint confusion - Bobble head 0 Answers
First Person Slingshot 0 Answers
Strange physics behaviour with spring joints and side walls. 1 Answer
Spring in unity 0 Answers