【问题标题】:Keeping the object/3D Model on the screen even when the target is lost (UNITY + Vuforia)即使目标丢失也能将对象/3D 模型保持在屏幕上(UNITY + Vuforia)
【发布时间】:2017-05-22 17:53:09
【问题描述】:

我想将对象/3D 模型保持在移动屏幕的中心,即使目标丢失(在跟踪 lost() 时)以及找到目标时最后跟踪的图像模型应该消失。我正在使用统一。

我尝试遵循 cloudreco 示例,但无法正确执行。

我正在使用的屏幕居中:

GameObject lost = GameObject.Find ("IT"+mTrackableBehaviour.TrackableName);

lost.transform.position=Camera.main.ScreenToWorldPoint(new Vector3(Screen.width/2, Screen.height/2, Camera.main.nearClipPlane) );


我有大约 10 个图像目标,最大同时图像跟踪设置为 1。
寻找解决方案。
谢谢!

编辑:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
namespace Vuforia
{
    /// <summary>
    /// A custom handler that implements the ITrackableEventHandler interface.
    /// </summary>
    public class dtehedit : MonoBehaviour,
    ITrackableEventHandler
    {

        #region PRIVATE_MEMBER_VARIABLES

        private TrackableBehaviour mTrackableBehaviour;
        private bool firsttime=false;
        //private bool secondtime=false;
        GameObject lost, lostclone;
        #endregion // PRIVATE_MEMBER_VARIABLES



        #region UNTIY_MONOBEHAVIOUR_METHODS

        void Start()
        {
            Debug.Log ("start method before registring");
            mTrackableBehaviour = GetComponent<TrackableBehaviour>();
            if (mTrackableBehaviour)
            {
                mTrackableBehaviour.RegisterTrackableEventHandler(this);
            }
            Debug.Log ("start method after registring");
        }

        #endregion // UNTIY_MONOBEHAVIOUR_METHODS



        #region PUBLIC_METHODS

        /// <summary>
        /// Implementation of the ITrackableEventHandler function called when the
        /// tracking state changes.
        /// </summary>
        public void OnTrackableStateChanged(
            TrackableBehaviour.Status previousStatus,
            TrackableBehaviour.Status newStatus)
        {
            if (newStatus == TrackableBehaviour.Status.DETECTED ||
                newStatus == TrackableBehaviour.Status.TRACKED ||
                newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
            {
                OnTrackingFound();
            }
            else
            {
                OnTrackingLost();
            }
        }

        #endregion // PUBLIC_METHODS



        #region PRIVATE_METHODS


        private void OnTrackingFound()
        {
            firsttime = true;
            if (lostclone != null) {
                Debug.Log ("LOST CLONE otf ::" + lostclone.name);
                DestroyObject (lostclone); // (1) if new object is scanned gameobject lostclone is not destroyed
            }

            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

            // Enable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = true;
            }

            // Enable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = true;
            }

            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
        }


        private void OnTrackingLost()
        {
//          Debug.Log (firsttime);
//          if (!firsttime) {
//              Renderer[] rendererComponents = GetComponentsInChildren<Renderer> (true);
//              Collider[] colliderComponents = GetComponentsInChildren<Collider> (true);
//
//              // Disable rendering:
//              foreach (Renderer component in rendererComponents) {
//                  component.enabled = false;
//              }
//
//              // Disable colliders:
//              foreach (Collider component in colliderComponents) {
//                  component.enabled = false;
//              }
//
//          } else {
//              string itname = mTrackableBehaviour.TrackableName;
//              Debug.Log ("lost trackable name " + itname);
//              GameObject lost = GameObject.Find ("IT" + itname);
// (2) WOrking but dont know how to reposition gameobject after next tracker is found 
//              lost.transform.GetChild(0).transform.position=Camera.main.ScreenToWorldPoint(new Vector3(Screen.width/2, Screen.height/2, Camera.main.nearClipPlane+20) ); 
// (3) workinh but dont know how to reset camera position when next tracker is found
////                Camera.main.transform.position = lost.transform.GetChild(0).transform.position + lost.transform.GetChild(0).transform.forward * 25;
////                Camera.main.transform.LookAt (lost.transform.GetChild(0).transform);
//          }


                            Renderer[] rendererComponents = GetComponentsInChildren<Renderer> (true);
                            Collider[] colliderComponents = GetComponentsInChildren<Collider> (true);

                            // Disable rendering:
                            foreach (Renderer component in rendererComponents) {
                                component.enabled = false;
                            }

                            // Disable colliders:
                            foreach (Collider component in colliderComponents) {
                                component.enabled = false;
                            }
            if (firsttime) {
                string itname = mTrackableBehaviour.TrackableName;
                Debug.Log ("lost trackable name " + itname);
                lost = GameObject.Find ("IT" + itname).transform.GetChild (0).gameObject;
                lostclone = Instantiate (lost) as GameObject; //decoupling
                Debug.Log ("LOST CLONE ::"+lostclone.name);
            }
            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
        }

        #endregion // PRIVATE_METHODS
    }
}

对于上面的代码,我尝试了三种方法/方法在跟踪丢失后将我的 3D 模型显示在屏幕上,但似乎都没有完美或按预期工作

我已经通过实例化方法解耦/克隆我的 3d 对象,但是当我再次找到跟踪器时,最后一个对象没有被破坏 (1) 以及如何使它出现在相机前面
我在跟踪丢失时将 3dobject 移动到相机,但是当再次跟踪发现如何将我的 3dmodel 再次带到原始位置时 (2)

我在跟踪丢失后将我的相机移动到我的 3dobject 但是当再次跟踪时发现如何将相机带到原始位置 (3)
请查看代码并请帮助我..不知道我错过了什么.. .?

【问题讨论】:

  • 1.您提供的代码到底发生了什么?什么不起作用? 2. 我相信您不需要ScreenToWorldPoint,您可以将GameObject 定位在Camera 所在的位置,然后使用tranform.forward 向量将您的GameObject 移动到相机正在寻找的位置。
  • 跟踪发现我的 3d 模型显示...我希望它保留在屏幕上,直到找到新的标记。意味着当标记被移除时,3d 模型不会从屏幕上消失。希望你明白了
  • 要做到这一点,你需要将GameObjectImageTarget 解耦。由于他们具有子父关系,因此当图像/标记丢失时,您的 GameObject 将被停用。
  • 你能告诉我怎么做吗?我应该让相机的父母和相机的3d模型孩子吗?我是新的团结?请告诉我该怎么做...谢谢!
  • 我解释了如何做到这一点。您必须进行一些研究工作,尝试实施它,如果它不起作用,请返回并使用您尝试过的代码编辑您的帖子。

标签: c# unity3d vuforia


【解决方案1】:

我已经查看了您的代码,并对其进行了一些修复,我相信这应该可以解决您的问题。

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
namespace Vuforia
{
    /// <summary>
    /// A custom handler that implements the ITrackableEventHandler interface.
    /// </summary>
    public class dtehedit : MonoBehaviour,
    ITrackableEventHandler
    {

        #region PRIVATE_MEMBER_VARIABLES

        private TrackableBehaviour mTrackableBehaviour;
        private bool firsttime = false;
        string itname = "";
        //private bool secondtime=false;
        GameObject lost, lostclone;
        #endregion // PRIVATE_MEMBER_VARIABLES



        #region UNTIY_MONOBEHAVIOUR_METHODS

        void Start()
        {
            Debug.Log("start method before registring");
            mTrackableBehaviour = GetComponent<TrackableBehaviour>();
            if (mTrackableBehaviour)
            {
                mTrackableBehaviour.RegisterTrackableEventHandler(this);
            }
            Debug.Log("start method after registring");
        }

        #endregion // UNTIY_MONOBEHAVIOUR_METHODS



        #region PUBLIC_METHODS

        /// <summary>
        /// Implementation of the ITrackableEventHandler function called when the
        /// tracking state changes.
        /// </summary>
        public void OnTrackableStateChanged(
            TrackableBehaviour.Status previousStatus,
            TrackableBehaviour.Status newStatus)
        {
            if (newStatus == TrackableBehaviour.Status.DETECTED ||
                newStatus == TrackableBehaviour.Status.TRACKED ||
                newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
            {
                OnTrackingFound();
            }
            else
            {
                OnTrackingLost();
            }
        }

        #endregion // PUBLIC_METHODS



        #region PRIVATE_METHODS


        private void OnTrackingFound()
        {
            // This is wrong because you never set it to false. Every time a tracker(image) is found it will be the first time - wrong.
            //      firsttime = true;      


            if (lostclone != null)
            {
                Debug.Log("LOST CLONE otf ::" + lostclone.name);
                // DestroyObject(lostclone); // (1) if new object is scanned gameobject lostclone is not destroyed
            }

            //Here you can reset the position of the GameObject back to the parent(tracker)'s position. 
            this.transform.GetChild(0).transform.position = new Vector3(0, 0, 0);

            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

            // Enable rendering:
            foreach (Renderer component in rendererComponents)
            {
                component.enabled = true;
            }

            // Enable colliders:
            foreach (Collider component in colliderComponents)
            {
                component.enabled = true;
            }

            Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
        }


        private void OnTrackingLost()
        {
            Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
            Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

            // What you can do is not disable this
            //foreach (Renderer component in rendererComponents)
            //{
            //    component.enabled = false;
            //}

            // Disable colliders: Disable this if you need it diabled only
            foreach (Collider component in colliderComponents)
            {
                component.enabled = false;
            }

            string itname = mTrackableBehaviour.TrackableName;
            Debug.Log("lost trackable name " + itname);
            GameObject lost = GameObject.Find("IT" + itname);
            //(2) WOrking but dont know how to reposition gameobject after next tracker is found

            // This is not decoupling but it should work ( you dont need to find the gameobject you can use [this] instead)
            this.transform.GetChild(0).transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width / 2, Screen.height / 2, Camera.main.nearClipPlane + 20));
            // Disable rendering:

            itname = mTrackableBehaviour.TrackableName;
            Debug.Log("lost trackable name " + itname);
            lost = GameObject.Find("IT" + itname).transform.GetChild(0).gameObject;
            // this is not I ment by decoupling sory, I ment de parenting -> (gameObject.parent = null)
            //lostclone = Instantiate(lost) as GameObject; //decoupling
        }

        #endregion // PRIVATE_METHODS
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多