Как связать объекты в unity

Обновлено: 24.04.2024

В этой статье я хочу рассказать про физический компонент Fixed Joint.

Fixed Joint (Неподвижное соединение) — этот компонент связывает несколько объектов, ограничивая их движение, т.е. этот процесс похож на присвоение «родительскому» компоненту «дочернего», но реализуется все это при помощи физики.

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

Первым делом на все части моста мы добавим mesh collider и rigidbody, это наверно единственный минус Fixed Joint, в том что нужно на каждый объект добавить rigidbody.

Далее сам компонент, т.к. у нашего моста две стороны, к каждому объекту добавим по два Fixed Joint. Это нужно для того чтобы, все детали имели две точки связи между другими объектами и чтобы наш мост не развалился при начале игры.

Fixed Joint имеет не большое количество настроек:
Connected Body Необязательная ссылка на другой объект с Rigidbody, к которому присоединяется текущий объект. Если поле оставить пустым, объект присоединяется к заданной точке в пространстве.

Break Force Сила, которую требуется приложить к объекту, чтобы разорвать соединение.

Break Torque Крутящий момент, который необходимо приложить к объекту, чтобы разорвать соединение.

Enable Collision Если включено, два соединенных тела будут сталкиваться друг с другом.

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

Я думаю здесь ничего сложного, просто нужно не запутаться, какой объект к какому присоединять. Например у нас есть столбы, к ним указываем 2 каната сверху и снизу, к доскам привязываем также канаты, но уже левый и правый, а к самим канатам привязываем наши столбы с одного и с другого конца. Получается что при помощи Fixed Joint мы соединили все части моста в одно целое.

Вообще, этот компонент можно применять где угодно, например при использовании липких объектов или висячих, дверей, шестеренок и т.д. Так же можно указать пределы прочности связи между объектами, по умолчанию эти значения равны Infinity (бесконечность) в Break Force и Break Torque, если указать другие значения и сила которая будет действовать на объекты, выше этого значения, то соединение разорвется.

Ниже можете посмотреть результат подвесного моста с настроенными физическими свойствами при помощи компонента Fixed Joint. На этом все. Удачных проектов!

С помощью компонента Joint , вы можете добавить один rigidbody объект к другому или к фиксированной точке в пространстве. Обычно вы желаете, чтобы у сочленения была хоть какая-то свобода движения, так что Unity предоставляет различные Joint компоненты, реализующие разные ограничения. Например, Hinge Joint позволяет осуществлять вращение вокруг заданной точки и оси, в то время как Spring Joint держит объекты раздельно, но расстояние между ними может немного пружинить. Как обычно, названия 2D компонентов оканчиваются на 2D, например, Hinge Joint 2D.

For example, a Hinge Joint allows rotation around a specific point and axis while a Spring Joint keeps the objects apart but lets the distance between them stretch slightly.

2D joint components have 2D at the end of the name, eg, Hinge Joint 2D. See Joints 2D for a summary of the 2D joints and useful background information.

У сочленений также есть другие опции, которые можно включить для различных эффектов. Например, вы можете настроить сочленение так, чтобы оно разрывалось при применении к нему силы больше заданного порога. Некоторые сочленения также позволяют возникать движущей силе ( drive force ) между соединёнными объектами для автоматического приведения их в движение.

Дополнительную информацию о свойствах сочленений вы можете найти на страницах справки по соответствующим компонентам.

В редакторе Unity вы изменяете свойства Компонента используя окно Inspector. Так, например, изменения позиции компонента Transform приведет к изменению позиции игрового объекта. Аналогично, вы можете изменить цвет материала компонента Renderer или массу твёрдого тела (RigidBody) с соответствующим влиянием на отображение или поведение игрового объекта. По большей части скрипты также изменяют свойства компонентов для управления игровыми объектами. Разница, однако, в том, что скрипт может изменять значение свойства постепенно со временем или по получению ввода от пользователя. За счет изменения, создания и уничтожения объектов в заданное время может быть реализован любой игровой процесс.

Обращение к компонентам

В UnityScript синтаксис немного отличается:

Как только у вас есть ссылка на экземпляр компонента, вы можете устанавливать значения его свойств, тех же, которые вы можете изменить в окне Inspector:

Дополнительная возможность, недоступная в окне Inspector - вызов функций экземпляра компонента:

Имейте ввиду, что нет причины, по которой вы не можете иметь больше одного пользовательского скрипта, присоединенного к одному и тому же объекту. Если вам нужно обратиться к одному скрипту из другого, вы можете использовать, как обычно, GetComponent, используя при этом имя класса скрипта (или имя файла), чтобы указать какой тип Компонента вам нужен.

Если вы попытаетесь извлечь Компонент, который не был добавлен к Игровому Объекту, тогда GetComponent вернет null; возникнет ошибка пустой ссылки при выполнении (null reference error at runtime), если вы попытаетесь изменить какие-либо значения у пустого объекта.

Обращение к другим объектам

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

Связывание объектов через переменные

Самый простой способ найти нужный игровой объект - добавить в скрипт переменную типа GameObject с уровнем доступа public:

Переменная будет видна в окне Inspector, как и любые другие:


Теперь вы можете перетащить объект со сцены или из панели Hierarchy в эту переменную, чтобы назначить его. Функция GetComponent и доступ к переменным компонента доступны как для этого объекта, так и для других, то есть вы можете использовать следующий код:

Кроме того, если объявить переменную с доступом public и заданным типом компонента в вашем скрипте, вы сможете перетащить любой объект, который содержит присоединенный компонент такого типа. Это позволит обращаться к компоненту напрямую, а не через игровой объект.

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

Нахождение дочерних объектов

Иногда игровая сцена может использовать несколько объектов одного типа, таких как враги, путевые точки и препятствия. Может возникнуть необходимость отслеживания их в определенном скрипте, который управляет или реагирует на них (например, все путевые точки могут потребоваться для скрипта поиска пути). Можно использовать переменные для связывания этих объектов, но это сделает процесс проектирования утомительным, если каждую новую путевую точку нужно будет перетащить в переменную в скрипте. Аналогично, при удалении путевой точки придется удалять ссылку на отсутствующий объект. В случаях, наподобие этого, чаще всего удобно управлять набором объектов, сделав их дочерними одного родительского объекта. Дочерние объекты могут быть получены, используя компонент Transform родителя (так как все игровые объекты неявно содержат Transform):

Вы можете также найти заданный дочерний объект по имени, используя функцию Transform.Find:

Это может быть полезно, когда объект содержит дочерний элемент, который может быть добавлен или удален в игровом процессе. Хороший пример - оружие, которое может быть подобрано и выброшено.

Нахождение объектов по имени или тегу

Нахождение игровых объектов в любом месте иерархии доступно всегда, когда у вас есть некоторая информация, по которой их можно идентифицировать. Отдельные объекты могут быть получены по имени, используя функцию GameObject.Find:

Объект или коллекция объектов могут быть также найдены по их тегу, используя функции GameObject.FindWithTag и GameObject.FindGameObjectsWithTag:-

Компонент Fixed Joints (Неподвижное соединение) ограничивает движение определенного объекта, связывая его с другим объектом. Этот процесс похож на Parenting (определение текущего объекта как “дочерний” по отношению к другому, “родительскому”, объекту), но реализован с помощью физики, а не иерархии компонентов Transform. Чаще всего этот компонент используется в случае, если в определенный момент времени может потребоваться разъединить два объекта, или наоборот, соединить два объекта без необходимости изменения иерархии.


Свойства

Свойство: Функция:
Connected Body Необязательная ссылка на другой объект с Rigidbody, к которому присоединяется текущий объект. Если поле оставить пустым, объект присоединяется к заданной точке в пространстве.
Break Force Сила, которую надо применить к соединению, чтобы сломать его.
Break Torque Крутящий момент, который надо применить к соединению, чтобы сломать его.
Enable Collision Если включено, то включаются коллизии между телами связанными соединением.
Enable Preprocessing Disabling preprocessing helps to stabilize impossible-to-fulfil configurations.

Детали

При создании игр иногда возникают случаи, когда требуется, чтобы объекты двигались вместе (временно или постоянно). Компоненты Fixed Joint позволяют упростить реализацию подобных ситуаций, поскольку вам не приходится менять положение объекта в иерархии с помощью скриптов. Минус подобного решения в том, что вам придется добавлять компоненты Rigidbodies на объекты, которые требуется соединить с помощью Fixed Joint.

Например, с помощью этого компонента можно реализовать “липкую гранату”. Для этого нужно написать скрипт, позволяющий определить столкновение с другим объектом, имеющим компонент Rigidbody (например врагом), после чего создать Fixed Joint, который присоединит гранату к этому Rigidbody, заставляя ее оставаться “прилипшей”, даже если враг будет двигаться.

Разрываемые соединения

Вы можете использовать свойства Break Force и Break Torque, чтобы установить лимиты силы по отношению к соединению. Если они меньше бесконечности, то Fixed Joint будет разрушен и соединение больше не будет поддаваться ограничениям.

Мне надо связать два (можно несколько) физических объекта, находящихся на расстоянии, в юнити. То есть сделать так, чтоб все силы действующие на один объект применялись и к другому, как-будто это один объект. Например: один из объектов уже достиг коллайдера, а второй - нет, но второй так же должен отскочить от пустоты, как это сделал первый от коллайдера. Один объект толкнули и он покатился, и второй так же, хоть его по сути никто и не толкал.
Нигде не видел ничего подобного, так что понятия не имею, как это нормально сделать. Буду очень рад хорошему совету.

Связать два объекта
Доброго времени суток! У меня на работе такое техническое задание (см.картинку) Я сделал.


Связать два объекта
Подскажите пожалуйста, как такое реализовать на JS. Вообщем есть несколько имен, допустим user1.

Не получается связать два объекта
Всем привет, только начинаю разбираться с Objective-C, перетаскиваю Button с зажатыми левой кнопкой.

1) Если они жестко связаны, то можно слить их в один объект.
2) Если они близко расположены друг к другу. То создать один один объект повесить на него коллайдер и риджидбоди, чтобы обхватывал все объекты, сделать его родительским, а у этих объектов убрать всю физику. Фактически вариация первого варианта.
3) Сделать стенку триггером, проверять вхождение какого-нибудь объекта из набора в этот тригер, и самостоятельно рассчитывать силу или скорость, а затем каждому объекту из набора применять её.

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

Коллайдеру же необязательно быть большим. Не помню, может ли коллайдер быть прерывистым, меш точно может, а вот коллайдер. Если на одном объекте, то да. А вот один коллайдер у множества объектов - не знаю.

А прописывать всю физику самим как-то через чур. Разве никак нельзя это сделать со встроенной физикой?

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

Ну а как рассчитывать вектор силы и скорости, не просчитывая всю физику? У риджитбоди есть как раз такой вектор скорости - velocity. Это и есть почти конечный результат всех вычислений.

У риджитбоди есть как раз такой вектор скорости - velocity. Это и есть почти конечный результат всех вычислений.

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

KakIgrat,
Кастуешь луч по направлению вектора скорости.
Находишь нормаль по данным RaycastHit.
Считаешь новый вектор скорости.
Присваиваешь этот новый вектор скорости всем нужным объектам.

Внимательно прочитай описание ко всем 3 классам. Там есть всё нужно для решения этой задачи.

Решение

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

Не очень понятно, чего именно вы хотите добиться. Но если буквально следовать вашему описанию, то вот:

Да, то что нужно, но всё работает с некоторыми багами к сожалению.

Добавлено через 36 секунд
А как вы нашли такое?

Не очень понятно, чего именно вы хотите добиться. Но если буквально следовать вашему описанию, то вот:

Но главная проблема этого решения заключается в том, что одно физ тело полностью копирует другое. Главное и зависимое просто быстро переключается. Но если в одно время воздействовать на два тела, то всё ломается.

Что значит с багами? Оно работает точно так как вы хотели. Но такая физика тел будет неустойчивой. Потому что один объект упирается в одну стенку, другой - в другую, и они постоянно будут толкать друг друга в разные стороны.
Уменьшите константу dump - например до 0.99 - поведение станет более вязким.

Нашел с помощью передачи нейротрансмиттеров сквозь кору головного мозга.

Давайте предаставим два физ тела которые точно повотряют движение друг друга. Как это будет выглядеть?
1. Расстояние между объектами будет постоянным. Это логично, потому что расстояние может изменить только если одно тело сдвинется относительно другого, а это невозможно по условию задачи, ведь все движения синхронизированны.
То же самое касается вращения - угол поворота между телами всегда будет одинаков, как бы тела ни крутились. Ведь они будут поворачиваться всегда на один и тот же угол.
2. Второе наблюдение. В какой момент какое тело будет "главным" и задавать движение? Поскольку в динамике направление и скорость тела может меняться только под действием силы, то очевидно в момент приложения силы. А сила прикладывается только в момент стокновения, то есть прии коллизии. Значит в момент коллизии, стокнушееся тело становится главным и нужно копировать его движение.
Разумеется, кроме коллизий может буть другая сила, которую вы прикладываете к телу. Если это так, то в момент приложения силы, вам еще нужно вызвать метод AssignCurrentMaster(this).

Читайте также: