Функция Mathf.clamp() в Unity

У меня есть куб (игрок) в моей игровой сцене. Я написал C# скрипт для ограничения движения (используя Mathf.Clamp()) куба, чтобы он не покинул экран.

Ниже мой FixedUpdate() метод из скрипта

private void FixedUpdate()
    {
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
        rb.velocity = movement * speed;

        rb.position = new Vector3(
            Mathf.Clamp (rb.position.x, x_min, x_max),
            0.5f,
            Mathf.Clamp(rb.position.z, z_min, z_max)
            );

    }

Значения x_min, x_max, z_min, z_max -3, 3, -2, 8 соответственно вводятся через инспектор единства.

ПРОБЛЕМА

Скрипт работает нормально, но мой игрок (Cube) может переместиться до -3.1 единиц в минус X-AXIS (если я продолжаю нажимать кнопку со стрелкой влево), что на 0,1 единицы больше в отрицательном X-AXIS(Такое поведение верно и для других осей). Это очевидно зажимает -3.1 к -3, когда я прекращаю нажимать кнопку.

  • Почему это происходит? Почему нет (Mathf.Clamp()) ограничить куб до -3 единиц на первом месте?
  • Почему я получаю эти дополнительные 0,1 единицы?
  • И почему это значение только 0,1 единицы? Почему не более или менее?

3 ответа

Решение
  • Это происходит потому, что внутреннее обновление физики перемещает куб после того, как вы поставили его в фиксированное положение. Mathf.Clamp() ограничивает куб в первую очередь ожидаемой позицией, что можно проверить, поместив Debug.Log непосредственно после назначения позиции.
  • Вы получаете дополнительные единицы.1, потому что вы даете объекту скорость, которая применяется после зажима
  • Это 0,1 единицы из-за скорости и настройки для Фиксированного временного шага (в Настройки проекта> Время). Если бы вы установили более высокую скорость, это было бы больше. Если бы вы понизили фиксированный временной шаг, это также было бы немного больше.

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

Чтобы это исправить, попробуйте сбросить скорость объекта до нуля, если он собирается покинуть ваши границы.

У вас уже есть причина, почему это происходит.

Чтобы исправить проблему, вы можете использовать этот код, чтобы куб не выходил за пределы:

private void FixedUpdate() {
    Vector3 movement = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));

    // Get new position in advance
    float xPos = rb.position.x + movement.x * speed * Time.fixedDeltaTime;
    float zPos = rb.position.z + movement.z * speed * Time.fixedDeltaTime;

    // Check if new position goes over boundaries and if true clamp it
    if (xPos > x_max || xPos < x_min) {
        if (xPos > x_max)
            rb.position = new Vector3(x_max, 0, rb.position.z);
        else
            rb.position = new Vector3(x_min, 0, rb.position.z);
        movement.x = 0;
    }
    if (zPos > z_max || zPos < z_min) {
        if (zPos > z_max)
            rb.position = new Vector3(rb.position.x, 0, z_max);
        else
            rb.position = new Vector3(rb.position.x, 0, z_min);
        movement.z = 0;
    }

    rb.velocity = movement * speed;
}
Другие вопросы по тегам