Search Unity

Collision with sides of screen?

Discussion in '2D' started by maxiedaniels, Feb 17, 2014.

  1. maxiedaniels

    maxiedaniels

    Joined:
    Nov 25, 2013
    Posts:
    12
    I'm trying to make a very simple test - a ball that bounces around, off the edges of the screen. I get using BoxCollider2D's, but would I use code to create BoxCollider2D's that are located just outside the screen?? Or is there a more efficient way to do this kind of thing? I imagine this is a common thing to need in a game... the trick is obviously needing the collision areas to move based on the resolution/aspect ratio.
     
  2. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,549
    Well, it's not that common of a need, usually people just eyeball it I think, but if you want to adjust for aspect ratio, then here's some code I just wrote up that does the trick:
    Code (csharp):
    1.  
    2.     public float colDepth = 4f;
    3.     public float zPosition = 0f;
    4.     private Vector2 screenSize;
    5.     private Transform topCollider;
    6.     private Transform bottomCollider;
    7.     private Transform leftCollider;
    8.     private Transform rightCollider;
    9.     private Vector3 cameraPos;
    10.     // Use this for initialization
    11.     void Start () {
    12.     //Generate our empty objects
    13.         topCollider = new GameObject().transform;
    14.         bottomCollider = new GameObject().transform;
    15.         rightCollider = new GameObject().transform;
    16.         leftCollider = new GameObject().transform;
    17.  
    18.     //Name our objects 
    19.         topCollider.name = "TopCollider";
    20.         bottomCollider.name = "BottomCollider";
    21.         rightCollider.name = "RightCollider";
    22.         leftCollider.name = "LeftCollider";
    23.        
    24.     //Add the colliders
    25.         topCollider.gameObject.AddComponent<BoxCollider2D>();
    26.         bottomCollider.gameObject.AddComponent<BoxCollider2D>();
    27.         rightCollider.gameObject.AddComponent<BoxCollider2D>();
    28.         leftCollider.gameObject.AddComponent<BoxCollider2D>();
    29.        
    30.     //Make them the child of whatever object this script is on, preferably on the Camera so the objects move with the camera without extra scripting
    31.         topCollider.parent = transform;
    32.         bottomCollider.parent = transform;
    33.         rightCollider.parent = transform;
    34.         leftCollider.parent = transform;
    35.            
    36.     //Generate world space point information for position and scale calculations
    37.         cameraPos = Camera.main.transform.position;
    38.         screenSize.x = Vector2.Distance (Camera.main.ScreenToWorldPoint(new Vector2(0,0)),Camera.main.ScreenToWorldPoint(new Vector2(Screen.width, 0))) * 0.5f;
    39.         screenSize.y = Vector2.Distance (Camera.main.ScreenToWorldPoint(new Vector2(0,0)),Camera.main.ScreenToWorldPoint(new Vector2(0, Screen.height))) * 0.5f;
    40.        
    41.     //Change our scale and positions to match the edges of the screen...   
    42.         rightCollider.localScale = new Vector3(colDepth, screenSize.y * 2, colDepth);
    43.         rightCollider.position = new Vector3(cameraPos.x + screenSize.x + (rightCollider.localScale.x * 0.5f), cameraPos.y, zPosition);
    44.         leftCollider.localScale = new Vector3(colDepth, screenSize.y * 2, colDepth);
    45.         leftCollider.position = new Vector3(cameraPos.x - screenSize.x - (leftCollider.localScale.x * 0.5f), cameraPos.y, zPosition);
    46.         topCollider.localScale = new Vector3(screenSize.x * 2, colDepth, colDepth);
    47.         topCollider.position = new Vector3(cameraPos.x, cameraPos.y + screenSize.y + (topCollider.localScale.y * 0.5f), zPosition);
    48.         bottomCollider.localScale = new Vector3(screenSize.x * 2, colDepth, colDepth);
    49.         bottomCollider.position = new Vector3(cameraPos.x, cameraPos.y - screenSize.y - (bottomCollider.localScale.y * 0.5f), zPosition);
    50.     }
    This script can be used for 3D colliders as well, just remove the "2D" part on those four BoxCollider component lines.
     
    Last edited: Feb 17, 2014
  3. maxiedaniels

    maxiedaniels

    Joined:
    Nov 25, 2013
    Posts:
    12
    Wow thanks so much man!! Much appreciated!
     
  4. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,549
    I actually took some time tonight to learn more about Dictionaries since this was a good enough time as any... Managed to shorten/simplify the code a fair bit! Dictionaries are pretty neat.
    Code (csharp):
    1.  
    2.     public float colThickness = 4f;
    3.     public float zPosition = 0f;
    4.     private Vector2 screenSize;
    5.  
    6.     void Start ()
    7.     {//Create a Dictionary to contain all our Objects/Transforms
    8.         System.Collections.Generic.Dictionary<string,Transform> colliders = new System.Collections.Generic.Dictionary<string,Transform>();
    9.     //Create our GameObjects and add their Transform components to the Dictionary we created above
    10.         colliders.Add("Top",new GameObject().transform);
    11.         colliders.Add("Bottom",new GameObject().transform);
    12.         colliders.Add("Right",new GameObject().transform);
    13.         colliders.Add("Left",new GameObject().transform);
    14.     //Generate world space point information for position and scale calculations
    15.         Vector3 cameraPos = Camera.main.transform.position;
    16.         screenSize.x = Vector2.Distance (Camera.main.ScreenToWorldPoint(new Vector2(0,0)),Camera.main.ScreenToWorldPoint(new Vector2(Screen.width, 0))) * 0.5f; //Grab the world-space position values of the start and end positions of the screen, then calculate the distance between them and store it as half, since we only need half that value for distance away from the camera to the edge
    17.         screenSize.y = Vector2.Distance (Camera.main.ScreenToWorldPoint(new Vector2(0,0)),Camera.main.ScreenToWorldPoint(new Vector2(0, Screen.height))) * 0.5f;
    18.     //For each Transform/Object in our Dictionary
    19.         foreach(KeyValuePair<string,Transform> valPair in colliders)
    20.         {
    21.             valPair.Value.gameObject.AddComponent<BoxCollider2D>(); //Add our colliders. Remove the "2D", if you would like 3D colliders.
    22.             valPair.Value.name = valPair.Key + "Collider"; //Set the object's name to it's "Key" name, and take on "Collider".  i.e: TopCollider
    23.             valPair.Value.parent = transform; //Make the object a child of whatever object this script is on (preferably the camera)
    24.  
    25.             if(valPair.Key == "Left" || valPair.Key == "Right") //Scale the object to the width and height of the screen, using the world-space values calculated earlier
    26.                 valPair.Value.localScale = new Vector3(colThickness, screenSize.y * 2, colThickness);
    27.             else
    28.                 valPair.Value.localScale = new Vector3(screenSize.x * 2, colThickness, colThickness);
    29.         }  
    30.     //Change positions to align perfectly with outter-edge of screen, adding the world-space values of the screen we generated earlier, and adding/subtracting them with the current camera position, as well as add/subtracting half out objects size so it's not just half way off-screen
    31.         colliders["Right"].position = new Vector3(cameraPos.x + screenSize.x + (colliders["Right"].localScale.x * 0.5f), cameraPos.y, zPosition);
    32.         colliders["Left"].position = new Vector3(cameraPos.x - screenSize.x - (colliders["Left"].localScale.x * 0.5f), cameraPos.y, zPosition);
    33.         colliders["Top"].position = new Vector3(cameraPos.x, cameraPos.y + screenSize.y + (colliders["Top"].localScale.y * 0.5f), zPosition);
    34.         colliders["Bottom"].position = new Vector3(cameraPos.x, cameraPos.y - screenSize.y - (colliders["Bottom"].localScale.y * 0.5f), zPosition);
    35.     }
    36.  
     
  5. vocweb

    vocweb

    Joined:
    Jul 15, 2016
    Posts:
    1
    Many thank
     
  6. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,408
    Last edited: Nov 25, 2018
    mrwellman_work and AyanRoy like this.
  7. Khawar-Munir

    Khawar-Munir

    Joined:
    Mar 1, 2015
    Posts:
    1
    Great script. Thanks man :)
     
  8. shavez94

    shavez94

    Joined:
    Apr 17, 2018
    Posts:
    3
    love it!
     
  9. amitm

    amitm

    Joined:
    Jul 16, 2014
    Posts:
    2
    This function will generate colliders on the sides of the screen:
    Code (CSharp):
    1.     void GenerateCollidersAcrossScreen()
    2.     {
    3.         Vector2 lDCorner = camera.ViewportToWorldPoint(new Vector3(0, 0f, camera.nearClipPlane));
    4.         Vector2 rUCorner = camera.ViewportToWorldPoint(new Vector3(1f, 1f, camera.nearClipPlane));
    5.         Vector2[] colliderpoints;
    6.  
    7.         EdgeCollider2D upperEdge = new GameObject("upperEdge").AddComponent<EdgeCollider2D>();
    8.         colliderpoints = upperEdge.points;
    9.         colliderpoints[0] = new Vector2(lDCorner.x, rUCorner.y);
    10.         colliderpoints[1] = new Vector2(rUCorner.x, rUCorner.y);
    11.         upperEdge.points = colliderpoints;
    12.  
    13.         EdgeCollider2D lowerEdge = new GameObject("lowerEdge").AddComponent<EdgeCollider2D>();
    14.         colliderpoints = lowerEdge.points;
    15.         colliderpoints[0] = new Vector2(lDCorner.x, lDCorner.y);
    16.         colliderpoints[1] = new Vector2(rUCorner.x, lDCorner.y);
    17.         lowerEdge.points = colliderpoints;
    18.  
    19.         EdgeCollider2D leftEdge = new GameObject("leftEdge").AddComponent<EdgeCollider2D>();
    20.         colliderpoints = leftEdge.points;
    21.         colliderpoints[0] = new Vector2(lDCorner.x, lDCorner.y);
    22.         colliderpoints[1] = new Vector2(lDCorner.x, rUCorner.y);
    23.         leftEdge.points = colliderpoints;
    24.  
    25.         EdgeCollider2D rightEdge = new GameObject("rightEdge").AddComponent<EdgeCollider2D>();
    26.  
    27.         colliderpoints = rightEdge.points;
    28.         colliderpoints[0] = new Vector2(rUCorner.x, rUCorner.y);
    29.         colliderpoints[1] = new Vector2(rUCorner.x, lDCorner.y);
    30.         rightEdge.points = colliderpoints;
    31.     }
     
    kapr-cz and path14 like this.
  10. doguceremey

    doguceremey

    Joined:
    Jul 7, 2020
    Posts:
    1

    Dude, that saved my day. Thank you so much.
     
  11. Avivyouker

    Avivyouker

    Joined:
    Aug 5, 2020
    Posts:
    14
    Worked for me! Thank you!
     
  12. spajdyy

    spajdyy

    Joined:
    May 28, 2021
    Posts:
    1
    Hi there, I got errors there as I wanted to do this, I am really a beginner, a dumb one, so I've trouble figuring it out. There is same error for four lines:
    A namespace cannot directly contain members such as fields or methods

    this goes for Line 5 column 14, Line 6 column 14, Line 7 column 17, Line 9 column 10.

    I really don't want my player to go out of bounds here and I want it to be able to adapt to aspect ratio.