Search Unity

How to wrap character from one edge of the screen to other

Discussion in 'Scripting' started by Guru, Jun 14, 2010.

  1. Guru

    Guru

    Joined:
    Apr 30, 2010
    Posts:
    118
    I have seen quite a few posts, one in particular that I can't find right now and why I am posting it here, have asked how to wrap movement from one side of the screen to another...

    well I am sure this is known by some but say the extents of your screen on the x-axis is 9.0 and -9.0 in a simple 2D, Asteroids type game. All you need to do is something like:

    Code (csharp):
    1.  
    2. if(transform.position.x < -9.0 || transform.position.x > 9.0) {
    3.   var xPos : float = Mathf.Clamp(transform.position.x, 9.0, -9.0);
    4.   transform.position = Vector3(xPos, transform.position.y, transform.position.z);
    5. }
    6.  
    7.  
    8.  
    9.  
    In the process of making a Breakout clone and accidentally switched the positive and negative numbers in the Clamp function and it gave me instant wrapping.

    Hopefully the guy who was making the Asteroids game will see this as I can't seem to find the post right now.
     
  2. Eyeofgod

    Eyeofgod

    Joined:
    Jun 25, 2010
    Posts:
    126
    Thx! I havent post the original thread but this has help me. But, one thing, anyone knows how to make the screen warp smoother so the object starts going out form one side of the screen an starts appearing in the other side (so you have half of the object visible in one side and half in the other).

    Thx!
     
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,002
    @Eyeofgod:
    That's tricky and can only be done when you have your object/character two times an the scene.
    My approach would be to have your object 2 times in your scene seperated by the whole screensize.
    That way you can see the object on both sides when it enters or leaves the screen.
    I would do something like:
    Code (csharp):
    1.  
    2. // The actual player
    3.     void Update()
    4.     {
    5.         // NOTE: this works only if the cam center is at 0,0
    6.         Vector3 pos = transform.position;
    7.  
    8.         //*** apply your movement here ***
    9.         // change pos as you want
    10.        
    11.         // this is the half size of the screen (so it goes from -9.0f to 9.0f)
    12.         float HalfScreenSize = 9.0f;
    13.                
    14.         // wrap check
    15.         pos.x = Mathf.Repeat(pos.x+HalfScreenSize,HalfScreenSize*2)-HalfScreenSize;
    16.  
    17.         transform.position = pos;
    18.     }
    19.  
    20.  
    and on the second instance this:
    Code (csharp):
    1.  
    2.     public Transform OriginalObject;
    3.  
    4.     void LateUpdate()
    5.     {
    6.         // NOTE: this works only if the cam center is at 0,0
    7.         // this is the half size of the screen (so it goes from -9.0f to 9.0f)
    8.         float HalfScreenSize = 9.0f;
    9.  
    10.         // Get the actual position of the original
    11.         Vector3 pos = OriginalObject.position;
    12.  
    13.         // Add the screen size
    14.         pos.x += HalfScreenSize*2;
    15.  
    16.         // wrap around if necessary
    17.         if (pos.x > HalfScreenSize*2)
    18.             pos.x -= HalfScreenSize*4;
    19.  
    20.         transform.position = pos;
    21.     }
    22.  
    Notice the LastUpdate function! otherwise the second instance would be 1 frame to late.
    It looks quite complicated but that's because the cam center is in the middle.
    It would be much easier to have 0 on the left side.


    That's the case when your scene origin is on the left side of the screen
    Code (csharp):
    1.  
    2. // The actual player
    3.    void Update()
    4.     {
    5.         Vector3 pos = transform.position;
    6.  
    7.         //*** apply your movement here ***
    8.         // change pos as you want you want
    9.        
    10.         // this is the half size of the screen (so it goes from 0.0f to 18.0f)
    11.         float HalfScreenSize = 9.0f;
    12.                
    13.         pos.x = Mathf.Repeat(pos.x ,HalfScreenSize*2);
    14.  
    15.         transform.position = pos;
    16.     }
    17.  
    Code (csharp):
    1.  
    2.     public Transform OriginalObject;
    3.  
    4.     void LateUpdate()
    5.     {
    6.         // this is the half size of the screen (so it goes from 0.0f to 18.0f)
    7.         float HalfScreenSize = 9.0f;
    8.  
    9.         Vector3 pos = OriginalObject.position;
    10.  
    11.         pos.x += HalfScreenSize*2;
    12.  
    13.         // here we need now 3 because everything is shifted to the left
    14.         if (pos.x > HalfScreenSize*3)
    15.             pos.x -= HalfScreenSize*4;
    16.  
    17.         transform.position = pos;
    18.     }
    19.  
    ps. that's C# - code ... sorry but i don't like to use "dirty"-languages ;)
     
    Last edited: Dec 24, 2010
  4. neverlash

    neverlash

    Joined:
    Sep 26, 2017
    Posts:
    1
    Thanks so much, it was exactly what I needed :) .
     
  5. hahahpizza

    hahahpizza

    Joined:
    Sep 9, 2015
    Posts:
    11
    @Bunny83, as you said, "the actual "size" of the screen in world units depends on your orthographic size of your camera and the aspect ratio." How can we make the object wrapping ortho size and aspect ratio independent so that it can work for any screen size?
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,002
    Well, just replace

    Code (CSharp):
    1. float HalfScreenSize = 9.0f;
    with something like:

    Code (CSharp):
    1. float HalfScreenSize = yourCam.aspect * yourCam.orthographicSize;
    It should be obvious that "yourCam" should be your orthographic camera that you're using. If you only have one camera you can just use
    Camera.main
     
    hahahpizza likes this.
  7. sn3akr

    sn3akr

    Joined:
    Mar 6, 2024
    Posts:
    1
    i've implemented the second method here into my program (scene origin on left) with the player and another duplicate player, i'm facing an issue where when the player is on the first left half of the screen it's actually displaying the duplicate entity, which doesn't properly collide with other objects on the screen. any way to fix this so it's always the real player on the screen?