Home / Forums / Writing 2D Bounding Box ESP in Unity C# with Camera.WorldToScreenPoint

UnreliableCode Community

Developer Research, Reverse Engineering & Coding Community

Tutorial

Writing 2D Bounding Box ESP in Unity C# with Camera.WorldToScreenPoint

RustMechanic
Unity & IL2CPP Reverser
VIP
Rep: 295
Join Date: Nov 2022
Posts: 32
Thanks: 74
3y ago · Jul 10, 2023 2:30 PM
#1
In Unity games, projecting 3D entity positions onto the 2D screen coordinate space is simplified using
CSHARP
Camera.main.WorldToScreenPoint()
.

How to calculate a dynamic 2D bounding box:
CSHARP
using UnityEngine;

public static class ESPUtils
{
    private static Texture2D _whiteTexture;
    public static Texture2D WhiteTexture
    {
        get
        {
            if (_whiteTexture == null)
            {
                _whiteTexture = new Texture2D(1, 1);
                _whiteTexture.SetPixel(0, 0, Color.white);
                _whiteTexture.Apply();
            }
            return _whiteTexture;
        }
    }

    public static void DrawBox(float x, float y, float width, float height, float thickness, Color color)
    {
        GUI.color = color;
        // Top & Bottom
        GUI.DrawTexture(new Rect(x, y, width, thickness), WhiteTexture);
        GUI.DrawTexture(new Rect(x, y + height - thickness, width, thickness), WhiteTexture);
        // Left & Right
        GUI.DrawTexture(new Rect(x, y, thickness, height), WhiteTexture);
        GUI.DrawTexture(new Rect(x + width - thickness, y, thickness, height), WhiteTexture);
    }

    public static void Draw2DBoxESP(Vector3 feetPos, Vector3 headPos, Color boxColor)
    {
        Camera cam = Camera.main;
        if (cam == null) return;

        Vector3 screenFeet = cam.WorldToScreenPoint(feetPos);
        Vector3 screenHead = cam.WorldToScreenPoint(headPos);

        // Check if entity is behind the camera
        if (screenFeet.z <= 0.01f || screenHead.z <= 0.01f) return;

        // Invert Y coordinate for Unity OnGUI (screen space top-left is 0,0)
        float feetY = Screen.height - screenFeet.y;
        float headY = Screen.height - screenHead.y;
        float height = feetY - headY;
        float width = height * 0.55f; // Standard human aspect ratio
        float x = screenFeet.x - (width * 0.5f);

        DrawBox(x, headY, width, height, 1.5f, boxColor);
    }
}
RustMechanic | IL2CPP & Unity Engine Analysis
The following users thanked RustMechanic for this post:
MatrixRecon
3D Math & Vectors
MEMBER
Rep: 225
Join Date: Jan 2025
Posts: 33
Thanks: 55
3y ago · Jul 10, 2023 4:15 PM
#2
The
CSHARP
Screen.height - screenPos.y
inversion is essential because Unity's world-to-screen matrix returns coordinates where (0,0) is bottom-left, while
CODE
OnGUI
starts at the top-left.
MatrixRecon · 3D Mathematics & View Matrix Calculations
ZeroMemory
Member
MEMBER
Rep: 75
Join Date: Oct 2024
Posts: 32
Thanks: 18
3y ago · Jul 11, 2023 9:20 AM
#3
Works like a charm in BepInEx! The 0.55f aspect ratio keeps the box scaling naturally with distance.
ZeroMemory · Always experimenting