Making Unity Colliders follow the screensize

I was recently looking for a way to make sure that my colliders would stay right at the edge of the screen, no matter what dimensions the screen were. This is rather important, if you want your colliders follow the screen, no matter what phone you are using or what format you end up using. I was starting to figure out a solution for myself, but then decided to quickly google it. I came across this post , so all credits for this solution goes to Invertex . Only thing that I added to the script was the ability to add a PhysicsMaterial2D to the colliders if that is a requirement.

As you can see on this image, the colliders will form a nice square right around the edge of the screen. Here the screen is represented by the “slightly” thicker green line. 

Using script

The script will make sure that at the start of the game, the colliders will be created, and will be set at the size of the screen. If you change the screen from landscape to portrait, the colliders will not follow. If you need to make the colliders change when the screen changes format, you should look at detecting this change, and then update the size and scale once it has turned. If you need an explanation on how to do this, please ask me to update on my facebook page

The way to use the script is to simply create a new gameobject in the scene and attach the script to it – the moment the game starts, there will be created 4 new child gameobjects that each have a collider with a name and follows the screen.

The Script

Create a script that is called “CreateScreenColliders” and paste this code into it.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CreateScreenColliders : MonoBehaviour {
    
    public float colThickness = 2f;
    public float zPosition = 0f;
    private Vector2 screenSize;

    //If you need a 3D version, just remove 2D from the PhysicsMaterial2D.
    public PhysicsMaterial2D physicsMaterial;

    void Start()
    {
        //Create a Dictionary to contain all our Objects/Transforms
        System.Collections.Generic.Dictionary<string, Transform> colliders = new System.Collections.Generic.Dictionary<string, Transform>();

        //Create our GameObjects and add their Transform components to the Dictionary we created above
        colliders.Add("Top", new GameObject().transform);
        colliders.Add("Bottom", new GameObject().transform);
        colliders.Add("Right", new GameObject().transform);
        colliders.Add("Left", new GameObject().transform);

        //Generate world space point information for position and scale calculations
        Vector3 cameraPos = Camera.main.transform.position;

        //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
        screenSize.x = Vector2.Distance(Camera.main.ScreenToWorldPoint(new Vector2(0, 0)), Camera.main.ScreenToWorldPoint(new Vector2(Screen.width, 0))) * 0.5f; 
        screenSize.y = Vector2.Distance(Camera.main.ScreenToWorldPoint(new Vector2(0, 0)), Camera.main.ScreenToWorldPoint(new Vector2(0, Screen.height))) * 0.5f;

        //For each Transform/Object in our Dictionary
        foreach (KeyValuePair<string, Transform> valPair in colliders)
        {
            //Add our colliders. Remove the "2D", if you would like 3D colliders.
            valPair.Value.gameObject.AddComponent<BoxCollider2D>(); 

            //Set the object's name to it's "Key" name, and take on "Collider".  i.e: TopCollider
            valPair.Value.name = valPair.Key + "Collider"; 

            //Make the object a child of whatever object this script is on (preferably the camera)
            valPair.Value.parent = transform; 

            //Scale the object to the width and height of the screen, using the world-space values calculated earlier
            if (valPair.Key == "Left" || valPair.Key == "Right") 
                valPair.Value.localScale = new Vector3(colThickness, screenSize.y * 2, colThickness);
            else
                valPair.Value.localScale = new Vector3(screenSize.x * 2, colThickness, colThickness);

            //We add the Physicsmaterial to the collider here if there is any
            //Remove the 2D from BoxCollider2D if you are working with 3D
            if(physicsMaterial){
                valPair.Value.gameObject.GetComponent<BoxCollider2D>().sharedMaterial = physicsMaterial;
            }
        }

        //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
        colliders["Right"].position = new Vector3(cameraPos.x + screenSize.x + (colliders["Right"].localScale.x * 0.5f), cameraPos.y, zPosition);
        colliders["Left"].position = new Vector3(cameraPos.x - screenSize.x - (colliders["Left"].localScale.x * 0.5f), cameraPos.y, zPosition);
        colliders["Top"].position = new Vector3(cameraPos.x, cameraPos.y + screenSize.y + (colliders["Top"].localScale.y * 0.5f), zPosition);
        colliders["Bottom"].position = new Vector3(cameraPos.x, cameraPos.y - screenSize.y - (colliders["Bottom"].localScale.y * 0.5f), zPosition);
    }
}

Have fun, and remember to reach out if you have any questions.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.