Making A Game Object Fly To The Screen - ScreenToWorldPoint problem

Hi all.

In my game I want at certain times for a game object to fly towards the top left corner of the screen.

My problem is that I can only seem to get the object to fly to the bottom right corner of the screen.

The update for the game object is below.

    function Update ()
{
    var target : Vector3 = Camera.main.ScreenToWorldPoint(Vector3(0, Camera.main.pixelHeight, Camera.main.nearClipPlane));
    var position : Vector3 = transform.position;

    if(Vector3.Distance(target, position) < 3)
        Destroy(gameObject);
    else
    {
        var velocity : Vector3 = target - position;
        velocity.Normalize();
        transform.position += velocity;
    }
}

Basically it converts the top left corner of the screen to world coordinates and moves towards the top left corner of the screen until it is close and then gets destroyed.

I can't figure out why the game object only goes to the bottom right of the screen. Any help would be appreciated.

If you are using the above code, then your object is indeed flying towards the top-left corner of the camera's near clip plane. I tested your script and it works perfectly as you say it should. In my test, with this exact script, I was able to have the game object fly to the top-left corner of my screen.

What I suspect you may be thinking is a problem is that your gameObject is likely disappearing before it ever appears to reach your top left corner even though it actually is heading there. There are some things to bear in mind here:

  1. The default Camera settings use perspective projection. This means that like a real camera lens, the perceived position in 3D space will be curved based on the lens (FoV in our case). Because of this, until the gameObject crosses the middle axes of the camera, it will appear to slow(slightly) closer to the center and will generally seem closer to the center when close to the camera than it actually is. You could use an orthographic projection, but then, there will be no apparent depth and this is likely not what you want in a 3D game engine.
  2. You are setting your depth to your near clip plane distance. If this distance is too small relative to your gameObject's size, then your gameObject may appear to head more towards the camera's position rather than your desired screen position before it disappears. (I recommend a distance of 1 or more for a cube of scale 1). The gameObject movement will still wrap around the lens projection, but by moving the clip plane back, the distortion is lessened.
  3. Your gameObject's size is relevant to where it appears to be moving. As your gameObject is moved by its transform (which is usually at the center), the side of the gameObject that the camera sees may clip too early or the object may generally appear not to have reached its destination because either the transform is located in an odd location or more than likely the gameObject's appearance is being projected such that it appears to be closer to the camera's center.
  4. You are destroying the object at a distance of three. Obviously the above to notes about relative scale apply. If you were to destroy the object at a smaller distance, you would see that it does indeed reach its destination, but because it was destroyed too early, it doesn't appear to. This is again due to perspective projection.

Solutions:

  1. Tune your scales and distances to accommodate the perspective projection and relative positioning.
  2. Translate by screen positions. At each frame, you would get the current screen position of the object and move according to your determined velocity. You would then get the world position of your object and apply it to the position. This will appear more as you want, except that again, as the gameObject gets close to the camera, its movement will appear to curve. You can either destroy it at the point where it curves (dependent upon your FoV) or compensate by accelerating the movement on the screen-space's z coordinate as it gets closer (doesn't really fix, but glosses over the problem).

You may want to go into more detail as to the look of the movement that you want if you want a more detailed solution, but this is generally why it may look wrong to you, but actually isn't and potential approaches to fixing it.

In addition to skovacs1's excellent answer, here's a long shot. If you have more than one camera, make sure you are viewing the output from the the one tagged Main. That's the one the code is using to determine the target coordinates. If you view the output from a different position, it will look wrong.

You also may have your camera rotated 180 degrees. :)