Отключить / включить визуализацию отслеживаемых самолетов в ARCore unity

Я некоторое время искал код для ARCore Unity, и я хочу выполнить одну простую задачу, а именно: иметь кнопку переключения, чтобы пользователь мог разместить объект в сцене, зная, где его разместить, пока отслеживаемые плоскости видны. и как только пользователь помещает объект, ему предоставляется возможность просто визуально отключить отслеживаемые плоскости, чтобы он выглядел более реалистично. Я смог сделать это в Android Studio, выполнив что-то вроде этого в основном HelloArActivity.java:

if (planeToggle) {
                mPlaneRenderer.drawPlanes(mSession.getAllPlanes(), frame.getPose(), projmtx);
            }

это было действительно просто. Я создал логический объект с именем planeToggle и просто поместил функцию mPlaneRenderer.drawPlanes в условие if. Когда логическое значение истинно, оно отображает плоскости, а когда оно ложно, оно не ...

Однако с Unity я запутался. Я сделал что-то подобное в HelloARController.cs:

Сделал кнопку для переключения самолетов. Установите для него прослушиватель событий, чтобы переключить логическую переменную, и выполните примерно следующее:

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(m_trackedPlanePrefab, Vector3.zero, Quaternion.identity,
                        transform);
                    planeObject.GetComponent<TrackedPlaneVisualizer>().SetTrackedPlane(m_newPlanes[i]);

                    m_planeColors[0].a = 0;

                    // Apply a random color and grid rotation.
                    planeObject.GetComponent<Renderer>().material.SetColor("_GridColor", m_planeColors[0]);
                    planeObject.GetComponent<Renderer>().material.SetFloat("_UvRotation", Random.Range(0.0f, 360.0f));


        if (togglePlanes == false){    // my code

          planeObject.SetActive(false); // my code

          } //
  }

Когда я нажимаю кнопку переключения, ничего не происходит.

Другой вариант, который у меня был, - это внести изменения в TrackedPlaneVisualizer.cs, где я сделал что-то вроде этого:

for (int i = 0; i < planePolygonCount; ++i)
            {
                Vector3 v = m_meshVertices[i];

                // Vector from plane center to current point
                Vector3 d = v - planeCenter;

                float scale = 1.0f - Mathf.Min((FEATHER_LENGTH / d.magnitude), FEATHER_SCALE);
                m_meshVertices.Add(scale * d + planeCenter);

                if (togglePlanesbool == true) // my code
                {
                    m_meshColors.Add(new Color(0.0f, 0.0f, 0.0f, 1.0f)); // my code
                }

                else
                {
                    m_meshColors.Add(new Color(0.0f, 0.0f, 0.0f, 0.0f)); // my code
                }
     }

Это сработало. Но у меня возникают задержки при переключении, и иногда, если были визуализированы две разные плоскости, они начинают переключаться между собой (если один включен, другой отключается). Так что я думаю, это тоже не вариант .... Кто-нибудь может помочь?

Обратите внимание, что я новичок в Unity.


person Adil.R    schedule 12.11.2017    source источник


Ответы (1)


Образец на самом деле не предназначен для скрытия и отображения самолетов, поэтому вам нужно добавить пару вещей.

Во-первых, нет коллекции GameObject, представляющей плоскости ARCore. Самый простой способ сделать это - добавить тег к игровым объектам:

В редакторе Unity найдите префаб TrackedPlaneVisualizer и выберите его. Затем в инспекторе свойств откройте раскрывающийся список Тег и добавьте тег с именем plane.

Далее в методе обработчика Toggle нужно найти все игровые объекты с тегом «plane». Затем получите компоненты Renderer и TrackedPlaneVisualizer и включите или отключите их с помощью переключателя. Вам нужно сделать оба компонента; средство визуализации рисует плоскость, а TrackedPlaneVisualizer повторно включает средство визуализации (в идеале он будет учитывать состояние средства визуализации).

    public void OnTogglePlanes(bool flag) {
        showPlanes = flag;
        foreach (GameObject plane in GameObject.FindGameObjectsWithTag ("plane")) {
            Renderer r = plane.GetComponent<Renderer> ();
            TrackedPlaneVisualizer t = plane.GetComponent<TrackedPlaneVisualizer>();
            r.enabled = flag;
            t.enabled = flag;
        }
    }

Вы также можете сделать то же самое, когда создается экземпляр GameObject, поэтому новые плоскости учитывают переключатель.

person Clayton Wilkinson    schedule 13.11.2017
comment
Ранее я реализовал GameObject (т.е. PlaneWrapper) и сделал следующее: Instantiate(plane, Vector3.zero, Quaternion.identity, PlaneWrapper.transform). Таким образом я могу просто установить PlaneWrapper.SetActicve([true|false]). Любопытно, а какая разница в накладных расходах? - person Daevin; 05.02.2018
comment
Большая разница в том, что SetActive управляет всеми скриптами объекта, тогда как если вы просто включаете / отключаете рендеринг, другие скрипты продолжают работать. По моему личному мнению, это ошибка в TrackedPlaneVisualizer, но она повторно включает средство визуализации при изменении сетки вместо проверки состояния средства визуализации. - person Clayton Wilkinson; 05.02.2018
comment
@ClaytonWilkinson, а что, если я хочу, чтобы был виден только определенный самолет? Можете ли вы предложить альтернативный метод для достижения этой цели? Если я нажимаю на обнаруженную плоскость на экране, пусть визуализируется только эта плоскость, скрывая все другие обнаруженные плоскости. - person NightFury13; 05.04.2019
comment
Самый простой подход - сохранить переменную-член выбранной плоскости и при зацикливании установить enabled = true, если плоскость == выбранная плоскость. - person Clayton Wilkinson; 06.04.2019