// With thanks to http://www.turiyaware.com/a-solution-to-unitys-camera-worldtoscreenpoint-causing-ui-elements-to-display-when-object-is-behind-the-camera/ public static MinMax3D GetScreenRectFromBounds(MeshFilter renderer, Camera mainCamera) { MinMax3D minMax = new MinMax3D (float.MaxValue, float.MinValue); Vector3[] screenBoundsExtents = new Vector3[8]; var localBounds = renderer.sharedMesh.bounds; bool anyPointIsInFrontOfCamera = false; for (int i = 0; i < 8; i++) { Vector3 localSpaceCorner = localBounds.center + Vector3.Scale (localBounds.extents, cubeCornerOffsets[i]); Vector3 worldSpaceCorner = renderer.transform.TransformPoint (localSpaceCorner); Vector3 viewportSpaceCorner = mainCamera.WorldToViewportPoint (worldSpaceCorner); if (viewportSpaceCorner.z > 0) { anyPointIsInFrontOfCamera = true; } else { // If point is behind camera, it gets flipped to the opposite side // So clamp to opposite edge to correct for this viewportSpaceCorner.x = (viewportSpaceCorner.x <= 0.5f) ? 1 : 0; viewportSpaceCorner.y = (viewportSpaceCorner.y <= 0.5f) ? 1 : 0; } // Update bounds with new corner point minMax.AddPoint (viewportSpaceCorner); } // All points are behind camera so just return empty bounds if (!anyPointIsInFrontOfCamera) { return new MinMax3D (); } return minMax; }
internal static MinMax3D GetScreenRectFromBounds(MeshFilter renderer, Camera main_camera) { // With thanks to http://www.turiyaware.com/a-solution-to-unitys-camera-worldtoscreenpoint-causing-ui-elements-to-display-when-object-is-behind-the-camera/ var min_max = new MinMax3D(min: float.MaxValue, max: float.MinValue); var screen_bounds_extents = new Vector3[8]; var local_bounds = renderer.sharedMesh.bounds; var any_point_is_in_front_of_camera = false; for (var i = 0; i < 8; i++) { var local_space_corner = local_bounds.center + Vector3.Scale(a: local_bounds.extents, b: _cube_corner_offsets[i]); var world_space_corner = renderer.transform.TransformPoint(position: local_space_corner); var viewport_space_corner = main_camera.WorldToViewportPoint(position: world_space_corner); if (viewport_space_corner.z > 0) { any_point_is_in_front_of_camera = true; } else { // If point is behind camera, it gets flipped to the opposite side // So clamp to opposite edge to correct for this viewport_space_corner.x = (viewport_space_corner.x <= 0.5f) ? 1 : 0; viewport_space_corner.y = (viewport_space_corner.y <= 0.5f) ? 1 : 0; } // Update bounds with new corner point min_max.AddPoint(point: viewport_space_corner); } // All points are behind camera so just return empty bounds if (!any_point_is_in_front_of_camera) { return(new MinMax3D()); } return(min_max); }