You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中如何获取GameObject相对于屏幕的起止坐标?

How to Get a GameObject's Screen Space Bounds (Start/End X,Y) in Unity

Great question! To get a GameObject's screen-space start (min X,Y) and end (max X,Y) coordinates, you need to convert its world-space bounding box to screen space using your main camera. Here's a step-by-step breakdown with code examples for both C# and UnityScript (JavaScript), plus handling for UI elements:

Core Idea

Every visible GameObject has a Renderer component (like MeshRenderer or SkinnedMeshRenderer) that defines its world-space bounds. We can grab these bounds, convert all 8 corners of the bounding box to screen coordinates, then find the minimum and maximum X/Y values—those are your start and end points.

C# Implementation

Attach this script to any GameObject, assign your target object, and it’ll log the screen bounds every frame:

using UnityEngine;

public class ScreenBoundsCalculator : MonoBehaviour
{
    public GameObject targetObject; // Assign your target in the Inspector
    private Camera mainCamera;

    void Start()
    {
        mainCamera = Camera.main;
        // Default to the script's own GameObject if no target is set
        if (targetObject == null) targetObject = gameObject;
    }

    void Update()
    {
        GetScreenBounds(targetObject, out Vector2 screenStart, out Vector2 screenEnd);
        Debug.Log($"Screen Start: ({screenStart.x:F2}, {screenStart.y:F2}), Screen End: ({screenEnd.x:F2}, {screenEnd.y:F2})");
    }

    void GetScreenBounds(GameObject obj, out Vector2 screenStart, out Vector2 screenEnd)
    {
        Renderer objectRenderer = obj.GetComponent<Renderer>();
        if (objectRenderer == null)
        {
            Debug.LogError("Target GameObject has no Renderer component! Add one (e.g., MeshRenderer) first.");
            screenStart = Vector2.zero;
            screenEnd = Vector2.zero;
            return;
        }

        // Get the world-space bounding box of the object
        Bounds worldBounds = objectRenderer.bounds;
        Vector3[] worldCorners = new Vector3[8];
        
        // Populate all 8 corners of the bounding box
        worldCorners[0] = worldBounds.min;
        worldCorners[1] = new Vector3(worldBounds.min.x, worldBounds.min.y, worldBounds.max.z);
        worldCorners[2] = new Vector3(worldBounds.max.x, worldBounds.min.y, worldBounds.max.z);
        worldCorners[3] = new Vector3(worldBounds.max.x, worldBounds.min.y, worldBounds.min.z);
        worldCorners[4] = worldBounds.max;
        worldCorners[5] = new Vector3(worldBounds.min.x, worldBounds.max.y, worldBounds.max.z);
        worldCorners[6] = new Vector3(worldBounds.min.x, worldBounds.max.y, worldBounds.min.z);
        worldCorners[7] = new Vector3(worldBounds.max.x, worldBounds.max.y, worldBounds.min.z);

        // Convert first corner to screen space to initialize our min/max values
        Vector3 firstScreenPoint = mainCamera.WorldToScreenPoint(worldCorners[0]);
        float minX = firstScreenPoint.x;
        float maxX = firstScreenPoint.x;
        float minY = firstScreenPoint.y;
        float maxY = firstScreenPoint.y;

        // Iterate through all corners to find the true min/max screen coordinates
        foreach (Vector3 corner in worldCorners)
        {
            Vector3 screenPoint = mainCamera.WorldToScreenPoint(corner);
            minX = Mathf.Min(minX, screenPoint.x);
            maxX = Mathf.Max(maxX, screenPoint.x);
            minY = Mathf.Min(minY, screenPoint.y);
            maxY = Mathf.Max(maxY, screenPoint.y);
        }

        // Assign the final start (min) and end (max) points
        screenStart = new Vector2(minX, minY);
        screenEnd = new Vector2(maxX, maxY);
    }
}

UnityScript (JavaScript) Implementation

If you’re still using UnityScript, here’s the equivalent code:

#pragma strict

var targetObject : GameObject; // Assign your target in the Inspector
private var mainCamera : Camera;

function Start()
{
    mainCamera = Camera.main;
    // Default to the script's own GameObject if no target is set
    if (targetObject == null) targetObject = gameObject;
}

function Update()
{
    var screenStart : Vector2;
    var screenEnd : Vector2;
    GetScreenBounds(targetObject, screenStart, screenEnd);
    Debug.Log("Screen Start: (" + screenStart.x.toFixed(2) + ", " + screenStart.y.toFixed(2) + "), Screen End: (" + screenEnd.x.toFixed(2) + ", " + screenEnd.y.toFixed(2) + ")");
}

function GetScreenBounds(obj : GameObject, out screenStart : Vector2, out screenEnd : Vector2)
{
    var objectRenderer : Renderer = obj.GetComponent.<Renderer>();
    if (objectRenderer == null)
    {
        Debug.LogError("Target GameObject has no Renderer component! Add one (e.g., MeshRenderer) first.");
        screenStart = Vector2.zero;
        screenEnd = Vector2.zero;
        return;
    }

    // Get the world-space bounding box of the object
    var worldBounds : Bounds = objectRenderer.bounds;
    var worldCorners : Vector3[] = new Vector3[8];
    
    // Populate all 8 corners of the bounding box
    worldCorners[0] = worldBounds.min;
    worldCorners[1] = Vector3(worldBounds.min.x, worldBounds.min.y, worldBounds.max.z);
    worldCorners[2] = Vector3(worldBounds.max.x, worldBounds.min.y, worldBounds.max.z);
    worldCorners[3] = Vector3(worldBounds.max.x, worldBounds.min.y, worldBounds.min.z);
    worldCorners[4] = worldBounds.max;
    worldCorners[5] = Vector3(worldBounds.min.x, worldBounds.max.y, worldBounds.max.z);
    worldCorners[6] = Vector3(worldBounds.min.x, worldBounds.max.y, worldBounds.min.z);
    worldCorners[7] = Vector3(worldBounds.max.x, worldBounds.max.y, worldBounds.min.z);

    // Convert first corner to screen space to initialize our min/max values
    var firstScreenPoint : Vector3 = mainCamera.WorldToScreenPoint(worldCorners[0]);
    var minX : float = firstScreenPoint.x;
    var maxX : float = firstScreenPoint.x;
    var minY : float = firstScreenPoint.y;
    var maxY : float = firstScreenPoint.y;

    // Iterate through all corners to find the true min/max screen coordinates
    for (var corner : Vector3 in worldCorners)
    {
        var screenPoint : Vector3 = mainCamera.WorldToScreenPoint(corner);
        minX = Mathf.Min(minX, screenPoint.x);
        maxX = Mathf.Max(maxX, screenPoint.x);
        minY = Mathf.Min(minY, screenPoint.y);
        maxY = Mathf.Max(maxY, screenPoint.y);
    }

    // Assign the final start (min) and end (max) points
    screenStart = Vector2(minX, minY);
    screenEnd = Vector2(maxX, maxY);
}

Notes & Edge Cases

  • UI Elements: For objects in a Canvas (like Images or Text), use RectTransform instead of Renderer. Here’s a quick C# snippet for UI:
    using UnityEngine;
    using UnityEngine.UI;
    
    public class UIScreenBoundsCalculator : MonoBehaviour
    {
        public RectTransform uiElement;
    
        void Update()
        {
            // Convert UI element's local bounds to screen space
            Vector2 screenMin = RectTransformUtility.WorldToScreenPoint(Camera.main, uiElement.position - uiElement.rect.size / 2);
            Vector2 screenMax = RectTransformUtility.WorldToScreenPoint(Camera.main, uiElement.position + uiElement.rect.size / 2);
            Debug.Log($"UI Screen Start: ({screenMin.x:F2}, {screenMin.y:F2}), UI Screen End: ({screenMax.x:F2}, {screenMax.y:F2})");
        }
    }
    
  • Screen Coordinate Origin: Unity’s screen coordinates start at the bottom-left corner (X=0 to Screen.width, Y=0 to Screen.height) — keep this in mind if you’re comparing to UI systems that use top-left origin.
  • Off-Screen Objects: If the object is partially or fully off-screen, the min/max values will still be accurate (they’ll just be outside the 0-Screen.width/height range).

内容的提问来源于stack exchange,提问作者Zaheer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:33:24