C# 如何使用vuforia修复hololens的统一脚本中的光拍错误
我正试图用我的PhotoCapture统一脚本通过全息镜头拍照。我想使用Vuforia引擎ARCamera,以便在看到我创建的AR-GUI(用于未来功能)的同时看到现实 我得到的主要错误是: 拍摄照片失败(hr=0xC00D3704) 为什么会发生这种情况?如何修复它? FocusManager单例尚未初始化。 调试:断言(布尔值,字符串) HoloToolkit.Unity.Singleton`1:Assertisizized()(在 Assets/HoloToolkit/Common/Scripts/Singleton.cs:51) HoloToolkit.Unity.CanvasHelper:Start()(位于 Assets/HoloToolkit/Utilities/Scripts/CanvasHelper.cs:30) 也是在开始unity场景时发生的错误,但我以前没有发生过 这是我正在使用的代码,放在ARCamera上(我还试用了带有vuforia行为脚本的混合现实摄影机,但没有出现第二个错误)。另外,我想向借用此代码的人道歉,因为我不记得你网站的链接C# 如何使用vuforia修复hololens的统一脚本中的光拍错误,c#,unity3d,vuforia,hololens,C#,Unity3d,Vuforia,Hololens,我正试图用我的PhotoCapture统一脚本通过全息镜头拍照。我想使用Vuforia引擎ARCamera,以便在看到我创建的AR-GUI(用于未来功能)的同时看到现实 我得到的主要错误是: 拍摄照片失败(hr=0xC00D3704) 为什么会发生这种情况?如何修复它? FocusManager单例尚未初始化。 调试:断言(布尔值,字符串) HoloToolkit.Unity.Singleton`1:Assertisizized()(在 Assets/HoloToolkit/Common/Scr
public class PhotoCaptureExample : MonoBehaviour
{
PhotoCapture photoCaptureObject = null;
Texture2D targetTexture = null;
public string path = "";
CameraParameters cameraParameters = new CameraParameters();
void Start()
{
}
void Update()
{
if (Input.GetKeyDown("k"))
{
Debug.Log("k was pressed");
Resolution cameraResolution = PhotoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
targetTexture = new Texture2D(cameraResolution.width, cameraResolution.height);
// Create a PhotoCapture object
PhotoCapture.CreateAsync(false, delegate (PhotoCapture captureObject)
{
photoCaptureObject = captureObject;
cameraParameters.hologramOpacity = 0.0f;
cameraParameters.cameraResolutionWidth = cameraResolution.width;
cameraParameters.cameraResolutionHeight = cameraResolution.height;
cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;
// Activate the camera
photoCaptureObject.StartPhotoModeAsync(cameraParameters, delegate (PhotoCapture.PhotoCaptureResult result)
{
// Take a picture
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
});
});
}
}
string FileName(int width, int height)
{
return string.Format("screen_{0}x{1}_{2}.png", width, height, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
}
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.dataPath + "/Snapshots/" + filename, bytes);
Debug.Log("The picture was uploaded");
// Deactivate the camera
photoCaptureObject.StopPhotoModeAsync(OnStoppedPhotoMode);
}
void OnStoppedPhotoMode(PhotoCapture.PhotoCaptureResult result)
{
// Shutdown the photo capture resource
photoCaptureObject.Dispose();
photoCaptureObject = null;
}
}
似乎我无法访问OnCapturedPhotoToMemory,或者如果它已经被方法调用破坏了。现在再试一次,代码偶尔不会显示我已经按下了k
感谢您的帮助 问题是:摄像头上的Vuforia
VuforiaBehaviour
拥有对设备真实摄像头硬件的访问权=>其他任何东西都不能同时使用它
要解决此问题,您可以使用Vuforia专用摄像头(只需在场景中的某个位置放置一个新游戏对象,例如
VuforiaaCamera
,然后将camera
组件以及VuforiaaBehaviour
附加到该组件
在Vuforia相机上,将消隐遮罩设置为无
(我们不使用该相机渲染任何内容)并将深度设置为,例如-2
(在顶部渲染更高的值->将其置于所有其他相机之后)
您必须这样做,否则Vuforia会自动将其添加到主摄影机(我们不想禁用它,因为这样我们什么都看不到)。通过手动将其添加到场景中,Vuforia会自动使用该摄影机
在场景中需要摄像头的任何地方,当然都可以使用Holo Tookit中的原始摄像头(您常用的主摄像头
)。问题您不能完全依赖脚本中的Camera.main
,因为在运行时VuforiaBehaviour
会自动将其Camera
标记为main Camera
。(-)Vuforia…因此,除此之外,我总是禁用并启用Vuforibabehaviour
以及游戏对象,但可能仅禁用和启用游戏对象就足够了。至少在游戏开始时,我想应该禁用它,直到所有依赖Camera.main
的操作完成为止
然后,您可以简单地禁用带有VuforiaBehaviour
的vuforiaaCamera
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.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);
}
不过,例外情况可能也与此有关。FocusManager的设置是什么?这真的是unityscript吗?对我来说,它看起来很简单。老实说,我不知道FocusManager是什么,也不知道它来自何方:它以前没有出现过,但可能是在我从holotoolkits mixedRealityCamera换回ARCamera时出现的…这是C#但这与unity脚本(unity中制作的脚本)不兼容吗?哦,sry我得到了错误的标记!!!好的,但它告诉你focusmanager尚未设置,这似乎是第一个错误点?@BugFinder是的。错误发生后,有3个调用focusmanager.Assertisinizated();
一个在SimpleSinglePointerSelector private void Start()方法中,一个在CanvasHelper private void Start()方法中,一个在CanvasEditorExtension中,用于检查“场景中是否有焦点管理器”我没有碰过任何一个。所以我应该有两个摄像头;一个上面描述的摄像头和一个主摄像头?是的。Vuforia摄像头甚至不需要移动。它只用于访问设备真实的摄像头。我仍然不完全理解。所以我有一个主摄像头标记为maincamera,我有一个带有脚本的ARcamera摄像头和一个摄像头d vuforia行为组件?脚本是否在右侧摄像头上?画布应指向哪个摄像头?我添加了设置。我注意到,实际上我在脚本中额外启用和禁用了vuforia行为本身,但这不会产生任何影响。在所有画布等需要摄像头的地方,您可以继续使用“正常”主摄像头与以前一样..您只添加了附加的ARCamera,其设置与添加的图片中的设置相同我仍然会得到拍摄照片失败的(hr=0xC00D3704)
错误。我只尝试了VuforiaBehaviour.Instance.gameObject.SetActive(false);
然后仅VuforiaBehaviour.Instance.enabled=false;
然后这两个选项的行为相同,因此在我的情况下使用哪一个可能无关紧要:)这些选项添加在start()下(以确保从一开始就不启用),在photoCaptureObject.StartPhotoModeAsync
之前,在OnStoppedPhotoMode
.Sry的末尾,因为速度慢,但我缺少什么?