Все взаимодействия в симуляторе построены на основе Unity XR Hands и Unity XR Interaction Toolkit. Meta SDK не используется в проекте. Всё взаимодействие происходит через XR Interaction Manager в случае взаимодействия руками с предметами, и XR UI Toolkit Manager в случае взаимодействия с Unity UIToolkit документами.
В проекте используется система синтетической и физической (трекинговой руки).
Физическая рука - это реальное положение руки и пальцев пользователя в пространстве. Она используется как управляющие сигналы для интеракторов, а также как ориентир, в который стремиться попасть синтетическая рука. Физическая рука невидима для пользователя.
Синтетическая рука - это визуальное отображение руки в VR. Она естественно не повторяет всё, что делает реальная рука. Она служит для того, чтобы показывать воздействие пользователя на виртуальный мир. Она может принимать определённые, заранее предзаписанные позы на предметах, имитировать усилие на воздействие, отставая от реальной руки. Когда вы нажимаете на кнопку и пока физическая рука проходит сквозь неё - синтетическая рука останется на этой самой кнопке.
На текущий момент проект использует следующие интеракторы:
Этот интерактор нужен, чтобы обрабатывать нажатия пальцев физической руки на заранее подготовленные предметы, в частности кнопки и UI на тачскрине ангиографа. В проекте используется дефолтный XRPokeInteractor, без модификаций.
Обработка визуального отклика идёт внутри драйвера синтетической руки. Для этого используется механика Hover, поэтому отключать Hover нельзя
Этот интерактор отвечает за дистанционное взаимодействие с UI. Он выглядит как луч, что появляется между пальцами при наведении на валидный объект.
Для взаимодействия с ним объект должен быть на слое UI_FarInteractive, чтобы избежать возможности удалённого управления тачскрином.
Это полностью самописный интерактор, который отвечает за физическое взаимодействие с миром путём щипка или захвата ладонью. В нём содержатся данные о позиции захвата, её ширине, а также синтетической руке, с которой он взаимодействует. Как правило, он уже настроен, и трогать его не нужно.
Если интеракторы - это то, что взаимодействует, то интерактаблы - это то, с чем они взаимодействуют.
В проекте используются следующие интеракторы:
Это интерактаблы, который работает с GrabInteractor. Он описывает взаимодействие руки с закреплёнными объектами, такими как элементы контрольной панели ангиографа (грибок, джойстики), а также дуги мониторов, за которые их можно двигать.
Сами они не воздействуют на предмет. Однако они передают события
OnGrabChangedв момент захвата или отпускания предмета, а такжеOnForceChanged, которая передаёт линейную и угловые силы, воздейстующие на объект. За воздействие на предмет отвечают драйверы.
Используются следующие виды контолов и драйверов
Это драйвер, которые превращает физическое воздейсвие в отклонение ручки джойстика. Можно задать вязкость ручки. Нужен для того, чтобы конвертировать воздействие руки пользователя в управляющий сигнал на драйверы моторов.
Joystick With Locked Axis Control отличается тем, что пока идёт воздействие на одну ось - вторая блокируется. Нужно для того, чтобы пользователь не мог подмешать управляющий сигнал, который он не хотел давать.
Это драйвер, который используется для разблокировки вращения стола. Нужно приложить усилие, чтобы повернуть переключатель, после чего он перемещается щелчком до конечной позиции. Когда усилие с него снято, он возвращается в первоначальное положение. Сигнал срабатывает один раз, при повороте.
With Fixation - эта версия также переключается щелчком, но в отличии от обычной переключатель остаётся в переключенном положении, когда пропадает усилие, и его нужно возвращать на место тем же усилием.
Этот драйвер используется для воздействия на грибок для перемещения стола. Прежде чем будет возможно перемещать стол, нужно утопить грибок вниз. Для этого данный контрол и используется. Нужно приложить усилие вдоль указанной оси, после чего контрол щелчком встаёт в конечную позицию и продолжает находиться там, пока рука его удерживает. При снятии усилия он возвращается на начальную позицию. Сигнал срабатывает два раза, при нажатии и при отпускании.
Это драйверы, которые позволяют проецировать воздействие пользователя на закреплённый объект по настроенной оси. Можно задавать максимальную скорость перемещения предмета по этой оси, а также лимиты движения по этой оси. Драйвер поворота работает аналогично.
Этот драйвер, которые получает управляющий сигнал и имитирует работу моторов. Этим драйвером можно управлять удалённо и выполнять действия, вроде возврата мотора в 0.
Эти драйверы используются на дугах ангиографа. Они отвечают за вращение объекта. Continuous версия не имеет лимитов и может вращаться бесконечно, обычная версия имеет лимиты.
Это драйвер линейного смещения. Он обязательно имеет лимиты. Используется этот драйвер для флэт детектора и механизма подъёма стола.
Этот интерактабл позволяет захватывать себя по всей длине сплайна. Кроме того, он поддерживает захват двумя руками и модифицирует ввод двух линейных или угловых сил рук, с учётом из позиции, выдавая один обработанный сигнал, который дальше может быть использован в Linear Hand Driver или Angular Hand Driver. На проекте этот интерактабл используется, чтобы двигать и поворачивать мониторы.
Этот интерактабл используется напрямую к предметам, которые можно переносить в руках. Это разные инструменты, шприцы и т.д. Он включает в себя как Kinematic перемещение этих предметов, так и PhysicsDriven, чтобы к примеру не ломать шланг в интродьюссере.
Отличительная черта этих предметов - рестрикторы.
Ввиду того, что предметы можно перемещать руками, потребовались некоторые ограничители, чтобы заставить предметы вести себя на сцене правильно. Для этого используются рестрикторы, которые воздействуют на предмет в руке или синтетическую руку, переопределяя их движение.
Это рестрикторы, которые ограничивают движение тела смещение по определённой оси или поворотом вокруг этой оси в пространстве другого предмета. При настройке Reaction на FreeBodyInteractable компоненте неприменённый остаток воздействия будет передаваться родителю.
Это группа рестрикторов, которые направляют предмет в заранее установленный сокет. Они отвечают за его движение, плавный ввод и движение по оси, если нужно, и различаются по логике парковки предмета в сокете
Этот рестриктор во время парковки создаёт Fixed Joint между объектами. Его прочность настраивается и его можно разорвать. Логика выхода из слота не применяется. Этот тип ограничителя используется для присоединения шприца к интродьюссеру, а впоследствиии и к катетеру.
Этот ограничитель после парковки парентит предмет к сокету. Это позволяет избегать визуального рассинхрона. Этот ограничитель применяется к примеру на Entry Wire и прочих простых объектах.
Этот рестриктор после парковки просто двигает объект за сокетом
Этот ограничитель заставляет ограничиваемое тело двигаться по сплайну. Там есть события парковки, когда объект достигает конечной позиции.
У каждого Interactable есть поле Attachement Config. В нём описываются правила применения поз и сами позы, доступные для данного предмета.
Правила захвата описываются в этих Scriptable Object. Они содержат в себе правила захвата для Pinch и Grab, а также доступные позы для левой и правой руки.
Это единичная записанная поза для конкретной руки. Она записывается в PlayMode на основе реального захвата. Пайплайн распишу позже. Также здесь можно задать тип захвата, Pinch или Grab, а также Режим захвата: Точная поза, Поза вокруг оси, Скольжение по оси. Режимы можно совмещать.