Unity Player столкновение с горизонтальными маленькими коллайдерами - PullRequest
0 голосов
/ 25 января 2019

Я знаю, что название не очень объяснительно, но вот моя проблема:

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

По какой-то неизвестной мне причине, когда мой куб игрока падает и пытается столкнуться горизонтально с полом, он просто проходит через ... Но хочу, чтобы его блокировали кубы, как это происходит вертикально. Любая помощь будет принята с благодарностью;)

вот как выглядит сцена

вот объект куба

вот объект игрока

Вот гиф игрока, проходящего через пол

Вот мой сценарий движения c # плеера (я знаю, что он очень плохой, но я предпочитаю ставить его здесь на случай, если он связан с моей проблемой):

void ApplyMovement()
{        

 transform.position += new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

}

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

Ответы [ 3 ]

0 голосов
/ 25 января 2019

Вы должны применить силу к Rigidbody персонажа, вместо того, чтобы напрямую манипулировать transform.position (это мешает физическому движку разрешать столкновения).Вы также замораживаете позиции X и Z на Rigidbody;Вы не хотите этого, потому что это полностью предотвращает манипулирование этими значениями Rigidbody.

Вместо transform.postion += ... сначала получите ссылку на Rigidbody где-то в вашем скрипте (лучше всего сделать в Awake() method):

private Rigidbody _body;
private void Awake() {
    _body = GetComponent<Rigidbody>();
}

Затем убедитесь, что вектор, построенный из ваших входов, применяется к «движению» объекта, а не к его позиции:

Vector3 inputVector = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
// You can multiply this vector by a float to adjust "speed"

_body.ApplyForce(inputVector, ForceMode.VelocityChange);

Наконец, вы должны прочитатьизучите различные опции ForceMode и решите, какой из них соответствует вашим предпочтениям: https://docs.unity3d.com/ScriptReference/ForceMode.html

Не забудьте, что это должно произойти в FixedUpdate(), а не Update() (все физические операции должны быть выполненыв FixedUpdate())


Как примечание стороны, существует также вероятность того, что ваши твердые тела все еще движутся слишком быстро и проходят друг через друга.Даже если вы используете силы и скорости, это возможно, поэтому, если вы столкнетесь с этим делом в будущем, исследуйте Режимы обнаружения столкновений .TLDR;это настройки производительности и компромиссов точности.

0 голосов
/ 25 января 2019
  1. Значение

    new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"))
    

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

    // Adjust the speed in the inspector
    public float speedMultiplicator = 1;
    
    //...
    
    new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")) * speedMultiplicator * Time.deltaTime
    

    чтобы получить независимое от частоты кадров движение. Также см. Пример в Input.GetAxis .

  2. При работе с RigidBody никогда не меняйте transform.positionrotation) напрямую!

    Если вы хотели бы сделать RigidBody прыжок на определенную позицию, используйте

    rigidBody.position = transform.position + ...;
    

    Однако вам нужно плавное движение, чтобы сохранить обнаружение столкновений без изменений. Поэтому вы должны использовать RigidBody.MovePosition вместо

    rigidBody.MovePosition(transform.position + ...);
    

    Вам не нужно иметь дело с силой и т. Д.

  3. Также добавьте компонент RigidBody к объектам пола. Даже если объект не движется, это улучшает обнаружение столкновений (за счет производительности в движке Физики). И поскольку объекты не должны двигаться, установите

    • isKinematic -> true
    • использовать Gravity -> false

    Вы также можете установить freeze position и freeze rotation.

  4. На объектах пола и игрока установлено Collision Detection -> Continous Dynamic.
    Это улучшает обнаружение коллизий и ищет коллизии также между кадрами.
    Имейте в виду, однако, что динамическое обнаружение довольно дорого, поэтому используйте его, только если все еще есть проблемы со слишком быстрыми объектами.

  5. На плеере вы также можете использовать interpolate.

  6. Наконец

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

Для получения дополнительной информации см. Руководство RigidBody и руководство Colliders

0 голосов
/ 25 января 2019

Я воссоздал сценарий, который вы описали на моем конце. Я поместил ваш код «ApplyMovement» в «Обновление». Я в основном смог воспроизвести ваши результаты.

Мне кажется, что проблема может быть в позиции замораживания X / Z на проигрывателе. Я думаю, что так как вы делаете это, вы говорите компоненту Rigidbody, что ему не разрешено изменять положение X / Z объектов как часть разрешения столкновений и физического моделирования. Когда я выключаю эти два, я получаю результаты, которые (я думаю) ближе к тому, что вы ищете.

Одно примечание: ваш код ApplyMovement заблокирован, что означает, что ваш игрок будет двигаться с разной скоростью с разной частотой кадров. Чтобы решить эту проблему, вам нужно умножить значения Input.GetAxis на Time.deltaTime.

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

...