Страницы

Поиск по вопросам

вторник, 31 декабря 2019 г.

Как в Unity вызывать действие, если камера направляется на некий обьект (например ImageTarget)?

#c_sharp #unity3d #vuforia


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


    


Ответы

Ответ 1



В задаче есть один критически важный нюанс не указанный автором: Нужно тригерить только если мы смотрим на обьект некоторое время иначе при повороте головы затригерятся слишком многие обьекты подряд -- например, все 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("I'm looking on" + objWeLookOn.name); } } //эти 2 переменные я разместил именно здесь, а не выше потому, что они //используются только в этом методе. Если бы использовались еще где-то //я бы разместил их над всеми методами 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; } } Вешаешь этот скрипт себе на камеру вуфории. Потом заменяй вывод в лог имени обьекта на нужное действие. Хоть проигрывание музыки, хоть любое другое.

Ответ 2



Звуки не привязывал, т.к. не в звуках же вопрос, разбираемся как определить на что смотрит игрок: Я написал 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 (); if (sound == prev) return; prev = sound; if (null == sound) return; Debug.Log(sound.language); Debug.Log(sound.sound); } } Тут всю работу делает метод Physics.Raycast он пускает луч от камеры в направлении сцены и возвращает объект, содержащий информацию о пересечении этого луча с первым активным коллайдером, в который он упрется В результате, когда камера смотрит на объект, в консоль выводится текст, из скриптов, которые я добавил к объектам сцены.

Комментариев нет:

Отправить комментарий