Перейти к содержимому

Rigidbody2d unity как работает

  • автор:

Rigidbodies (твёрдые тела)

Rigidbody — это основной компонент, подключающий физическое поведение для объекта. С прикреплённым Rigidbody, объект немедленно начнёт реагировать на гравитацию. Если добавлен один или несколько компонентов Collider, то при коллизиях (столкновениях) объект будет передвигаться.

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

There are some cases where you might want a GameObject to have a Rigidbody without having its motion controlled by the physics engine. For example, you may want to control your character directly from script code but still allow it to be detected by triggers (see Triggers under the Colliders topic). This kind of non-physical motion produced from a script is known as kinematic motion. The Rigidbody component has a property called Is Kinematic which removes it from the control of the physics engine and allow it to be moved kinematically from a script. It is possible to change the value of Is Kinematic from a script to allow physics to be switched on and off for an object, but this comes with a performance overhead and should be used sparingly.

См. страницы справки по Rigidbody и Rigidbody 2D для дополнительной информации о настройках и опциях по скриптингу этих компонентов.

Засыпание

When a Rigidbody is moving slower than a defined minimum linear or rotational speed, the physics engine assumes it has come to a halt. When this happens, the GameObject does not move again until it receives a collision or force, and so it is set to “sleeping” mode. This optimisation means that no processor time is spent updating the Rigidbody until the next time it is “awoken” (that is, set in motion again).

Когда твёрдое тело перемещается со скоростью, меньшей определённого минимального порога, физический движок предполагает, что оно остановилось и находится в покое. При этом, объект не будет вновь двигаться до тех пор, пока с ним не произойдёт столкновение или пока к нему не применят силу, так что он уходит в “спящий” режим. Эта оптимизация означает, что на объект не будут расходоваться ресурсы CPU, пока его вновь не “разбудят” (т.е. не вновь не приведут в движение). По многим причинам засыпание и пробуждение твёрдых тел происходит прозрачно. Однако, иногда объект не удаётся разбудить, если в него или от него переместится статичный коллайдер (тот, что без твёрдого тела) изменяя положение трансформации. Это может привести, скажем, к висящему в воздухе твёрдому телу, когда пол под ним сдвинулся вниз. В таких случаях объект можно разбудить принудительно, с помощью функции WakeUp . См. страницы про компоненты Rigidbody и Rigidbody 2D для дополнительной информации о засыпании.

Компонент Rigidbody 2d Unity

  • Body Type — тип тела. Три варианта, dynamic — динамическое тело(с массой), cinematic — тело без массы, statc — жестко зафиксированное тело.
  • Simulated — TO DO.
  • Use Auto Mass — использовать автоматический расчет массы. Расчитывается исходя из размеров Коллайдера.
  • Mass — масса.
  • Linear Drag — размер линейного сопротивления.
  • Angular Drag — размер сопротивления на поворот объекта.
  • Gravity Scale — угол, при котором на объект действует гравитация.
  • Collision Detection — как обрабатывать столкновения между объектами. Discrete — событие столкновения регистрируется при взаимодействии коллайдеров, во время программно обновления расчетов. Continuous — столкновение регистрируется, когда коллайдер объекта должен коснуться другого коллайдера, между обновлениям расчетов.
  • Sleeping Mode — для экономии ресурсов, объект может спать, sleeping mode обрабатывает этот эффект. Never Sleep — объект никогда не спит. Start Awake — объект изначально не спящий. Start Asleep — объект спит, но может быть разбужен внешними воздействиями.
  • Interpolate — сглаживание объекта. None — сглаживание не применяется. Interpolate — применяется сглаживание, основанное на предыдущем и текущем кадрах. Extrapolate — применяется сглаживание, основанное на текущем и будущем кадрах.
  • Constraints — ограничение на движение твердого тела. Freeze Position — Останавливает движение объекта, движущегося по осям X и Y. Freeze Rotation — останавливает объект, вращающийся вокруг оси Z.

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

Зачем нужно писать в метод класс rb = GetComponent();?

Мы объявляем переменную типа float с именем speed и присваиваем ей значении 100f.

Если мы объявляем переменную и не присваиваем ей никакого значения, то компилятор сделает это за нас и присвоит значение по умолчанию. Для float это будет 0f. Для Rigidbody2D это будет null (отсутствие ссылки, пустота).

Естественно с пустотой работать не получится и строчкой кода:

rb = GetComponent(); 

мы присваиваем переменной rb типа Rigidbody2D значение конкретного Rigidbody2D.

Компилятор не может сам догадаться о каком именно Rigidbody2D идет речь, потому что мы можем хотеть работать с компонентом Rigidbody2D, подключенном к другому игровому объекту (или даже создать новый Rigidbody2D). Например, мы могли использовать такую строчку кода, что бы подключить к переменной rb компонент Rigidbody2D с игрового объекта с тегом Enemy:

rb = GameObject.FindWithTag("Enemy").GetComponent(); 

PS: этот мой первый ответ на этом сайте, дайте знать если я сделал что-то не так.

нет столкновения с машиной и объект не уничтожается.

Добрый день, друзья! Подскажите, пожалуйста. Сделал простейшую аркаду, но у меня почему-то сама машинка при соприкосновении с другими машинками проходит сквозь них, хотя у всех машин установлено свойств Box collider2d. А также я запрограммировал уничтожение машинки при соприкосновении по тэгу с другими машинки, но почему -то машинка не уничтожается. Тэги проверил, стоят. Можете помочь, в чем проблема? Здесь фото экрана https://disk.yandex.ru/i/8CaUax11esS3zw. А здесь проект https://disk.yandex.ru/i/8CaUax11esS3zw

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
<
public float speed = 3f;

void Update()
<
float hor = Input.GetAxisRaw(«Horizontal»);// Получение координаты при нажатии на клавишу по оси икс
Vector3 dir = new Vector3(hor, 0, 0);
transform.Translate(dir.normalized * Time.deltaTime * speed);// перемещение самой машинки на вычисленную ранее координату
>
private void OnCollisionStay(Collision collision)
<
if (collision.gameObject.CompareTag(«car»))// если просиходит столкновение с другими авто с тэгом car, то объект уничтожается.
Destroy(gameObject);
>
>

#1
14:18, 31 июля 2022

При использовании физики нужно добавлять rigidbody, если управляется напрямую с помощью скриптов, то установить в режим kinematic.
Перемещать исключительно влияя на rigidbody, а не transform.
Если не требуется физических столкновений, коллайдер перевести в режим trigger.
Использовать OnCollisionEnter (OnTriggerEnter в случае триггера), вместо OnCollisionStay.

  • Eugeny1984
  • Пользователь

#2
14:40, 31 июля 2022

Tokarn
> OnTriggerEnter
поставил параметр Body Type =Cinematic. — не помогло. Перемещать исключительно влияя на rigidbody, а не transform. -это как? Пробовал галочку ставить на is Trigger — не помогло.

#3
14:53, 31 июля 2022

transform.position это телепорт объекта, так физические тела не двигают. И да на всех машинах должен висеть rigidbody. Trigger не используется для физических коллизий, он служит для обнаружения вхождения в него другого физического тела.

Найди физическое тело автомобиля

Rigidbody Telo = AutoObject.transform.GetComponent();

Задай ему импульс

Telo.AddForce(transform.forward * 7f * Time.deltaTime * 1000f, ForceMode.Impulse);

#4
16:42, 31 июля 2022

Eugeny1984
> поставил параметр Body Type =Cinematic. — не помогло. Перемещать исключительно
> влияя на rigidbody, а не transform. -это как? Пробовал галочку ставить на is
> Trigger — не помогло.
1) На всех физических объектах в игре, не являющихся статичными должен присутствовать Rigidbody
Почему:
а) При отсутствии rigidbody объект с коллайдером считается статичным и входит в массив статичных коллайдеров.
б) Массив статичных коллайдеров создан чтобы обрабатывать все взаимодействие со статикой в физическом движке за один присест, т.е. очень оптимизированно.
в) При изменении любого элемента в массиве статичных коллайдеров ведется полный перерасчет всех объектов являющихся статичными (объекты с коллайдером без rigidbody или с rigidbody в состоянии «Static»), что занимает большое количество вычислительной мощности, если таких объектов очень много.
2) Физические игровые объекты (т.е. с rigidbody), полностью управляющиеся с помощью скрипта-контроллера или например анимации (например платформа анимированная в Аниматоре) или агента NavMesh, должны быть переключены в состояние «Kinematic»
Почему:
а) При состоянии не равном Kinematic, состояние может быть либо Static, либо Dynamic: в первом случае оно относится к статическим объектам и его положение не должно изменяться вообще, дабы избежать просадок в производительности (как стена, которую не возможно сдвинуть и сломать), во втором случае положение объекта управляется физическим движком (с физически правильным просчетом столновений, силой тяжести и т.п., как шарик в пинболе).
б) Использование статического ригидбоди все равно что не использовать ригидбоди вообще. Любой объект с коллайдером но без компонента Rigidbody считается движком статическим физическим объектом, т.е. по умолчанию объект с коллайдером без ригидбоди получает свойства как у объекта с ригидбоди в состоянии Static.
в) В случае Dynamic передвижением можно управлять добавляя силу (AddForce) в нужном векторе (например персонаж в платформере, бегает и прыгает — в части случаев это rigidbody в режиме dynamic, с фиксированным углом поворота).
г) В твоем случае это Kinematic с полным контролем движения через скрипт, ты напрямую управляешь положением физического тела. Например в твоем случае можно указать ригидбоди в инспекторе: public Rigidbody rb; А затем использовать её rb.position += dir.normalized * Time.deltaTime * speed;
3) Если в твоей игре требуется только коснуться с объектом и он удаляется, производительнее использовать триггер-коллайдеры, вместо обычных коллайдеров.
Почему:
а) Событие коллизии двух коллайдеров собирает в себя большое количество не нужной в таком случае информации — векторы столкновений, точка пересечения, расчеты физики столкновений и т.п. Событие пересечения коллайдеров «легковеснее» для расчетов. Например для пуль в платформере не нужно использовать коллайдеры, если пули не рикошетят с физически правильным просчетом, а сразу исчезают и показывают эффект попадания, вместо этого используются триггер-коллайдеры. Судя по всему у тебя другие машины ведут себя как снаряды, сразу же уничтожаясь при столкновении.
б) Столкновения с другими коллайдерами могут вызвать лишние дерганья, баги, если движение обоих объектов управляются скриптами и один или двое из объектов имеет динамический ригидбоди. Если игрой не предполагаются физически правильные столкновения, а просто имеет место быть «событие столкновения с препятствием», то смысла в использовании коллайдеров в режиме коллизий нет.
4) В расчете столкновения использовать OnCollisionEnter (OnTriggerEnter в случае триггера), вместо OnCollisionStay.
Почему:
а) При использовании OnCollisionStay код срабатывает не в момент первого касания, а чуть позже (в следующем цикле физических расчетов).
б) При использовании OnCollisionStay предполагается что два объекта некоторое время соприкасаются друг с другом, и каждый физический тик выполняется код, указанный в функции OnCollisionStay — т.е. не единожды, а почти каждый кадр или несколько раз в кадр.
в) OnCollisionEnter (OnTriggerEnter) выполнятся именно в момент соприкосновения с другим игровым объектом с коллайдером (триггером в случае OnTriggerEnter), в отличии от OnCollisionStay, что при больших скоростях сделает просчет игровых событий гораздо стабильнее (при очень больших скоростях и расчетах столкновения в OnCollisionStay, пройденное за один физический тик расстояние может значительно влиять на геймплей, вызывая баги).
г) Использование OnCollisionStay можно рассматривать в контексте блока с лавой, когда на нем стоишь тратится здоровье — т.е. выполняется просчет всё время, пока ты касаешься блока. В то время как OnCollisionEnter (OnTriggerEnter) выполняется только в момент первого касания и единожды.

#5
16:53, 31 июля 2022

Eugeny1984
Обращаясь к transform вместо rigidbody ты просто телепортируешь объект полностью без просчета физики, такая методика применима только к объектам не имеющим физического тела (например объект, выполняющий роль какого-то визуального эффекта).
Если перемещать transform объекта с rigidbody, физическое столкновение все равно может быть просчитано движком в следующий физический тик, но вместо логичного легковесного в расчетах и правильного поведения будет использоваться некий физический дебагер, который будет рассчитывать как вытащить один коллайдер, застрявший в другом — это в сотни и тысячи раз тяжелее для расчетов и будет сильно затормаживать систему в случае массовых пересечений коллайдеров.

  • Eugeny1984
  • Пользователь

#6
18:01, 31 июля 2022

Tokarn
> а) Событие коллизии двух коллайдеров собирает в себя большое количество не
> нужной в таком случае информации — векторы столкновений, точка пересечения,
> расчеты физики столкновений и т.п. Событие пересечения коллайдеров
> «легковеснее» для расчетов. Например для пуль в платформере не нужно
> использовать коллайдеры, если пули не рикошетят с физически правильным
> просчетом, а сразу исчезают и показывают эффект попадания, вместо этого
> используются триггер-коллайдеры. Судя по всему у тебя другие машины ведут себя
> как снаряды, сразу же уничтожаясь при столкновении.
> б) Столкновения с другими коллайдерами могут вызвать лишние дерганья, баги,
> если движение обоих объектов управляются скриптами и один или двое из объектов
> имеет динамический ригидбоди. Если игрой не предполагаются физически правильные
> столкновения, а просто имеет место быть «событие столкновения с препятствием»,
> то смысла в использовании коллайдеров в режиме коллизий нет.
> 4) В расчете столкновения использовать OnCollisionEnter (OnTriggerEnter в
> случае триггера), вместо OnCollisionStay.
> Почему:
Спасибо за подробности, но из того, что вы написали, я понял лишь 10%, пробовал использовать OnCollisionEnter — не уничтожается все равно объект при столкновении. вы лучше скажите, пож. как исправит, чтобы столкновения просходили?

#7
18:14, 31 июля 2022

Eugeny1984
Уберите проверку на тег и попробуйте проверить работу скрипта без него, если позволяет механика. Может быть у вас ошибка в написании тега.

  • Eugeny1984
  • Пользователь

#8
18:38, 31 июля 2022

Tokarn
я закоментировал private void OnCollisionStay(Collision collision), чтобы компилятор не воспринимал. К сожалению все без изменений.

#9
18:43, 31 июля 2022

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

Это не приведет к быстрому решению вашей задачи, потому что конкретного решения вы не найдете. Оно окупится вам в будущем, спустя недели, когда ваше подсознание переварит полученную информацию и на основе её вы сможете строить новые осознанные и более сложные логические цепочки, включая и решение вашей задачи. Если конечно вы не забросите практику разработки игр.

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

  • Eugeny1984
  • Пользователь

#10
22:11, 31 июля 2022

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

#11
0:29, 1 авг 2022

1) Проверьте не используете ли вы Collider2D и rigidbody2D в связке с методом OnCollisionEnter или аналогичным. В unity используются два физических движка не связанных друг с другом: для 2D физики и для 3D физики. Для 2D физики есть методы-синонимы, например OnCollisionEnter2D и т.д.

2) Проверьте правильно ли указан тег который вы указали для объекта в инспекторе. Теги регистрозависимые, т.е. MainCamera != mainCamera.

3) Проверьте наличие коллайдеров у обоих объектов, которые должны создавать коллизию.

4) Проверьте чтобы используемый метод соответствовал используемому типу коллайдера. Т.е. если коллайдер препятствия отмечен как триггер-коллайдер, а используется метод для отслеживания коллизии между двумя коллайдерами, а не пересечения с триггером, метод отрабатывать не будет. Это же работает в обратную сторону.

  • DemiosFantasimo
  • Участник

#12
4:38, 1 авг 2022

Когда тебе написали что нужно перемещать через rigibody нужно было начать копаться что такое это самое rigibody. Ты опять берешся за игру не понимая что ты пишешь. Просто берись за свой код, и по порядку бери от туда из того что не понимаешь и штудируй, а то опять будешь плодить вопросы по самым базовым вопросам. Почитай об этом, посмотри видео. Создай пустой проект и на кубах тестируй. Когда дойдет как это работает то уже берись за игру.

  • Eugeny1984
  • Пользователь

#13
15:37, 1 авг 2022

DemiosFantasimo
Как раз в этот раз я и понимаю ,что написал, здесь код очень простой и закоментирован. Ну не хотите вникать в мою проблему, я вас не заставляю.

#14
15:54, 1 авг 2022

1. тебе уже помогали и не раз
2. но ты спрашиваеш однотипные вопросы
3. никто нехочет ковырять где и какую галочку ты не проставил
4. тебе дают описание как это работает, но ты не особо хочеш это понять
5. ты делаеш свой проект на основе «тыкну тут — вдруг заработает»

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *