Unity中如何获取GameObject相对于屏幕的起止坐标?
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
RectTransforminstead 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

