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!

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
}

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
}

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.