ARCore:执行每一帧而不是在触摸屏幕时执行(Unity)
ARCore: execute each frame instead of when touching the screen (Unity)
我在一个项目中工作,该项目需要每帧执行一个函数,但不点击屏幕。我不知道为什么将代码放在 Update 函数中不起作用(它需要所有时间和无论如何触摸屏幕来执行代码)。我把每帧要播放的部分代码放在这里:
anchor.transform.position = Vector3.zero;
hotPoint.transform.position = Vector3.zero;
_androidPosVector3ZeroText.text = anchor.transform.position.ToString();
_camPosText.text = FirstPersonCamera.transform.position.ToString();
我将解释它是如何工作的:我已将 android 图标及其锚点放置在 0, 0, 0 世界位置。我这样做是因为我一直想知道应用程序中我的世界中心在哪里。最后,我想知道每一帧是相机相对于该中心的位置。我在文本中显示每个值。这段代码在 Update 函数中,我不知道为什么我必须触摸屏幕才能执行它,如果它不在任何 if 或其他东西中...
在此先感谢您!
好的,这是完整的更新功能。我的部分代码在最后几行,直接在Update中调用。
public void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
_QuitOnConnectionErrors();
// Check that motion tracking is tracking.
if (Session.Status != SessionStatus.Tracking)
{
const int lostTrackingSleepTimeout = 15;
Screen.sleepTimeout = lostTrackingSleepTimeout;
if (!m_IsQuitting && Session.Status.IsValid())
{
SearchingForPlaneUI.SetActive(true);
}
return;
}
Screen.sleepTimeout = SleepTimeout.NeverSleep;
// Iterate over planes found in this frame and instantiate corresponding GameObjects to visualize them.
Session.GetTrackables<TrackedPlane>(m_NewPlanes, TrackableQueryFilter.New);
for (int i = 0; i < m_NewPlanes.Count; i++)
{
// Instantiate a plane visualization prefab and set it to track the new plane. The transform is set to
// the origin with an identity rotation since the mesh for our prefab is updated in Unity World
// coordinates.
GameObject planeObject = Instantiate(TrackedPlanePrefab, Vector3.zero, Quaternion.identity,
transform);
planeObject.GetComponent<TrackedPlaneVisualizer>().Initialize(m_NewPlanes[i]);
}
// Disable the snackbar UI when no planes are valid.
Session.GetTrackables<TrackedPlane>(m_AllPlanes);
bool showSearchingUI = true;
for (int i = 0; i < m_AllPlanes.Count; i++)
{
if (m_AllPlanes[i].TrackingState == TrackingState.Tracking)
{
showSearchingUI = false;
break;
}
}
SearchingForPlaneUI.SetActive(showSearchingUI);
// If the player has not touched the screen, we are done with this update.
Touch touch;
if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
{
return;
}
// Raycast against the location the player touched to search for planes.
TrackableHit hit;
TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
TrackableHitFlags.FeaturePointWithSurfaceNormal;
Frame.Raycast(0.5f, 0.5f, raycastFilter, out hit);
float distance = hit.Distance;
if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit) && Time.time < 15)
{
hotPoint = Instantiate(AndyAndroidPrefab, Vector3.zero, hit.Pose.rotation);
// Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
// world evolves.
anchor = hit.Trackable.CreateAnchor(hit.Pose);
anchor.transform.position = hotPoint.transform.position;
_androidPosVector3ZeroText.text = anchor.transform.position.ToString();
_camPosText.text = FirstPersonCamera.transform.position.ToString();
// Andy should look at the camera but still be flush with the plane.
if ((hit.Flags & TrackableHitFlags.PlaneWithinPolygon) != TrackableHitFlags.None)
{
// Get the camera position and match the y-component with the hit position.
Vector3 cameraPositionSameY = FirstPersonCamera.transform.position;
cameraPositionSameY.y = hit.Pose.position.y;
// Have Andy look toward the camera respecting his "up" perspective, which may be from ceiling.
hotPoint.transform.LookAt(cameraPositionSameY, hotPoint.transform.up);
}
// Make Andy model a child of the anchor.
//hotPoint.transform.parent = anchor.transform;
hotPoints.Add(hotPoint);
hotPointDistanceToCamera = Vector3.Distance(FirstPersonCamera.transform.position, anchor.transform.position);
hotPointDistancesToCamera.Add(hotPointDistanceToCamera);
distanceTexts[0].text = "Hot Point " + (Time.time.ToString()) + ": " + hotPointDistancesToCamera[0].ToString();
Text newText = Instantiate(distanceText, canvas.transform, false);
distanceTexts.Add(newText);
if (lastText != null)
{
newText.rectTransform.localPosition = lastText.rectTransform.localPosition + new Vector3(0, -30, 0);
}
lastText = newText;
}
anchor.transform.position = Vector3.zero;
hotPoint.transform.position = Vector3.zero;
_androidPosVector3ZeroText.text = anchor.transform.position.ToString();
_camPosText.text = FirstPersonCamera.transform.position.ToString();
}
好的伙计们,我知道了。你只需要将你想要应用的代码放在每一帧上,就在 "if" 上面,当你触摸屏幕时,它会放置 Android 预制件。
我不知道为什么,但这行得通。希望对某人有所帮助。
我在一个项目中工作,该项目需要每帧执行一个函数,但不点击屏幕。我不知道为什么将代码放在 Update 函数中不起作用(它需要所有时间和无论如何触摸屏幕来执行代码)。我把每帧要播放的部分代码放在这里:
anchor.transform.position = Vector3.zero;
hotPoint.transform.position = Vector3.zero;
_androidPosVector3ZeroText.text = anchor.transform.position.ToString();
_camPosText.text = FirstPersonCamera.transform.position.ToString();
我将解释它是如何工作的:我已将 android 图标及其锚点放置在 0, 0, 0 世界位置。我这样做是因为我一直想知道应用程序中我的世界中心在哪里。最后,我想知道每一帧是相机相对于该中心的位置。我在文本中显示每个值。这段代码在 Update 函数中,我不知道为什么我必须触摸屏幕才能执行它,如果它不在任何 if 或其他东西中...
在此先感谢您!
好的,这是完整的更新功能。我的部分代码在最后几行,直接在Update中调用。
public void Update()
{
if (Input.GetKey(KeyCode.Escape))
{
Application.Quit();
}
_QuitOnConnectionErrors();
// Check that motion tracking is tracking.
if (Session.Status != SessionStatus.Tracking)
{
const int lostTrackingSleepTimeout = 15;
Screen.sleepTimeout = lostTrackingSleepTimeout;
if (!m_IsQuitting && Session.Status.IsValid())
{
SearchingForPlaneUI.SetActive(true);
}
return;
}
Screen.sleepTimeout = SleepTimeout.NeverSleep;
// Iterate over planes found in this frame and instantiate corresponding GameObjects to visualize them.
Session.GetTrackables<TrackedPlane>(m_NewPlanes, TrackableQueryFilter.New);
for (int i = 0; i < m_NewPlanes.Count; i++)
{
// Instantiate a plane visualization prefab and set it to track the new plane. The transform is set to
// the origin with an identity rotation since the mesh for our prefab is updated in Unity World
// coordinates.
GameObject planeObject = Instantiate(TrackedPlanePrefab, Vector3.zero, Quaternion.identity,
transform);
planeObject.GetComponent<TrackedPlaneVisualizer>().Initialize(m_NewPlanes[i]);
}
// Disable the snackbar UI when no planes are valid.
Session.GetTrackables<TrackedPlane>(m_AllPlanes);
bool showSearchingUI = true;
for (int i = 0; i < m_AllPlanes.Count; i++)
{
if (m_AllPlanes[i].TrackingState == TrackingState.Tracking)
{
showSearchingUI = false;
break;
}
}
SearchingForPlaneUI.SetActive(showSearchingUI);
// If the player has not touched the screen, we are done with this update.
Touch touch;
if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
{
return;
}
// Raycast against the location the player touched to search for planes.
TrackableHit hit;
TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinPolygon |
TrackableHitFlags.FeaturePointWithSurfaceNormal;
Frame.Raycast(0.5f, 0.5f, raycastFilter, out hit);
float distance = hit.Distance;
if (Frame.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit) && Time.time < 15)
{
hotPoint = Instantiate(AndyAndroidPrefab, Vector3.zero, hit.Pose.rotation);
// Create an anchor to allow ARCore to track the hitpoint as understanding of the physical
// world evolves.
anchor = hit.Trackable.CreateAnchor(hit.Pose);
anchor.transform.position = hotPoint.transform.position;
_androidPosVector3ZeroText.text = anchor.transform.position.ToString();
_camPosText.text = FirstPersonCamera.transform.position.ToString();
// Andy should look at the camera but still be flush with the plane.
if ((hit.Flags & TrackableHitFlags.PlaneWithinPolygon) != TrackableHitFlags.None)
{
// Get the camera position and match the y-component with the hit position.
Vector3 cameraPositionSameY = FirstPersonCamera.transform.position;
cameraPositionSameY.y = hit.Pose.position.y;
// Have Andy look toward the camera respecting his "up" perspective, which may be from ceiling.
hotPoint.transform.LookAt(cameraPositionSameY, hotPoint.transform.up);
}
// Make Andy model a child of the anchor.
//hotPoint.transform.parent = anchor.transform;
hotPoints.Add(hotPoint);
hotPointDistanceToCamera = Vector3.Distance(FirstPersonCamera.transform.position, anchor.transform.position);
hotPointDistancesToCamera.Add(hotPointDistanceToCamera);
distanceTexts[0].text = "Hot Point " + (Time.time.ToString()) + ": " + hotPointDistancesToCamera[0].ToString();
Text newText = Instantiate(distanceText, canvas.transform, false);
distanceTexts.Add(newText);
if (lastText != null)
{
newText.rectTransform.localPosition = lastText.rectTransform.localPosition + new Vector3(0, -30, 0);
}
lastText = newText;
}
anchor.transform.position = Vector3.zero;
hotPoint.transform.position = Vector3.zero;
_androidPosVector3ZeroText.text = anchor.transform.position.ToString();
_camPosText.text = FirstPersonCamera.transform.position.ToString();
}
好的伙计们,我知道了。你只需要将你想要应用的代码放在每一帧上,就在 "if" 上面,当你触摸屏幕时,它会放置 Android 预制件。 我不知道为什么,但这行得通。希望对某人有所帮助。