Проблема в том, что Vuforia VuforiaBehaviour
на камере удерживает доступ к реальному аппаратному обеспечению камеры устройства>> Пока что больше никто не может его использовать.
Для исправления этого вы можете использовать выделенную камеру для Vuforia (просто где-нибудь поместите новый GameObject, например, VuforiaCamera
на сцену и прикрепите к ней компонент Camera
, а также VuforiaBehaviour
.
На Vuforia Camera установите Culling Mask
на Nothing
(мы ничего не визуализируем с этой камерой) и Depth
на например. -2
(более высокие значения отображаются сверху -> поместите это позади всех остальных камер).
Вы должны сделать это, потому что в противном случае Vuforia автоматически добавляет его в основную камеру (которую мы не хотим отключать, потому что тогда мы ничего не видим). При добавлении одного к сцене Vuforia автоматически использует его вместо этого.
Везде, где вам нужна камера, конечно, вы используете оригинальную камеру из голо-туки (ваша обычная MainCamera
). Проблема в том, что вы не можете полностью положиться на Camera.main
в сценариях, потому что во время выполнения VuforiaBehaviour
автоматически помечает Camera
как MainCamera
... (-_-) Vuforia ... так что дополнительно я всегда отключал и включил VuforiaBehaviour
вместе с GameObject, но, возможно, этого уже достаточно, чтобы только отключить и включить GameObject. По крайней мере, в GameStart его следует отключить, я полагаю, пока все, что зависит от Camera.main
, не будет закончено.
Тогда вы можете просто отключить VuforiaCamera
, на котором есть VuforiaBehaviour
.
VuforiaBehaviour.Instance.gameObject.SetActive(false);
// Note: that part I'm just inventing since I did it different
// using reference etc. I hope vuforia does not destroy the Instance
// OnDisable .. otherwise you would need the reference instead of using Instance here
// but maybe it is already enough to just enable and disable the GameObject
VuforiaBehaviour.Instance.enabled = false;
Благодаря этому камера устройства стала «бесплатной», и PhotoCapture теперь может использовать ее.
PhotoCapture.StartPhotoModeAsync(....
Если вам снова понадобится камера для vuforia, сначала остановите PhotoCapture
PhotoCapture.StopPhotoModeAsync(..
и затем после остановки в обратном вызове снова включите ARCamera
(объект с VuforiaBehaviour
) и VuforiaBehaviour
снова.
Что-то вроде
private void Awake()
{
var cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
// Create a PhotoCapture object
PhotoCapture.CreateAsync(false, captureObject =>
{
photoCaptureObject = captureObject;
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
});
}
private void Update()
{
// if not initialized yet don't take input
if (photoCaptureObject == null) return;
if (Input.GetKeyDown("k"))
{
Debug.Log("k was pressed");
VuforiaBehaviour.Instance.gameObject.SetActive(false);
// Activate the camera
photoCaptureObject.StartPhotoModeAsync(cameraParameters, result =>
{
if (result.success)
{
// Take a picture
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
else
{
Debug.LogError("Couldn't start photo mode!", this);
}
});
}
}
private static string FileName(int width, int height)
{
return $"screen_{width}x{height}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png";
}
private void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame photoCaptureFrame)
{
// Copy the raw image data into the target texture
photoCaptureFrame.UploadImageDataToTexture(targetTexture);
Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture.ReadPixels(new Rect(0, 0, cameraResolution.width, cameraResolution.height), 0, 0);
targetTexture.Apply();
byte[] bytes = targetTexture.EncodeToPNG();
string filename = FileName(Convert.ToInt32(targetTexture.width), Convert.ToInt32(targetTexture.height));
//save to folder under assets
File.WriteAllBytes(Application.streamingAssetsPath + "/Snapshots/" + filename, bytes);
Debug.Log("The picture was uploaded");
// Deactivate the camera
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
private void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
// Shutdown the photo capture resource
photoCaptureObject.Dispose();
photoCaptureObject = null;
VuforiaBehaviour.Instance.gameObject.SetActive(true);
}
Однако исключение также может быть связано с этой проблемой .