Fall off left side of screen and spawn on right

Evening all!

I’m nearing the end of my doodle-jump style game (1st unity project!) and have come across what I hope is the final hurdle.

Currently I have a spaceship which moves left to right along the X axis when you tilt the phone, the ship goes off screen and continues on forever unless you tilt back in the opposite direction.

I would like the ship to re-appear on the opposite side of the screen when it falls off the edge, a bit like Asteroids…to complicate things further I’d need to allow for varying screen resolutions and maybe use a percentage of the screen width, is this possible? if so, how?

Here is my movement script…

void Update() {
	rigidbody.velocity = new Vector3(0, 0, 0);
    rigidbody.AddForce(new Vector3(0, 8000, 0), ForceMode.Force);

// rigidbody.velocity = new Vector3(0, rigidbody.velocity.y, 0);

    transform.Translate(Input.GetAxis("Horizontal") * Time.deltaTime * speed, 0, 0); //pc controls (arrows)

    Vector3 dir = Vector3.zero;  //Android controls - accelorometer
    dir.x = -Input.acceleration.y;
    dir.y = 0;
	dir.z = 0;
    if (dir.sqrMagnitude > 1)
        dir.Normalize();
    
    dir *= Time.deltaTime;
    transform.Translate(dir * speed);
}

EDIT :

To use Camera.main.ScreenToWorldPoint, pass a Vector3 and specify a screen-pixel for X and Y, for Z you need to specify the distance between the camera and the spaceship. e.g. if the camera Z is -10 , and the ship Z is 0, then the distance is 10. so the command should read : leftConstraint = Camera.main.ScreenToWorldPoint(new Vector3(0.0f, 0.0f, 10.0f)).x;

Here’s a working C# script :

using UnityEngine;
using System.Collections;

public class Screen_Bounds : MonoBehaviour 
{
 public float leftConstraint = 0.0f;
 public float rightConstraint = 0.0f;
 public float buffer = 1.0f; // set this so the spaceship disappears offscreen before re-appearing on other side
 public float distanceZ = 10.0f;

 void Awake() 
 {
     // set Vector3 to ( camera left/right limits, spaceship Y, spaceship Z )
     // this will find a world-space point that is relative to the screen

     // using the camera's position from the origin (world-space Vector3(0,0,0)
     //leftConstraint = Camera.main.ScreenToWorldPoint( new Vector3(0.0f, 0.0f, 0 - Camera.main.transform.position.z) ).x;
     //rightConstraint = Camera.main.ScreenToWorldPoint( new Vector3(Screen.width, 0.0f, 0 - Camera.main.transform.position.z) ).x;
 
     // using a specific distance
     leftConstraint = Camera.main.ScreenToWorldPoint( new Vector3(0.0f, 0.0f, distanceZ) ).x;
     rightConstraint = Camera.main.ScreenToWorldPoint( new Vector3(Screen.width, 0.0f, distanceZ) ).x;
 }

 void Update() 
 {
 /*
     if (shipX < leftConstraint - buffer) { // ship is past world-space view / off screen
        shipX = rightConstraint + buffer;  // move ship to opposite side
     }

     if (shipX > rightConstraint + buffer) {
        shipX = leftConstraint - buffer;
     }
     */
 }
}

Original Answer :

You can find a position in world-space that the spaceship moves off screen, then move the spaceship to a position on the other side that is off-screen. Use Camera.main.ScreenToWorldPoint

http://docs.unity3d.com/Documentation/ScriptReference/Camera.ScreenToWorldPoint.html

Here is a JS example (just saw it was C#, have added below). Also consider the Update functions as psuedoCode =]

 var leftConstraint : float = 0.0;
 var rightConstraint : float = 960.0;
 var buffer : float = 1.0; // set this so the spaceship disappears offscreen before re-appearing on other side

 function Start() 
 {
     // set Vector3 to ( camera left/right limits, spaceship Y, spaceship Z )
     // this will find a world-space point that is relative to the screen
     leftConstraint = Camera.main.ScreenToWorldPoint(Vector3(Screen.width * 0.0, 0.0, 0.0)).x;
     rightConstraint = Camera.main.ScreenToWorldPoint(Vector3(Screen.width * 1.0, 0.0, 0.0)).x;
 }

 function Update() 
 {
     if (shipX < leftConstraint - buffer) { // ship is past world-space view / off screen
         shipX = rightConstraint + buffer;  // move ship to opposite side
     }
 
     if (shipX > rightConstraint + buffer) {
         shipX = leftConstraint - buffer;
     }
 }

Converted : C# is not my native language, but try :

 float leftConstraint = 0.0f;
 float rightConstraint = 960.0f;
 float buffer = 1.0f; // set this so the spaceship disappears offscreen before re-appearing on other side

 void Start() 
 {
     // set Vector3 to ( camera left/right limits, spaceship Y, spaceship Z )
     // this will find a world-space point that is relative to the screen
     leftConstraint = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width * 0.05f,0.0f,0.0f)).x; // Or set to (0,0,0)
     rightConstraint = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width * 0.95f,0.0f,0.0f)).x; // Or set to (Screen.width,0,0)
 }

 void Update() 
 {
     if (shipX < leftConstraint - buffer) { // ship is past world-space view / off screen
         shipX = rightConstraint + buffer;  // move ship to opposite side
     }
 
     if (shipX > rightConstraint + buffer) {
         shipX = leftConstraint - buffer;
     }
 }

Use a Raycast and shoot it at your object. If it misses, your object flew off the screen and you should calculate which side it flew off of (probably by calculating where it is relative to the central coordinate your camera is looking at).

Ok, so I’ve played about with various things including Jay Kay’s solution which looked good but something wasnt quite right.

I’ve simplified it now and it works well except it won’t scale on screen size…

if( transform.position.x < -12 ) transform.position = new Vector3(12,transform.position.y, transform.position.z);
else if( transform.position.x > 12 ) transform.position = new Vector3(-12,transform.position.y, transform.position.z);

//Scales to screen

using UnityEngine;
using System.Collections;

public class TransportObjectOnScreenExit : MonoBehaviour {
    float leftConstraint = Screen.width;
    float rightConstraint = Screen.width;
    float bottomConstraint = Screen.height;
    float topConstraint = Screen.height;
    float buffer = 1.0f;
    Camera cam;
    float distanceZ;

    void Start() {
        cam = Camera.main;
        distanceZ = Mathf.Abs(cam.transform.position.z + transform.position.z);

        leftConstraint = cam.ScreenToWorldPoint(new Vector3(0.0f, 0.0f, distanceZ)).x;
        rightConstraint = cam.ScreenToWorldPoint(new Vector3(Screen.width, 0.0f, distanceZ)).x;
        bottomConstraint = cam.ScreenToWorldPoint(new Vector3(0.0f, 0.0f, distanceZ)).y;
        topConstraint = cam.ScreenToWorldPoint(new Vector3(0.0f, Screen.height, distanceZ)).y;
    }

    void FixedUpdate() {
        if (transform.position.x < leftConstraint - buffer) {
            transform.position = new Vector3(rightConstraint + buffer, transform.position.y, transform.position.z);
        }
        if (transform.position.x > rightConstraint + buffer) {
            transform.position = new Vector3(leftConstraint - buffer, transform.position.y, transform.position.z);
        }
        if (transform.position.y < bottomConstraint - buffer) {
            transform.position = new Vector3(transform.position.x, topConstraint + buffer, transform.position.z);
        }
        if (transform.position.y > topConstraint + buffer) {
            transform.position = new Vector3(transform.position.x, bottomConstraint - buffer, transform.position.z);
        }
    }
}