unity3d - Как в Unity действия кнопки прикрепить к AR-объектам (ImageTarget)?


1

Есть несколько ImageTargetов, и в интерфейсе есть три кнопки, при нажатии играет звук (озвучивание на трех языках). Как можно прикрепить действие к ImageTarget? введите сюда описание изображения введите сюда описание изображения

Источник
  •  221
  •  2
  • 21 янв 2019 2019-01-21 05:12:07
Тоесть вы хотите, чтобы когда один из объектов, которые Вы рендерите, попал в центр экрана или определенную его область, он определялся, И менялись звуки? — 22 янв 20192019-01-22 03:43:06.000000
Когда через камеру находит один из объектов, например: Слон, и когда нажимаю на кнопки, должен на определенном языке озвучить (на якутском, русском, английском) и так далее. — 22 янв 20192019-01-22 00:19:10.000000
Действие проигрывания звука?, если честно из вопроса плохо понятно что у Вас не выходит — 21 янв 20192019-01-21 05:41:34.000000

2 ответа

0

В задаче есть один критически важный нюанс не указанный автором: Нужно тригерить только если мы смотрим на обьект некоторое время

иначе при повороте головы начнется творится лютая дичь т.к. затригерятся слишком многие обьекты подряд -- например, все 3 аудиозаписи начнут проигрыватся одновременно


опробуй следующий код:

    using UnityEngine;

    public class VrController : MonoBehaviour
    {
        //рисовать ли луч дебага и какой длинны
        public bool DrawRay = true;
        public int RayLength = 50;

        //время срабатывания в секундах
        public float TriggerTime = 1f;


        void Update()
        {
            GameObject objWeLookOn;

            //здесь делаются всякие реакции на взгляд на обьект
            if (CheckIfWeLookOnObject(out objWeLookOn))
            {
                Debug.Log("Im looking on" + objWeLookOn.name);
            }
        }

        private GameObject _lastObjWeLookedOn;
        private float _timeOfLook = 0;
        //метод возвращает тру если мы смотрим на обьект triggerTime времени и в аут запихивает сам обьект на который мы смотрим
        public bool CheckIfWeLookOnObject(out GameObject go)
        {
            RaycastHit hit;

            //рисуем луч в эдиторе если нужно для дебага
            //в рантайме видно не будет. 
            //Что бы было видно в рантайме используй lineRenderer компонет
            if (DrawRay)
            {
                Vector3 forward = transform.TransformDirection(Vector3.forward) * RayLength;
                Debug.DrawRay(transform.position, forward, Color.green);
            }

            //если ни на что не смотрим -- выходим из метода
            //и обнуляем сохраненные данные
            if (!Physics.Raycast(transform.position, transform.forward, out hit))
            {
                _timeOfLook = 0;
                _lastObjWeLookedOn = null;
                go = null;
                return false;
            }

            //Проверяем на какой обьект мы смотрим
            var currObj = hit.transform.gameObject;

            //если это новый обьект, обнуляемся
            if (_lastObjWeLookedOn != currObj)
            {
                _timeOfLook = 0;
                _lastObjWeLookedOn = currObj;
            }

            //если прошел период времени -- возвращаем тру и геймобджект на который смотрим
            if (_timeOfLook > TriggerTime)
            {
                go = hit.collider.gameObject;
                _timeOfLook = 0;
                return true;
            }

            //иначе - возвращаем ничего, но считаем время т.к. мы продолжаем смотреть на этот же обьект
            go = null;
            _timeOfLook += Time.deltaTime;
            return false;
        }
    }

Вешаешь этот скрипт себе на камеру. В случае VR это две камеры... Повесь только на родительский обьект по отношению к камерам. Или на одну из них. Особой роли это сыграть не должно.

Потом заменяй вывод в лог имени обьекта на нужное действие. Хоть проигрывание музыки, хоть любое другое.

  • 22 янв 2019 2019-01-22 12:26:57
0

Звуки не привязывал, т.к. не в звуках же вопрос, разбираемся как определить на что смотрит игрок:

Я написал 2 скрипта, один развесил по объектам сцены и заполнил текст разными строками, так же на эти объекты я повесил BoxCollider

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RaycastSound : MonoBehaviour {
    public string language;
    public string sound;
}

Второй скрипт я повесил на камеру.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class RaycastPalyer : MonoBehaviour {

	RaycastSound prev;

	void Update () {

		RaycastHit hit;

		if (!Physics.Raycast (transform.position, transform.forward, out hit))
			return;

		RaycastSound sound = hit.collider.GetComponent<RaycastSound> ();

		if (sound == prev)
			return;
		
		prev = sound;

		if (null == sound)
			return;
		
		Debug.Log(sound.language); 
		Debug.Log(sound.sound); 

	}
}

Тут всю работу делает метод Physics.Raycast он пускает луч от камеры в направлении сцены и возвращает объект, содержащий информацию о пересечении этого луча с первым активным коллайдером, в который он упрется

В результате, когда камера смотрит на объект, в консоль выводится текст, из скриптов, которые я добавил к объектам сцены.