Unity Rigidbody.SweepTestAll () иногда не обнаруживает коллайдеры - PullRequest
0 голосов
/ 06 октября 2019

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

Моя игра не использует встроенную физическую систему, вместо этого персонажи выполняют SweepTest в заданном направлении перед обновлением своей позиции с помощью transform.position + = moveVector; . Это позволяет мне держать их в точном соответствии с пространством сетки, что необходимо для моей головоломки. Иногда, играя в мою игру, персонаж падает через кусок пола. Другие персонажи или объекты могут перемещаться по одной и той же части пола без каких-либо проблем. Кажется, это особые отношения только между двумя объектами, которые, казалось бы, выбираются случайным образом. Он не всегда влияет на одного и того же персонажа и не всегда влияет на один и тот же кусок пола. Неважно, в каком направлении персонаж приближается к полу или как он расположен относительно пола. Из-за заданного количества частей пола (или стен или других объектов), а также персонажей, я наткнулся на него только один раз в голубой луне. Могут быть месяцы между тем, когда я сталкиваюсь с этим (я провожу много времени, развиваясь, но не много времени, играя). Запуск новой игры в приложении через меню, перезапуск приложения (если это встроенная версия) или выход из режима игры (если он есть в редакторе) не может воспроизвести проблему таким же образом. Опять же, это кажется случайным.

Это означает, что если я хочу выполнить некоторую отладку, мне нужно все это кодировать перед текущим выполнением, потому что редактирование любых сценариев вызывает их перекомпиляцию и вызывает ошибки втекущая сессия.

Моя игра - построить карту головоломки, добавив сцену, загружающую несколько комнат головоломки. Я не знаю, может ли это быть фактором, но я все равно упомяну об этом.

Мой персонаж имеет шкалу (100, 200, 100) и скорость перемещения 20. Его коробка Коллайдер установлен в масштабе (0,99, 0,99, 0,99). У него также есть кинематическое твердое тело . Верхняя часть пола находится на высоте 0, а его поле Коллайдер имеет эквивалентную шкалу (1, 1, 1). Персонаж обычно сидит на позиционной высоте 100, и его происхождение находится в его центре. Это означает, что его основание всегда должно быть около 1 над полом, а это означает, что его основание никогда не должно идеально совмещаться с полом, предотвращая перекрытие ошибок с плавающей запятой. Это также означает, что SweepTest с величиной 20 вниз должен поднимать пол без проблем.

Инспектор символов: https://i.imgur.com/c4detlv.png Инспектор пола: https://i.imgur.com/fQFotn7.png

Используя некоторую отладку, я записывал результаты каждого вниз SweepTest , вот код и результаты.

RaycastHit[] hitThings = GetComponent<Rigidbody>().SweepTestAll(moveVector, moveVector.magnitude, QueryTriggerInteraction.Ignore);
Debug.Log(gameObject.transform.position);
Debug.Log(moveVector);
Debug.Log(moveVector.magnitude);
Debug.Log(hitThings.Length);
foreach (RaycastHit hitThing in hitThings) {
    Debug.Log(hitThing.collider.name);
    Debug.Log(hitThing.collider.tag);
    Debug.Log(hitThing.collider.transform.parent.name);
    Debug.Log(hitThing.collider.transform.root.name);
    Debug.Log(hitThing.distance);
    Debug.Log(hitThing.collider.transform.position);
}
Debug.Log("--------");

.

(-2370.0, 100.0, -4050.0)
(0.0, -20.0, 0.0)
20
1
Piston
Piston
WalkwayExtendedEast
Tier1Room-
1.252515
(-2450.0, -50.0, -4000.0)
--------
(-2350.0, 100.0, -4050.0)
(0.0, -20.0, 0.0)
20
0
--------
(-2350.0, 80.0, -4050.0)
(0.0, -20.0, 0.0)
20
0
--------
(-2350.0, 60.0, -4050.0)
(0.0, -20.0, 0.0)
20
0
--------
(-2350.0, 40.0, -4050.0)
(0.0, -20.0, 0.0)
20
0
--------
(-2350.0, 20.0, -4050.0)
(0.0, -20.0, 0.0)
20
0
--------

Символначинается сверху чего-то твердого. Как только он двигается вправо на 20, он теперь находится только над рассматриваемым полом. Как видите, в SweepTest обнаружены попадания.

В отдельной части отладки я провел Physics.OverlapBox () для персонажа, чтобыопределить, начинается ли персонаж внутри рассматриваемой части пола. Вот эти результаты.

Debug.Log(trasform.position);
Debug.Log(transform.scale * 0.99f);
Collider[] overlapping = Physics.OverlapBox(gameObject.transform.position, transform.scale * 0.99f / 2f);
foreach (Collider currentCollider in overlapping) {
    if (currentCollider.tag != "Character") {
        Debug.Log(currentCollider.tag);
        Debug.Log(currentCollider.transform.position);
        Debug.Log(currentCollider.transform.root.position);

    }
}
Debug.Log("--------")

.

(-2370.0, 100.0, -4050.0)
(99.0, 198.0, 99.0)
--------
(-2350.0, 100.0, -4050.0)
(99.0, 198.0, 99.0)
--------
(-2350.0, 80.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, 60.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, 40.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, 20.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, 0.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -20.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -40.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -60.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -80.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -100.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -120.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -140.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -160.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -180.0, -4050.0)
(99.0, 198.0, 99.0)
Fixture
(-2250.0, -75.0, -4000.0)
(-4000.0, 0.0, -4000.0)
--------
(-2350.0, -200.0, -4050.0)
(99.0, 198.0, 99.0)
--------
(-2350.0, -220.0, -4050.0)
(99.0, 198.0, 99.0)
--------

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

Мой персонаж кинематографический. Если он не кинематичен, а гравитация включена, персонаж остановится на оскорбительном участке пола. Это в сочетании с результатами Physics.OverlapBox () показывает, что физическая система обнаруживает пол, а не SweepTest .

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

Символ через объект: https://imgur.com/VwbUfUx

Я скопировал и вставил кусок пола. Мой персонаж не смог пройти через этот новый объект, и отладка также показала это. Несмотря на то, что скопированный объект имел те же свойства и значения, теперь обнаруживались столкновения с помощью SweepTest .

Добавление еще одного блока Коллайдер к полу также предотвратило моиперсонаж проваливается сквозь него. Так же было добавлено еще одно поле Коллайдер для моего персонажа. Я думаю, что что-то не так с этими двумя конкретными экземплярами этих Коллайдеров , добавляя новый Коллайдер или копируя объект, создавая новый Коллайдер компонентный экземпляр и чтоновый экземпляр, вероятно, имеет такой же шанс «один раз в синюю лунку» иметь этот глюк.

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

Хотя это случается редко, это может вызвать большие проблемы в игре. Игрок с таким персонажем может быть вынужден возобновить свою игру. Неспособность пересечь определенные участки пола может сделать многие игры неразрешимыми. Другие игроки не могут закончить игру без присутствия каждого игрока, поэтому они также будут прерваны.

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

Моя теория: хотя я сталкивался с этой проблемой только между одним из моих персонажей и другим объектом, я рискнул бы предположить, что это возможно дляэта проблема возникает между любыми двумя объектами. Видя, что я сталкиваюсь с этим только раз в пару месяцев и видя, что мои персонажи - это объекты, которые чаще всего соприкасаются с другими объектами, я сомневаюсь, что когда-нибудь смогу это пережить. Эта проблема, кажется, связывает два экземпляра Collider вместе, и я предполагаю, что существует очень небольшая вероятность того, что любые два Collider будут иметь эти отношения.

Unity 2018.4.9f1Личный ЛТС. Настройки физики: https://imgur.com/pKI7Q07

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...