Триггеры


photo

Recommended Posts

Собираю всю информацию о триггерах.

На момент версии 2.12 есть три типа триггеров:

1) WorldTrigger

2) NodeTrigger

3) PhysicalTrigger

 

World Trigger 

Документация WorldTrigger, WorldTrigger Class.

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

Алгоритм:

Важно! Если вы будете работать с триггером из скрипта, то поля Enter Callback / Leave Callback должны оставаться пустыми!

1) Создаете на сцене (World) WorldTrigger

2) На него кидаете скрипт WorldTriggerComponent

3) На объекте (нодах) который должен взаимодействовать с триггером ставите галочку Triggers Interaction которая находится в поле Node

Внимание! Исходя из пояснений vvvaseckiy, следует следующее (правленая цитата):

World Trigger по вертикали должен соответствовать размеру баунд бокса объекта на который должен реагировать триггер, т.к. иначе он никогда не попадает в World Trigger. Опция Touch, позволяет фиксировать пересечение объема триггера с Bounding Box ноды даже в случае частичного пересечения этих объемов (по умолчанию фиксируются только полные вхождения Bounding Box в триггер).

Иначе говоря, если вы создали куб 1*1*1, то для того чтобы сработал триггер, триггер должен быть больше по размеру чем ваш куб. Поскольку триггер среагирует только тогда, когда ваш куб будет полностью помещен в триггер. Для того чтобы обрабатывались пересечения поверхностей объекта и триггера, необходимо у триггера включитьTouch.

Внимание! (далее цитата) 

11 hours ago, stockyspark said:

World Trigger обнаруживает объекты по Bounding Box. Дело в том, что вы поставили галочку Triggers Interaction у родительского элемента Node Reference. У него нет Bounds. Чтобы World Trigger корректно реагировал на входящие и выходящие из него объекты, у этих объектов должна быть включена галочка Triggers Interaction (в вашем случае это объекты ObjectMeshStatic). См. прикрепленное ниже видео. Мы добавим об этом заметку в документацию. Также в следующей версии редактора эта галочка уберется у объектов, у которых нет Bounds.

 

Дублирую сообщения и скрипт из Удочерить нод для стандартного FPS.:

On 9/2/2020 at 8:15 AM, karpych11 said:

Здравствуйте!

Функции из полей Enter Callback / Leave Callback вызываются в скрипте на UnigineScript, который настроен для текущего мира. Чтобы настроить вызов коллбеков триггера для методов компонент необходимо их добавить в коде через AddEnterCallback / AddLeaveCallback. Простой пример есть в прикрепленной компоненте. Добавьте её на любой WorldTrigger в мире. Также не забудьте про включенный флаг Triggers Interaction у тех нод, на которые должен реагировать триггер. При запуске приложения будет визуализироваться сам триггер, а в консоль будут выводиться сообщения при вызове коллбеков.

WorldTriggerComponent.cs 772 B · 5 downloads

Скрипт (поправленный):

Spoiler

using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

[Component(PropertyGuid = "Ваш ID скрипта")]
public class WorldTriggerComponent : Component
{
	private WorldTrigger trigger = null;

	private void Init()
	{
		if (Unigine.Console.GetInt("show_messages") == 0)
			Unigine.Console.SetInt("show_messages", 1);

  		Log.Message("Enabled Log. show_messages = {0} \n", Unigine.Console.GetInt("show_messages"));
  
  		Unigine.Console.Run("show_visualizer 1");
  
  		Log.Message("We turned on the console");

		Log.Message("Testing started WorldTrigger. Script on the object = {0} \n", node.Name);

		trigger = node as WorldTrigger;
		if (!trigger)
		{
			Log.Error("WorldTriggerComponent error: can't cast node to WorldTrigger\n");
			return;
		}
		else
		{
			Log.Message("Trigger found and converted = {0} \n", trigger.Name);
		}

		Log.Message("Adding Callback. trigger = {0} \n", trigger.Name);

		trigger.AddEnterCallback(OnEnter);
		trigger.AddLeaveCallback(OnLeave);

		Log.Message("Turn on visualization. trigger = {0} \n", trigger.Name);
		Visualizer.Enabled = true;
	}
	
	private void Update()
	{
		if (!trigger)
			return;

		trigger.RenderVisualizer();
	}

	private void OnEnter(Node n)
	{
		Log.Message($"Trigger fired {trigger.Name}. OnEnter: {n.Name}\n");
	}

	private void OnLeave(Node n)
	{
		Log.Message($"Trigger fired {trigger.Name}. OnLeave: {n.Name}\n");
	}
}

 

 

Node Trigger

Честно говоря слабость документации и практически тотальное отсутствие примеров уже начинает вызывать головную боль. Обратите внимание что версия странички 2.12 не содержит гифку куда пихать этот триггер. Trigger 2.12.  Гифка тут - Triggers 2.6.1, NodeTrigger Class.

Это пожалуй самый странный триггер который я когда либо видел. Можно предположить что это что-то типа mesh триггера, но нет. Не имеет вызова LeaveCallback, но зато реагирует на смену позиции что кстати очень оригинально и может быть весьма полезно, если бы... Это был обычный триггер. Должен быть прописан Unigine script:

Quote

Функции обратного вызова enabled и position должны быть реализованы в мировом скрипте.

Функция обратного вызова также может принимать 2 дополнительных аргумента . Однако вы можете установить такие обратные вызовы только через код. Через UnigineEditor вы можете указать только функции обратного вызова, которые получают 0 или 1 в качестве аргумента.

 Сложно представить зачем он вообще такой нужен. В документации что-то говорится о молнии и громе, что странно - если я сам же создаю молнию, в чем проблема мне же создать звук грома? Разве что если молния ударит в предмет, то воспроизвести звук взрыва или что там произойдет. В общем, будем надеяться на комментарии разработчиков.

 

Physical Trigger

Пожалуй наиболее полная информация в документации среди существующих триггеров. Правда, до скрипта который будет представлен ниже берущий за основу скрипт представленный выше, там конечно еще не дошли. Так же традиционное тотальное отсутствие примеров для каждого свойства/метода, но есть таки целых три примера с кодом - основной и для вызовов. Очевидно это по тому что этот тип триггеров относительно молодой (первая версия документации о нем датируется версией 2.2), так что разработчики уделили внимание как с ним работать более полно. Итак ссылки - Physical TriggerPhysicalTrigger Class.

Алгоритм в общем такой же как и у WorldTrigger, с небольшими отличиями.

Важно! Если вы будете работать с триггером из скрипта, то поля Enter Callback / Leave Callback должны оставаться пустыми! Объекты без физики с этим триггером не реагируют (немного не понятно зачем такое разделение на физику и без, однако разработчикам виднее).

Внимание! Возвращаемое значение Body. К примеру если вы напишите - void OnEnter(Body n),  а затем n.Name, то вам вернет имя не объекта (objeck.Name), а судя по всему имя из поля Physic.

Алгоритм:

1) Создаете на сцене (World) PhysicalTrigger

2) На него кидаете скрипт PhysicalTriggerComponent приведенный ниже

Здесь не нужно на объекте (нодах) который должен взаимодействовать с триггером ставить галочку Triggers Interaction которая находится в поле Node

Внимание! Любопытно, что 

void OnEnter(Body n)
{
	Log.Message($"Call OnEnter of PhysicalTrigger. node.Name: {node.Name}\n"); //вернет имя триггера
	Log.Message($"Call OnEnter of PhysicalTrigger. node.ObjectBody.Object.Name: {node.ObjectBody.Object.Name}\n");  //вернет имя объекта в котором этот триггер
	Log.Message($"Call OnEnter of PhysicalTrigger. n.Object.Name: {n.Object.Name}\n"); //вернет имя объекта попавшего в триггер
	Log.Message($"Call OnEnter of PhysicalTrigger. n.Object.Parent.Name: {n.Object.Parent.Name}\n"); //вернет имя родителя объекта попавшего в триггер
	Log.Message($"Call OnEnter of PhysicalTrigger. n.Parent.Name: {n.Parent.Name}\n"); //вернет ошибку 'Object reference not set to an instance of an object.'
}

 

Скрипт:

Spoiler

using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

[Component(PropertyGuid = "Ваш ID script")]
public class PhysicalTriggerComponent : Component
{
	private PhysicalTrigger trigger = null;

	private void Init()
	{
      	if (Unigine.Console.GetInt("show_messages") == 0)
      		Unigine.Console.SetInt("show_messages", 1);
  
  		Log.Message("Enabled Log. show_messages = {0} \n", Unigine.Console.GetInt("show_messages"));
  
  		Unigine.Console.Run("show_visualizer 1");
  
  		Log.Message("We turned on the console");
  
		Log.Message("Testing started PhysicalTrigger. Script on the object = {0} \n", node.Name);

		trigger = node as PhysicalTrigger;

		if (!trigger)
		{
			Log.Error("PhysicalTriggerComponent error: can't cast node to PhysicalTrigger \n");
			return;
		}
		else
		{
			Log.Message("Found PhysicalTrigger = {0} \n", trigger.Name);
		}
      
		Log.Message("Adding Callback. trigger = {0} \n", trigger.Name);
		trigger.AddEnterCallback(OnEnter);
		trigger.AddLeaveCallback(OnLeave);
	
		Log.Message("Turn on visualization. trigger = {0} \n", trigger.Name);
		Visualizer.Enabled = true;
	}
	
	private void Update()
	{
		if (!trigger)
			return;

		trigger.RenderVisualizer();
	}

	private void OnEnter(Body n)
	{
		Log.Message($"Call OnEnter of PhysicalTrigger. Body: {node.Name}\n");
	}

	private void OnLeave(Body n)
	{
		Log.Message($"Call OnLeave of PhysicalTrigger. Body: {node.Name}\n");
	}
}

 

Что еще выяснилось по ходу.

Ошибка в синтаксисе Unigine.Console.Run("show_visualizer 1"); (я вместо show_visualiZer , написал show_visualiSer) привела к тому что не работал trigger.RenderVisualizer();

Из-за того что у меня раскладка клавиатуры менялась на Ё (~), не открывалась консоль. Заморочки Виндоса уже - сначала меняется раскладка и только при зажатии клавиши проходит нажатие кнопки и открывается консоль. Кто-бы мог подумать.

Edited by nikolay.sykharev
Link to post

Привет, nikolay.sykharev

Спасибо за ваш интерес к тригерам.

Хотелось бы немного прояснить про World Trigger. За взаимодействие ноды с этим триггером отвечает чекбокс Triggers Interaction. Здесь не важно есть ли у ноды Body и Shape (физический ли объект или нет). Взаимодействие рассчитывается с помощью Bounding Box. Также обратите внимание на наличие чекбокса Touch, который позволяет фиксировать пересечение объема тригера с Bounding Box ноды даже в случае частичного пересечения этих объемов (по умолчанию фиксируются только полные вхождения Bounding Box в тригер).

Мы планируем и дальше улучшать документацию, в том числе и на основе ваших впечатлений о ней.

Link to post
9 hours ago, stockyspark said:

Здесь не важно есть ли у ноды Body и Shape (физический ли объект или нет)

Это очень странно, потому что у меня World Trigger, объекты с физикой напрочь игнорировал. Я могу за это поручиться, поскольку алгоритм был следующий:

1) Создаю триггер

2) Добавляю ему компонент скрипта

3) Проверяю работу с объектом на который должен реагировать триггер (работает)

4) Добавляю физику объекту на который ранее триггер реагировал

4) Проверяю работу (не работает)

5) Убираю физику

6) Проверяю работу (не работает)

7) Создаю новый объект который должен реагировать с триггером без физики

8) Проверяю работу (работает)

Link to post

Здравствуёте Николай,

У нас сходу не получилось воспроизвести проблему с отсутсвием реакции триггера на объекты с физикой. С WorldTrigger и обычным примитивом с BodyRigid всё работает нормально. Может дело в каких-то дополнительных параметрах сцены, или спецефичной настройкой физики. Если есть возможность - прикрепите, пожалуйста, минимальную тестовую сцену в которой триггер не срабатывает. 

Спасибо

Link to post
On 9/28/2020 at 12:21 PM, vvvaseckiy said:

прикрепите, пожалуйста, минимальную тестовую сцену в которой триггер не срабатывает. 

Это удивительно, но я трижды создавал глюченные новые тестовые проекты. Судя по всему если удалить world который создается по умолчанию и так же назвать вновь созданный, то движок начинает глючить. В первом случае у меня не отображались публичные переменные, во втором не срабатывала строка trigger.RenderVisualizer();

Затем я так и не смог заставить работать консоль и вывод лога. И что удивительно сам ворлдтриггер.

В общем устал я бороться со всем этим, прикрепляю все четыре проекта

Test_trigger.rar Test_triiger_2.rar Test_Trigger_3.rar Test_Trigger_4.rar

Link to post

Николай,

В проектах с первого по третий размер World Trigger по вертикали не соответсвует размеру баунд бокса падающего кубика. Т.е. кубик в действительности никогда не попадает в World Trigger. Если же увеличить размер триггера или включить опцию Touch у World Trigger, то он начинает корректно работать, в т.ч. с объектами с физикой. Опция Touch, позволяет фиксировать пересечение объема тригера с Bounding Box ноды даже в случае частичного пересечения этих объемов (по умолчанию фиксируются только полные вхождения Bounding Box в тригер).

 

Quote

В первом случае у меня не отображались публичные переменные



Если я правильно понимаю речь идёт об IntelliSense в IDE? Какие именно переменные не отображались?

 

On 10/17/2020 at 4:08 AM, nikolay.sykharev said:

во втором не срабатывала строка trigger.RenderVisualizer();

Вроде бы во всех проектах визуалайзер отображается, за исключением четвертого где эта строка закомментированна. Обратите внимание что Visualizer может не отображатся из за глобальной настройки Visualizer для всех объектов.

 

On 10/17/2020 at 4:08 AM, nikolay.sykharev said:

Затем я так и не смог заставить работать консоль и вывод лога. И что удивительно сам ворлдтриггер.

Если речь о четвертом проекте, то в нём у падающих фигур отключена опция Triggers Interaction. Если её включить, то триггер работает.

 

  • Like 1
Link to post
On 10/19/2020 at 9:08 AM, vvvaseckiy said:

Если я правильно понимаю речь идёт об IntelliSense в IDE? Какие именно переменные не отображались?

Нет. Это которые я делаю public и они должны появиться в поле node components and... в самом движке. Тут уже были темы с подобными проблемами.

On 10/19/2020 at 9:08 AM, vvvaseckiy said:

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

Ну а у меня не отображались в описанных случаях. Закоментил я ее по тому что лог тоже не выводился, вот решил так попробовать увидеть реакцию на триггер. Четвертый я хотел сделать с физическим триггером, но поскольку лог не выводится, плюнул уже на это все - и так два часа псу под хвост.

Вообще я ни как не могу понять от чего зависит работа Log.Message. В основном проекте он работает. Стоит создать новый world - не работает. Запускаешь основную сцену, работает во всем проекте. Создаешь новый проект - не работает. Честно говоря для меня до сих пор загадка, как лог у меня начал работать. Консоль тоже не открывается.

On 10/19/2020 at 9:08 AM, vvvaseckiy said:

В проектах с первого по третий размер World Trigger по вертикали не соответсвует размеру баунд бокса падающего кубика. Т.е. кубик в действительности никогда не попадает в World Trigger. Если же увеличить размер триггера или включить опцию Touch у World Trigger, то он начинает корректно работать

Просто сделайте толковые туториалы. И кстати в документации я не нашел trigger.RenderVisualizer();. 

 

Есть ли возможность сделать MeshTrigger?

Link to post
On 10/21/2020 at 4:57 AM, nikolay.sykharev said:

Нет. Это которые я делаю public и они должны появиться в поле node components and... в самом движке.

Попробуйте обновится на релиз 2.12 SDK. Мы значительно улучшили работу компонент в этом релизе

 

On 10/21/2020 at 4:57 AM, nikolay.sykharev said:

Вообще я ни как не могу понять от чего зависит работа Log.Message. В основном проекте он работает. Стоит создать новый world - не работает. Запускаешь основную сцену, работает во всем проекте. Создаешь новый проект - не работает. Честно говоря для меня до сих пор загадка, как лог у меня начал работать. Консоль тоже не открывается.

 

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

 

 

On 10/21/2020 at 4:57 AM, nikolay.sykharev said:

Просто сделайте толковые туториалы.

У нас буквально вчера вышел краткий видеогайд по WorldTrigger:

 

On 10/21/2020 at 4:57 AM, nikolay.sykharev said:

И кстати в документации я не нашел trigger.RenderVisualizer();. 

Trigger наследует метод RenderVisualizer() от класса Node

 

On 10/21/2020 at 4:57 AM, nikolay.sykharev said:

Есть ли возможность сделать MeshTrigger?

Что в вашем понимании должен делать этот обьект?

Link to post

 

9 hours ago, vvvaseckiy said:
14 hours ago, nikolay.sykharev said:

Есть ли возможность сделать MeshTrigger?

Что в вашем понимании должен делать этот обьект?

Такой же триггер, но с сеткой mesh'а какой нибудь модели. Обычно нужен для того что бы не настраивать триггеры под размеры объектов на сцене, коих может быть не одна сотня.

 

Сделал новый проект, хорошо, вроде лог в IDE заработал, а вот триггер по прежнему работать с физическими объектами отказывается. И почему то не работает RenderVisualizer. До кучи, выводятся только сообщения из OnLeave, из Init выводиться не хотят. Консоль не открывается. Записал видео, архив и проект прикрепил.

 

PS

Я не могу редактировать свои посты, только удалить. Что-то у меня все не слава Богу...

Unigine_project.rar

Link to post
On 10/21/2020 at 7:12 PM, nikolay.sykharev said:

 

Такой же триггер, но с сеткой mesh'а какой нибудь модели. Обычно нужен для того что бы не настраивать триггеры под размеры объектов на сцене, коих может быть не одна сотня.

 

Сделал новый проект, хорошо, вроде лог в IDE заработал, а вот триггер по прежнему работать с физическими объектами отказывается. И почему то не работает RenderVisualizer. До кучи, выводятся только сообщения из OnLeave, из Init выводиться не хотят. Консоль не открывается. Записал видео, архив и проект прикрепил.

 

PS

Я не могу редактировать свои посты, только удалить. Что-то у меня все не слава Богу...

Unigine_project.rar 316.84 MB · 2 downloads

Добрый день, nikolay.sykharev

Я посмотрел ваш проект. 

  • У вас опечатка в консольной команде, которая включает Visualizer: 
Unigine.Console.Run("show_visualiser 1"); -> Unigine.Console.Run("show_visualizer 1");
  • Консоль в райнтайме запускается по нажатию на клавишу тильда (~).

image.png

  • Как видите, ваши сообщения из Init выводятся корректно. 
  • World Trigger обнаруживает объекты по Bounding Box. Дело в том, что вы поставили галочку Triggers Interaction у родительского элемента Node Reference. У него нет Bounds. Чтобы World Trigger корректно реагировал на входящие и выходящие из него объекты, у этих объектов должна быть включена галочка Triggers Interaction (в вашем случае это объекты ObjectMeshStatic). См. прикрепленное ниже видео. Мы добавим об этом заметку в документацию. Также в следующей версии редактора эту галочку уберем у объектов, у которых нет Bounds. Приносим извенения за неудобства и неоднозначности.

Надеюсь это вам пригодится.

  • Like 1
Link to post
5 hours ago, stockyspark said:

Я посмотрел ваш проект. 

  • У вас опечатка в консольной команде, которая включает Visualizer: 


Unigine.Console.Run("show_visualiser 1"); -> Unigine.Console.Run("show_visualizer 1");
  • Консоль в райнтайме запускается по нажатию на клавишу тильда (~).

Ага, спс. Почему-то не нашел в документации команды для Run, переписывал с видео. Разобрался с консолью. Оказывается у меня она не открывалась потому что на Ё у меня сменялся язык ввода. В общем получается что при нажатии на нее у меня меняется сначала язык, а при продолжительном нажатии, срабатывает сама кнопка.

Кстати не корректная работа trigger.RenderVisualizer();, тоже была связана с этой "show_visualiser" ошибкой. Любопытно.

Да, триггер теперь работает корректно. Только что то я не могу редактировать первое сообщение чтобы внести новую информацию в первый пост. Вроде раньше была кнопка edit.

Edited by nikolay.sykharev
Link to post
Quote

 Только что то я не могу редактировать первое сообщение чтобы внести новую информацию в первый пост. Вроде раньше была кнопка edit.

А сейчас есть?

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post
3 hours ago, silent said:

А сейчас есть?

Ага, появилась. Спасибо)

Link to post

 

On 10/21/2020 at 5:12 PM, nikolay.sykharev said:
On 10/21/2020 at 6:58 AM, vvvaseckiy said:
On 10/21/2020 at 2:57 AM, nikolay.sykharev said:

Есть ли возможность сделать MeshTrigger?

Что в вашем понимании должен делать этот обьект?

Такой же триггер, но с сеткой mesh'а какой нибудь модели. Обычно нужен для того что бы не настраивать триггеры под размеры объектов на сцене, коих может быть не одна сотня.

Дублирую вопрос. Так есть ли возможность использовать сетку меша для триггера?

Link to post

Меш триггеры пока не планируются. Там много потенциальных подводных камней (в том числе и с производительностью).

Если нужно точно "пощупать" какой-то отбъект по его сетке, лучше использовать Intersrction для этого.

  • Like 2

How to submit a good bug report
---
FTP server for test scenes and user uploads:

Link to post