diff --git a/content/en-us/assets/engine-api/classes/Camera/DeviceSafeAreaVsFullscreen.png b/content/en-us/assets/engine-api/classes/Camera/DeviceSafeAreaVsFullscreen.png
new file mode 100644
index 000000000..b196f93ca
--- /dev/null
+++ b/content/en-us/assets/engine-api/classes/Camera/DeviceSafeAreaVsFullscreen.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6913ee127d7270f5d1622bb070c0f4ba075813cc221eebe30239425fbc75a432
+size 303211
diff --git a/content/en-us/assets/engine-api/classes/Camera/ViewportPointToRayOrigin.png b/content/en-us/assets/engine-api/classes/Camera/ViewportPointToRayOrigin.png
new file mode 100644
index 000000000..171b56cba
--- /dev/null
+++ b/content/en-us/assets/engine-api/classes/Camera/ViewportPointToRayOrigin.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e049042542892316c1aff60de6165cd56b3e9a80c1438a62832d0bcae61fe4ed
+size 286189
diff --git a/content/en-us/reference/engine/classes/Camera.yaml b/content/en-us/reference/engine/classes/Camera.yaml
index 0c0f2a928..0764bdd8b 100644
--- a/content/en-us/reference/engine/classes/Camera.yaml
+++ b/content/en-us/reference/engine/classes/Camera.yaml
@@ -238,6 +238,11 @@ properties:
viewport to its opposite corner) the camera can view. See
`Class.Camera.FieldOfView|FieldOfView` for a more general explanation of
field of view.
+
+ Note that `DiagonalFieldOfView` represents the field of view that is
+ visible by the `Class.Camera` rendering into the fullscreen area which
+ may be occluded by notches or screen cutouts on some devices. See `Class.
+ Camera.ViewportSize|ViewportSize` for more information.
code_samples:
type: float
tags:
@@ -271,6 +276,11 @@ properties:
using binoculars.
- Increasing FOV when the player is "sprinting" to give the impression of
a lack of control.
+
+ Note that `FieldOfView` represents the field of view that is visible by
+ the `Class.Camera` rendering into the fullscreen area which may be
+ occluded by notches or screen cutouts on some devices. See `Class.Camera.
+ ViewportSize|ViewportSize` for more information.
code_samples:
type: float
tags: []
@@ -534,15 +544,36 @@ properties:
writeCapabilities: []
- name: Camera.ViewportSize
summary: |
- Describes the dimensions, in pixels, of the client's viewport.
+ The dimensions of the device safe area on a Roblox client.
description: |
- **ViewportSize** describes the dimensions, in pixels, of the client's
- viewport.
-
- This property ignores the GUI inset applied by the top bar, meaning the
- center of the screen can be found at precisely at 50% of the viewport in
- both directions. You can find the position of a `Datatype.Vector3` in the
- world on the viewport using `Class.Camera:WorldToViewportPoint()`.
+ `Class.Camera.ViewportSize|ViewportSize` returns the dimensions of the
+ device safe area on the current screen. This area is a rectangle which
+ includes the Roblox top bar area but does not include any device notches
+ or screen cutouts. The units of `Class.Camera.ViewportSize|ViewportSize` are Roblox
+ UI offset units which may be different from native display pixels.
+
+
+
+ As noted above, `Class.Camera.ViewportSize|ViewportSize` is not equal to the fullscreen
+ area size on displays with cutouts or
+ notches. To obtain the fullscreen area size on all displays, you can query the
+ `Class.ScreenGui.AbsoluteSize|AbsoluteSize` property of a `Class.ScreenGui` with
+ `Class.ScreenGui.ScreenInsets|ScreenInsets` set to `Enum.ScreenInsets.None|None`. See
+ `Enum.ScreenInsets` for a more information about how screen areas are defined.
+
+ Finally, note that `Class.Camera.ViewportSize|ViewportSize` is not the actual viewport size
+ the camera uses for rendering (the camera renders in the fullscreen area). Also, the
+ `Class.Camera.FieldOfView` and `Class.Camera.DiagonalFieldOfView` properties are
+ based on the fullscreen area, not `Class.Camera.ViewportSize|ViewportSize`.
+
+ ##### Camera Updates
+
+ Only the `Class.Camera` currently referred to by `Class.Workspace.
+ CurrentCamera` has its `Class.Camera.ViewportSize|ViewportSize` updated each
+ frame during the `Class.RunService.PreRender|PreRender` step. The
+ `Class.Camera.ViewportSize|ViewportSize` of all other cameras in your
+ experience won't be updated, including those used for
+ `Class.ViewportFrame|ViewportFrames`.
code_samples:
type: Vector2
tags:
@@ -1158,26 +1189,45 @@ methods:
summary: |
Creates a unit `Datatype.Ray` from a position on the viewport (in pixels),
at a given depth from the `Class.Camera`, orientated in the camera's
- direction. Does not account for the GUI inset.
+ direction. Does not account for the `Enum.ScreenInsets|CoreUISafeInsets` inset.
description: |
- This function creates a unit `Datatype.Ray` from a 2D position on the
- viewport (defined in pixels). This position does **not** account for the
- GUI inset. The `Datatype.Ray` originates from the `Datatype.Vector3`
- equivalent of the 2D position in the world at the given depth (in studs)
- away from the `Class.Camera`.
-
- As this function does not acknowledge the GUI inset, the viewport position
- given is not equivalent to the screen position used by GUI elements. If
- you are not using `Class.ScreenGui.IgnoreGuiInset` and need an otherwise
- identical function that accounts for the GUI offset, use
+ This function creates a unit `Datatype.Ray` from a 2D position in device
+ safe viewport coordinates, defined in pixels. The ray originates from the
+ `Datatype.Vector3` equivalent of the 2D position in the world at the
+ given depth (in studs) away from the `Class.Camera`.
+
+ As illustrated below, `(0, 0)` corresponds to the top‑left point of the Roblox
+ top bar. This means that the input 2D position does **not** account for the
+ `Enum.ScreenInsets|CoreUISafeInsets` inset, but it does account for any
+ `Enum.ScreenInsets|DeviceSafeInsets`.
+
+
+
+ Note that UI instances use a different coordinate system
+ (`Class.GuiObject.AbsolutePosition` uses the
+ `Enum.ScreenInsets|CoreUISafeInsets` viewport coordinate system
+ while this function uses the `Enum.ScreenInsets|DeviceSafeInsets`
+ viewport coordinate system). If you
+ would like to specify position in core UI coordinates, please use
`Class.Camera:ScreenPointToRay()`.
+ Also note that this function only works for the `Class.Workspace.
+ CurrentCamera` camera.
+ Other cameras, such as those you create for a `Class.ViewportFrame`, have
+ an initial viewport size of `(1, 1)` and are only updated after you set
+ them to `Class.Workspace.CurrentCamera|CurrentCamera`. The mismatch in
+ viewport size causes the camera to return a ray with an incorrect
+ `Datatype.Ray.Direction`.
+
This function can be used in conjunction with the
- `Class.Camera.ViewportSize` property to create a ray from the centre of
+ `Class.Camera.ViewportSize|ViewportSize` property to create a ray from the centre of
the screen, for example:
```lua
- local camera = workspace.CurrentCamera
+ local Workspace = game:GetService("Workspace")
+
+ local camera = Workspace.CurrentCamera
+
local viewportPoint = camera.ViewportSize / 2
local unitRay = camera:ViewportPointToRay(viewportPoint.X, viewportPoint.Y, 0)
```
@@ -1186,33 +1236,30 @@ methods:
create a longer ray, you can do the following:
```lua
- local camera = workspace.CurrentCamera
+ local Workspace = game:GetService("Workspace")
+
+ local camera = Workspace.CurrentCamera
+
local length = 500
local unitRay = camera:ScreenPointToRay(100, 100)
local extendedRay = Ray.new(unitRay.Origin, unitRay.Direction * length)
```
-
- This function only works for the current Workspace camera. Other cameras,
- such as those you create for a `Class.ViewportFrame`, have an initial
- viewport size of `(1, 1)` and are only updated after you set them to
- `Class.Workspace.CurrentCamera`. The mismatch in viewport size causes the
- camera to return a ray with an incorrect `Datatype.Ray.Direction`.
code_samples:
parameters:
- name: x
type: float
default:
summary: |
- The position on the X axis, in pixels, of the viewport point at which
- to originate the `Datatype.Ray`. This position does not account for
- the GUI inset.
+ The position on the **X** axis, in pixels, of the viewport point at
+ which to originate the `Datatype.Ray`, in device safe area
+ coordinates.
- name: 'y'
type: float
default:
summary: |
- The position on the Y axis, in pixels, of the viewport point at which
- to originate the `Datatype.Ray`. This position does not account for
- the GUI inset.
+ The position on the **Y** axis, in pixels, of the viewport point at
+ which to originate the `Datatype.Ray`, in device safe area
+ coordinates.
- name: depth
type: float
default: 0