Полезное

Мы Вконтакте

Discord канал

#
Пред.
Модератор: icms
Аватара пользователя
Пользователь
Сообщения: 469
В связи практически с полным отсутствием уроков и доков по данному вопросу, решил поделиться тем до чего дошёл сам.
Видео уроки на нашем сайте и в ютюбе давно устарели либо вообще как показала практика не совсем верны.
Все ниже изложенное актуально для версии 4.11

Сделал урок в текстово-графическом виде так как считаю видео менее информативным и удобным.

С помощью приведённых ниже методов вы сможете передавать переменные из одного BP в другой. А также вызывать функции в другом блюпринте.
Рассматриваемые способы коммуникации это: прямое общение блюпринтов(Direct Blueprint Communications), интерфейсы блюпринтов(Blueprint Interface).
1. Вызов функции и передача переменной из одного блюпринта в другой.

Самый на мой взгляд простой и удобный способ.
1.1

Изображение

Используем функцию Get All Actors Of Class, указываем в ней целевой блюпринт (у меня BP2) и вуаля - вызываем функцию ChangeZ из другого блюпринта. Напрямую передать или задать переменную таким способом у меня не получилось, но ведь ни кто не мешает передать данные как аргумент функции.(в функции ChangeZ аргумент Position).

Следует обратить внимание на то что данный способ обращается сразу ко всем объектам имеющий данный блюпринт. Если необходимо обратится лишь к одному экземпляру используем данный способ. Указываем в индексе номер нужного нам объекта.

Изображение


1.2

Изображение

Это несколько иной способ который именуется разработчиками как Direct Blueprint Communications. Мы всё также вызываем функцию из второго блюпринта и целью(target) в ней указываем переменную тип у которой указан типом целевого блюпринта.

Изображение

Т.е. нужно создать в нашем блюпринте BP 1 переменную и указать ей тип второго блюпринта BP 2 и эту переменную мы и цепляем к target.
Не забываем сделать её Public(открыть напротив переменной глаз).

Но это к сожалению ещё не всё что нужно сделать. Переменную нужного типа мы создали, но она просто унаследовала тип и не получила ссылку на конкретный экземпляр класса. Чтобы это реализовать переходим в основное окно редактора, выбираем наш блюпринт в котором создали переменную и в закладке Details - Defoult видим нашу переменную. Нажимаем пипетку справа и указываем на сцене нужный нам объект со вторым, целевым блюпринтом. Можно просто воспользоваться выпадающим списком.

Изображение

Этим способом можно напрямую задавать значение переменной в целевом блюпринте.

Изображение

Здесь мы задаём переменную Var Text dj втором блюпринте и в нём же вызываем функцию печати с аргументом.

Использование интерфейсов для таких простых задач наверное избыточно, по этому я решил не использовать их.

2. Общение между виджетом UMG и блипринтом(двухстороннее).

Цитата:
Частный вариант способа описанного выше для виджетов.
Если нужно отправить получить данные виджету в том же блюпринте где он создаётся гораздо удобнее использовать такой способ, работает и в левел блюпринте и в своих тоже.

Изображение

т.е. вытягиваем связь из create widget и получаем доступ к любым переменным и функциям виджета.



Более замороченный вариант(но тоже имет право на жизнь).

Тут немного менее удобно.
Сначала рассмотрим обращение со стороны виджета.
Полностью работает вариант 1.1 изложенный выше.

Изображение

В моём виджете есть Slider по изменению которого вызывается событие. Тут мы тоже вызываем функцию и передаём ей значение переменной.

Вариант 1.2 заставить работать мне не удалось так как я не смог указать конкретный экземпляр блюпринта(то что мы делали с пипеткой и списком в основном окне редактора). Связано это с тем что виджет не находится на сцене и соответственно в панели World Outliner поэтому нельзя прямым способом указать на конкретный экземпляр бп.

Я обратил внимание на "двухстороннее" так как отправить переменную или вызвать функцию виджета из блюпринта предложенными выше способами не получилось ни как. И обратная связь от блюпринта к виджету реализована с помощью интерфейсов(Blueprint Interface).

Соответственно нужно создать блюпринт интерфейса с входными и выходными переменными(могут быть только одни).

Изображение

И указать его в Class settings виджета и блюпринта.

Изображение

Далее получаем все виджеты использующие интересующий нас интерфейс. Нужно его указать в Get All Widgets with interface. У меня интерфейс называется Bp Com.

Изображение

Обратите внимание что нужно использовать внешний вариант вызова интерфейса, он помечен конвертиком.


Использовать Get All Widgets Of Class не получилось т.к. найденные виджеты не удалось указать как target при вызове функции.

И завершающим этапом нужно обработать вызов интерфейса, это очень просто!
Для этого просто кликните в бп UMG на функцию вашего интерфейса.

Изображение

Тело этой функции и будет выполнятся при Interface Call. У меня это просто печать строки.
Изображение

Вот пожалуй и всё.
Проект качаем кому интересно здесь - https://cloud.mail.ru/public/KXay/8KpVmeuUd
Чего то я там начудил при попытках уменьшить размер, так что после запуска открываем карту direct_bp_communication ручками(дабл клик :))

Очень бы хотелось реализовать те варианты которые у меня не получились или просто прояснить с ними ситуацию.
Get All Widgets Of Class - не получается использовать найденные виджеты как target, хотя этот же способ отлично работает с блюпринтами типа actor. Из за чего приходится прибегать к использованию интерфейсов.

P.S. Не пинайте сильно изучаю UE4 около 2х месяцев да и то только в свободное от работы время.
_________________
Project SKIT
Последний раз редактировалось icms 22 май 2016, 13:37, всего редактировалось 5 раз(а).
Аватара пользователя
Пользователь
Сообщения: 261
Неявное преобразование не есть хорошо! Вот не помню как в 9 версии, позволяло ли неявно преобразовать actora к бп, может в 11 и разрешили, но стоит вам изменить ваш бп2 (удалить Change Z), то изменения предупреждения, что где-то что то будет работать не правильно не появится.

Что бы пример был понятен, надо видеть саму функцию( которая принимает массив любых актеров и чего-то с ними делает).
Так что от каста отказываться рано.
Работать с массивом актеров уровня чаще всего приходится только во время его создания( зачем опрашивать всех в самой игре? Хотя может где иногда и пригодится как костыль, что бы не переделывать)

С указателем внутри объекта более-менее.

А так зря на старые уроки, они актуальны до сих пор, хоть и не все удачные примеры там, но суть показывают.
Аватара пользователя
Пользователь
Сообщения: 469
Не совсем понял где у меня неявное преобразование, Miha15z поясните пожалуйста. Насчёт каста, не спорю, но для вызова функций и передачи значений его использовать нелогично. Другое дело использовать его по назначению например получать доступ статик мешу или плееру, что бы изменять его внутренние свойства без дополнительных внешних костылей. И к стате описанная мной система это не костыль это офф способы взаимодействия. Вот отсюда https://docs.unrealengine.com/latest/INT/Engine/Blueprints/UserGuide/BlueprintComms/index.html я просто это представил в более доступном виде именно для коммуникации 2 блюпринтов не относящихся к актору.
_________________
Project SKIT
Аватара пользователя
Пользователь
Сообщения: 261
Да это способ взаимодействия, но какой ценой, перебора всех актеров уровня(относительно первого варианта), а если у вас 2 и более и вам надо ток к 1 обратится.
Что делает и что должна принимать функция Change Z? И к кому она относится?
В 1.1 в качестве бп2 может быть что угодно, не обязательно правильно взаимодействующее с Change Z( другое дело если просто координату читать, а она есть у всех объектов actor)

Про способ 1,2 вопросов нет, он применим в определенных ситуациях.
Аватара пользователя
Пользователь
Сообщения: 469
Miha15z замечание
Цитата:
а если у вас 2 и более и вам надо ток к 1 обратится

абсолютно обосновано, спасибо сразу не обратил внимания.Поправлю в статье.
Насчёт перебора всех объектов на сцене - это совсем не нагрузка для движка по сравнению даже с самой малой анимацией, не говоря уже о том что событие происходят не в Event Tick.

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

Изображение

Таким образом удобно получать доступ не используя куски кода(блюпринта) для каждого объекта, а просто указывая индекс нужного объекта. Возможно ли такое провернуть с кастом?
_________________
Project SKIT
Аватара пользователя
Пользователь
Сообщения: 44
А как вызвать из Виджета в левелблюпринт??? есть какие нибудь способы саsta в роде нету такого. Мне риходится Через эвентик и переменную внутри виджета делать, что является полным ппц.
Аватара пользователя
Пользователь
Сообщения: 469
Цитата:
А как вызвать из Виджета в левелблюпринт??? есть какие нибудь способы саsta в роде нету такого. Мне риходится Через эвентик и переменную внутри виджета делать, что является полным ппц.

Работает способ с интерфейсами описанный выше.



Цитата:
Ты хуже гитлера.

Цитата:
)) если разберется с наследованием и полиморфизмами, может и поймет истинное назначение каста. Кстати переводится каст как "преобразовать к" ))

Авторам, не флудите и изучайте офф доки. Форуму по моему нужен модер вычищать весь этот пустой трёп. Сотни сообщений из которых 70% ни о чём , так просто чтобы отписаться.


p.s
Цитата:
полиморфизмами
улыбнуло.
_________________
Project SKIT
Аватара пользователя
Пользователь
Сообщения: 44
icms я так не понял как правильно из UMG на левелблупринт повлиять, но придумал кривой костыль который работает. из Umg идёт сигнал на Актёра(по твоему методу) этот актёр смещается на сцене на 100 единиц в Другого актёра, после столкновения срабатывает тригер -этот актёр возвращается обратно (на 100 единиц) и включает функцию нужная ( с проверками UMG). Хотя костыль кривой, но он всё таки меньше нагружает систему. А у тебя icms какие методы передачи с UMG в Blueprint, как упростить?
Аватара пользователя
Пользователь
Сообщения: 469
Тут всё просто!
Создаём блюпринт интерфейс. Указываем его в UMG и в LevelBlueprint (во вкладке ClassSettings).

Дальше пример с картинками :).
Blueprint Interface
Изображение

UMG вызов(в GetAllActorsWithInterface нужно указать в interface свой InterfaceBlueprint у меня BP com)

Изображение

Принимаем в LevelBlueprint (нужно кликнуть по функции интерфейса в левел блюпринте)

Что у нас получается?
Из UMG по клику кнопки делаем InterfaceCall( в моём случае с текстовым параметром), а в левел блюпринте его принимаем!!! И всё.

Не обязательно должен быть какой либо параметр, можно просто делать вызов и вызывать функцию или эвент в левел блюпринте.
Изображение

Эта схема проверенно работает и для коммуникации UMG (виджетов)
_________________
Project SKIT
Последний раз редактировалось icms 15 май 2016, 18:21, всего редактировалось 1 раз.
Аватара пользователя
Пользователь
Сообщения: 1297
Зачем делать getAllACtorWithInterface если и так есть референс на widget. А если у тебя сетевая игрушка и сам сервер хочет изменить твой UMG, делать через getAllACtorWithInterface не получится, только если не всем поменять.
_________________
Мои работы.
Youtube Channel
Форум по геймдеву.


Сейчас этот форум просматривают: Google [Bot] и гости: 23

UEngine.ru © 2017
Все права защищены. При копировании материалов с сайта, ссылка на первоисточник обязательна.
Яндекс.Метрика
Главная страница