Migrating to UXR.QuestCamera V3
UXR.QuestCamera v3 introduces a soft rewrite of the package with several breaking changes. It's highly recommended to update to v3, as it includes fixes for many crashes and stutters. This page documents all changes to the public API in v3.0.0 and v3.1.0 compared to v2.6.1.
Basic Sample
This script shows the most important changes in V3 compared to V2:
// Open the camera.
CameraDevice camera = UCameraManager.Instance.OpenCamera(currentCamera);
if (camera == null)
{
Debug.LogError("Could not open camera!");
yield break;
}
yield return camera.WaitForInitialization();
// Check if it opened successfully
if (camera.CurrentState != NativeWrapperState.Opened)
{
Debug.LogError("Could not open camera!");
// Very important, this frees up any resources held by the camera.
// V2: camera.Destroy();
// V3: Yield to DisposeAsync() using extension instead of calling Destroy().
yield return camera.DisposeAsync().Yield();
yield break;
}
// Create a capture session with the camera, at the chosen resolution.
// V2: CreateContinuousCaptureSession returns CaptureSessionObject<ContinuousCaptureSession>
// V3: CreateContinuousCaptureSession returns CapturePipeline<ContinuousCaptureSession>
CapturePipeline<ContinuousCaptureSession> sessionObject = camera.CreateContinuousCaptureSession(highestResolution);
if (sessionObject == null)
{
Debug.LogError("Could not open camera session!");
yield return camera.DisposeAsync().Yield(); // V3 dispose
yield break;
}
yield return sessionObject.CaptureSession.WaitForInitialization();
// Check if it opened successfully
if (sessionObject.CaptureSession.CurrentState != NativeWrapperState.Opened)
{
Debug.LogError("Could not open camera session!");
// Both of these are important for releasing the camera and session resources.
// V2: sessionObject.Destroy();
// V3: Yield to DisposeAsync().
yield return sessionObject.DisposeAsync().Yield();
yield return camera.DisposeAsync().Yield(); // V3 dispose
yield break;
}
// Set the image texture.
_rawImage.texture = sessionObject.TextureConverter.FrameRenderTexture;
CameraDevice
CameraDevice is no longer a MonoBehavior and now implements AndroidJavaProxy and IAsyncDisposable.
Removed
Release(),Destroy()— replaced byDisposeAsync().IsActiveAndUsable
Changed
OnDeviceOpened:Action<string>— parameter is the ID of the opened camera.OnDeviceClosed:Action<string?>— parameter is the ID of the closed camera, ornullif it failed to open.OnDeviceErred:Action<string?, ErrorCode>— parameters are the ID of the erred camera (ornullif it failed to open) and the error code.OnDeviceDisconnected:Action<string>— parameter is the ID of the disconnected camera.WaitForInitialization()now returns aWaitUntilobject and throwsObjectDisposedExceptionif theCameraDevicewas disposed at the time of calling.WaitForInitializationAsync()now accepts an optionalCancellationTokenand throwsObjectDisposedExceptionif theCameraDevicewas disposed at the time of calling.CreateContinuousCaptureSession()andCreateOnDemandCaptureSession()now returnCapturePipeline<ContinuousCaptureSession>?andCapturePipeline<OnDemandCaptureSession>?, respectively, and throwObjectDisposedExceptionif theCameraDevicewas disposed at the time of calling.CreateSurfaceTextureCaptureSession()andCreateOnDemandSurfaceTextureCaptureSession()now have nullable return types and throwObjectDisposedExceptionif theCameraDevicewas disposed at the time of calling.CameraIdis no longer a property and is now a cached value.
v3.1.0 Specific Changes
WaitForInitializationAsync()now returnsTask<bool>representing the open state of the device.
CaptureSessionObject
CaptureSessionObject<T> has been replaced by CapturePipeline<T>, which implements IAsyncDisposable.
- Removed
GameObjectCameraFrameForwarder— functionality moved toContinuousCaptureSession.Destroy()— replaced byDisposeAsync().
ContinuousCaptureSession
ContinuousCaptureSession is no longer a MonoBehavior and now implements AndroidJavaProxy and IAsyncDisposable.
Removed
Release()— replaced byDisposeAsync().IsActiveAndUsable
Changed
OnSessionConfigurationFailed:Action<bool>— parameter indicates whether the failure was caused by a camera access or security exception.OnSessionConfigured,OnSessionRequestSet,OnSessionRequestFailed:ActionWaitForInitialization()now returns aWaitUntilobject and throwsObjectDisposedExceptionif theContinuousCaptureSessionwas disposed at the time of calling.WaitForInitializationAsync()now accepts an optionalCancellationTokenand throwsObjectDisposedExceptionif theContinuousCaptureSessionwas disposed at the time of calling.
v3.1.0 Specific Changes
WaitForInitializationAsync()now returnsTask<bool>representing the open state of the session.
OnDemandCaptureSession
OnDemandCaptureSession inherits from ContinuousCaptureSession and includes the same breaking changes, plus the following:
- Changed
RequestCapture()now throwsObjectDisposedExceptionif theOnDemandCaptureSessionwas disposed at the time of calling.
YUVToRGBAConverter
YUVToRGBAConverter is no longer a MonoBehavior and now implements IDisposable.
Removed
Release()— replaced byDispose().OnFrameProcessedWithTimestamp— replaced with newOnFrameProcessed.SetupCameraFrameForwarder()— replaced with new constructorYUVToRGBAConverter(Resolution).CameraFrameForwarder
Changed
Shaderis now a nullable-aware property.OnFrameProcessed:Action<RenderTexture, long>— parameters for the frame'sRenderTextureand the capture's timestamp, in nanoseconds.
SurfaceTextureCaptureSession
SurfaceTextureCaptureSession has been moved to the Uralstech.UXR.QuestCamera.SurfaceTextureCapture namespace, no longer inherits from ContinuousCaptureSession, and now implements AndroidJavaProxy and IAsyncDisposable.
Removed
Release()— replaced byDisposeAsync().Resolution— useTexture.widthandTexture.heightinstead.IsActiveAndUsable
Changed
Textureis now a read-only field.OnSessionConfigurationFailed:Action<bool>— parameter indicates whether the failure was caused by a camera access or security exception.OnSessionConfigured,OnSessionRequestSet,OnSessionRequestFailed:ActionWaitForInitialization()now returns aWaitUntilobject and throwsObjectDisposedExceptionif theSurfaceTextureCaptureSessionwas disposed at the time of calling.WaitForInitializationAsync()now accepts an optionalCancellationTokenand throwsObjectDisposedExceptionif theSurfaceTextureCaptureSessionwas disposed at the time of calling.
v3.1.0 Specific Changes
WaitForInitializationAsync()now returnsTask<bool>representing the open state of the session.
OnDemandSurfaceTextureCaptureSession
OnDemandSurfaceTextureCaptureSession (moved to the Uralstech.UXR.QuestCamera.SurfaceTextureCapture namespace) inherits from SurfaceTextureCaptureSession and includes the same breaking changes, plus the following:
Changed
RequestCapture(Action<Texture2D>)is nowbool RequestCapture(Action<Texture2D, long>)where thelongcallback parameter is the capture timestamp, returning the success of the capture, and throwsObjectDisposedExceptionif theOnDemandSurfaceTextureCaptureSessionwas disposed at the time of calling.RequestCapture()now returns aWaitUntil?object (nullwhen the capture fails) and throwsObjectDisposedExceptionif theOnDemandSurfaceTextureCaptureSessionwas disposed at the time of calling.RequestCaptureAsync()is nowAwaitable<(Texture2D?, long)> RequestCaptureAsync()(Texture2Disnullwhen the capture fails), accepts an optionalCancellationToken, and throwsObjectDisposedExceptionif theOnDemandSurfaceTextureCaptureSessionwas disposed at the time of calling.
v3.1.0 Specific Changes
RequestCaptureAsync()now returnsTask<(Texture2D?, long)>.
CameraInfo
CameraInfo is now a record type and implements IDisposable.
- Changed
CameraEyenow defines the following enumeration values:Unknown = -1Left = 0Right = 1
CameraSourcenow defines the following enumeration values:Unknown = -1PassthroughRGB = 0
LensPoseTranslationis now nullable (Vector3?).LensPoseRotationis now nullable (Quaternion?).Intrinsicsis now nullable (CameraIntrinsics?).NativeCameraCharacteristicsis now managed by theCameraInfoinstance — do not dispose it manually.CameraIntrinsicsis now a record type.- All properties are now read-only fields with cached values.
CameraFrameForwarder (Removed)
CameraFrameForwarder has been removed. Its functionality has been moved to ContinuousCaptureSession.
- Changed
OnFrameReady:Action<IntPtr, IntPtr, IntPtr, int, int, int, long>— moved toContinuousCaptureSession.
See theOnFrameReadydocumentation for parameter details.
CaptureTemplate
- Removed
ZeroShutterLag— not compatible with capture sessions created by the plugin.
UCameraManager
All methods and properties in UCameraManager are now nullable-aware with no breaking changes.