AndroidManifest.xml and remove the following line if present:<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="horizonos.permission.HEADSET_CAMERA" />
horizonos.permission.HEADSET_CAMERA permission, avoiding any duplicate permission requests.PassthroughCameraAccess cameraAccess = gameObject.AddComponent<PassthroughCameraAccess>(); cameraAccess.CameraPosition = PassthroughCameraAccess.CameraPositionType.Left; cameraAccess.RequestedResolution = new Vector2Int(1280, 960);
public class WebCamTextureManagerExample : MonoBehaviour
{
[SerializeField] private WebCamTextureManager webCamTextureManager;
void Update()
{
// Wait until WebCamTexture is available
if (webCamTextureManager.WebCamTexture != null)
{
// Use WebCamTexture as Texture
Texture texture = webCamTextureManager.WebCamTexture;
// Get additional data via PassthroughCameraUtils
var intrinsics = PassthroughCameraUtils.GetCameraIntrinsics(webCamTextureManager.Eye);
Pose pose = PassthroughCameraUtils.GetCameraPoseInWorld(webCamTextureManager.Eye);
Ray ray = PassthroughCameraUtils.ScreenPointToRayInWorld(webCamTextureManager.Eye, screenPoint);
}
}
}
public class PassthroughCameraAccessExample : MonoBehaviour
{
[SerializeField] private PassthroughCameraAccess cameraAccess;
void Update()
{
if (cameraAccess.enabled)
{
// Texture can be accessed immediately after enabling the component.
// The texture itself can be black for a couple of frames, but it's already safe to use.
Texture texture = cameraAccess.GetTexture();
}
// Wait until PassthroughCameraAccess.IsPlaying is true
if (cameraAccess.IsPlaying)
{
// Camera data is available only when IsPlaying is true
PassthroughCameraAccess.CameraIntrinsics intrinsics = cameraAccess.Intrinsics;
Pose pose = cameraAccess.GetCameraPose();
Ray ray = cameraAccess.ViewportPointToRay(normalizedViewportPoint);
// Newly added properties:
Vector2Int resolution = cameraAccess.CurrentResolution;
DateTime timestamp = cameraAccess.Timestamp;
}
}
}
| Old API | New PassthroughCameraAccess Method | |
|---|---|---|
PassthroughCameraUtils.GetOutputSizes(cameraEye) | GetSupportedResolutions(cameraPosition) | Returns a list of available camera resolutions. A static method which can be called before creating PassthroughCameraAccess instance. |
webCamTextureManager.Eye | CameraPositionType CameraPosition | Controls which camera (Left or Right) will be used. Use instead of PassthroughCameraEye enum. |
webCamTextureManager.WebCamTexture.width/height | Vector2Int CurrentResolution | Returns current camera resolution. |
webCamTextureManager.WebCamTexture | GetTexture() | Retrieves GPU texture of the latest camera image. Use this method to access camera images on GPU. Available immediately after enabling PassthroughCameraAccess if permission is granted. |
PassthroughCameraUtils.GetCameraIntrinsics(cameraEye) | Intrinsics | Returns static intrinsic parameters of the sensor. Available immediately after enabling PassthroughCameraAccess if permission is granted. |
PassthroughCameraUtils.GetCameraPoseInWorld(cameraEye) | GetCameraPose() | Return Camera’s world-space pose. Uses current timestamp to return precise camera pose. |
PassthroughCameraUtils.ScreenPointToRayInWorld(cameraEye, screenPoint) | ViewportPointToRay(viewportPoint) | Returns a world-space ray going from camera through a viewport point. Viewport-space is normalized and relative to the camera. The bottom-left of the camera is (0,0); the top-right is (1,1). |
N/A (not available) | WorldToViewportPoint(worldPosition) | Transforms worldPosition from world-space into viewport-space. |
N/A (not available) | Timestamp | Timestamp associated with the latest camera image. |
texturePoint point:Vector2 texturePoint = ...; // Texture pixel coordinates
Vector2 currentResolution = new Vector2(webCamTextureManager.WebCamTexture.width, webCamTextureManager.WebCamTexture.height);
Vector2 sensorResolution = PassthroughCameraUtils.GetCameraIntrinsics(webCamTextureManager.Eye).Resolution;
var sensorCoord = new Vector2Int(
Mathf.RoundToInt(texturePoint.x / currentResolution.x * sensorResolution.x),
Mathf.RoundToInt(texturePoint.y / currentResolution.y * sensorResolution.y));
var ray = PassthroughCameraUtils.ScreenPointToRayInWorld(
PassthroughCameraEye.Left,
sensorCoord
);
texturePoint to normalized viewport coordinates before passing them to ViewportPointToRay:Vector2 texturePoint = ...; // Texture pixel coordinates
var viewportPoint = new Vector2(
(float)texturePoint.x / cameraAccess.CurrentResolution.x, // Normalize to 0-1
(float)texturePoint.y / cameraAccess.CurrentResolution.y // Normalize to 0-1
);
var ray = cameraAccess.ViewportPointToRay(viewportPoint);
// New reverse conversion also available
Vector3 worldPos = hitPoint;
Vector2 backToViewport = cameraAccess.WorldToViewportPoint(worldPos);