Nano Hash - криптовалюты, майнинг, программирование

Мой префаб плеера нормально движется вперед, пока не наткнется на объект, что происходит?

Я делаю игру Unity на основе TierZoo, и во время тестирования сценария движения я врезался в одно из деревьев твердых тел для развлечения... и это заставило префаб игрока перестать двигаться вперед, и он начал двигаться в странных направлениях Вот мой код:

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

public class NewPlayerController : MonoBehaviour
{
    private Rigidbody rb;
    public GameObject player;
    public float thrust = 1.0f;
    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.W))
        {
            rb.AddRelativeForce(player.transform.right * thrust * 2.5f);
        }
        if (Input.GetKey(KeyCode.A)) { player.transform.Rotate(0, -1, 0); }
        if (Input.GetKey(KeyCode.D)) { player.transform.Rotate(0, 1, 0); }
        if (Input.GetKey(KeyCode.S))
        {
            rb.AddRelativeForce(player.transform.right * thrust * -2.5f);
        }
    }
}

Если вы можете найти способ исправить это, дайте мне знать.

18.03.2020

  • Когда вы говорите странно. Определить нечетное 18.03.2020
  • возможно, объект игрока вращался из-за удара, и, таким образом, player.transform.right вращается вместе с ним? 18.03.2020
  • @BugFinder Как движение вбок или назад. 18.03.2020
  • @derHugo Возможно, у моего префаба отключено вращение по осям x и z. 18.03.2020
  • так может быть, тогда он вращается вокруг Y? ;) Я имею в виду из-за коллизии, а не той, которую она все равно делает в вашем скрипте. 18.03.2020
  • @derHugo Вот как работает система вращения a и d 18.03.2020
  • @derHugo oof, я не подумал об этой последней части комментария, когда публиковал его. 18.03.2020
  • да, но кажется, что вы получаете некоторые дополнительные вращения, которые вы не хотите получать .. также обратите внимание, что код, который у вас есть, очень плох по двум причинам: когда задействован Rigidbody, не делайте движений в Update и через transform! Это ломает физику. Скорее в FixedUpdate и через rb например. используя MovePosition и MoveRotation. Во-вторых, вы перемещаетесь и вращаетесь в зависимости от кадра с фиксированными шагами 1 или thrust * 2.5f. Вместо этого используйте Time.deltaTime для преобразования этих значений из единиц/кадр в единицу/секунду: rb.MoveRotation(Vector3.up * ANGLEPERSECOND * Time.deltaTime); 18.03.2020
  • вы должны обрабатывать UserInput (Update) и Physics (FixedUpdate) отдельно 18.03.2020
  • @derHugo, можете ли вы опубликовать исправленный сценарий? Я все еще нуб, когда дело доходит до реального программирования (однако я довольно хорошо кодирую наcratch.mit.edu) 18.03.2020

Ответы:


1

Вы также можете зафиксировать вращение в направлении Y, отслеживая его и установив жестко в FixedUpdate.

В общем, как сказано в комментариях:

Всякий раз, когда речь идет о Rigidbody, вы не должны не

  • делать движения через компонент transform
  • делать движения в Update

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

Скорее делайте - пройдите через компонент Rigidbody, например. используя MovePosition и MoveRotation — сделайте это в FixedUpdate

они сохраняют физику нетронутой и перемещают только ваш Rigidbody, например. пока он не сталкивается тем временем.

Затем для поворота у вас есть зависящие от частоты кадров значения Rotate(0, -1, 0)! Вы предпочитаете использовать Time.deltaTime, чтобы получить плавную частоту кадров- независимая скорость вращения - не в 1 градус за кадр, а, например, в 45 градусов в секунду.

Ваш сценарий может выглядеть так

public class NewPlayerController : MonoBehaviour
{
    // already reference this via the Inspector
    [SerializeField] private Rigidbody rb;
    public GameObject player;
    public float thrust = 1.0f;

    private void Awake()
    {
        // as fallback get it on runtime
        if(!rb) rb = GetComponent<Rigidbody>();
    }

    bool moveLeft;
    bool moveRight;
    bool rotateLeft;
    bool rotateRight;

    private float angle;

    void Update()
    {
        // Get User input here 
        // (in your case it would be also fine to do it in FixedUpdate.
        //  What doesn't work in FixedUpdate are mainly the one-time events like GetKeyDown)
        moveRight = Input.GetKey(KeyCode.W);
        rotateLeft = Input.GetKey(KeyCode.A);
        rotateRight = Input.GetKey(KeyCode.D);
        moveLeft = Input.GetKey(KeyCode.S); 
    }

    private void FixedUpdate()
    {
        if(moveRight) rb.AddRelativeForce(rb.rotation * Vector3.right * thrust * 2.5f);
        if(moveLeft) rb.AddRelativeForce(rb.rotation * Vector3.right * thrust * -2.5f);

        // Now for the rotations keep track of what you rotated already
        // and overwrite the rotation with the fix value:
        if(rotateLeft)
        {
            // e.g. for rotating 45°/second
            angle -= -45 * Time.deltaTime; 
            rb.MoveRotation(Quaternion.Euler(0, angle, 0));
        }
        if(rotateRight)
        {
            angle += 45 * Time.deltaTime; 
            rb.MoveRotation(Quaternion.Euler(0, angle, 0));
        }
    }
}
18.03.2020
  • Проблема все еще существует, когда я натыкаюсь на что-то, вектор движения вперед перестает быть направленным в правильном направлении, и я в конечном итоге двигаюсь в неправильном направлении. Я бы предложил добавить больше вещей, которые относятся к префабу, а не к миру. 18.03.2020
  • Вы правы, совершенно забыл исправить проблему ^^ Сосредоточился только на предложенной части рефакторинга, извините ^^ Обновлено 18.03.2020
  • Новые материалы

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

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..