Почему я продолжаю получать эту ошибку во время вычисления траектории?

#c# #unity3d

#c# #unity3d

Вопрос:

Я хочу произвести вычисления траектории, и я знаю, какое значение y оно будет иметь при посадке (это -0.995). Я пытаюсь рассчитать, сколько времени потребуется, чтобы упасть до этой высоты, чтобы я мог установить значение x на основе этого.

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

Попытка назначения Rigidbody2D.position для ‘Spawner’ недопустима. Входная позиция равна { NaN, -1.000000 }. UnityEngine.Rigidbody2D:set_position(Vector2) Spawner:Update() (в Assets/Spawner.cs:29)

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

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

public class Spawner: MonoBehaviour
{
    float arriveTime;
    public GameObject player;
    Rigidbody2D rb;
    float predictedX = 1;
    void Start()
    {
        rb = player.GetComponent<Rigidbody2D>();
    }

    
    void Update()
    {

        if (Input.GetKeyDown(KeyCode.P))
        {


            arriveTime = (-1 * rb.velocity.y - Mathf.Sqrt(rb.velocity.y * rb.velocity.y - 4 * (Physics2D.gravity.y / 2 * -0.995f))) / Physics2D.gravity.y;
            predictedX = rb.position.x   arriveTime * rb.velocity.x;

            GetComponent<Rigidbody2D>().position = new Vector2(predictedX, -1);

        }
    }
}
 

Ответ №1:

Потому что ваш Input position is { NaN, -1.000000 }.

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

Итак, если arriveTime уже есть NaN , то также predictedX будет NaN , поскольку arriveTime участвует в его вычислении.

NaN обычно это результат математически неопределенной (для рациональных чисел) операции.

Есть два места, которые я могу сразу определить при расчете arriveTime , где это может произойти:

  • Возможно деление на 0 в конце для / Physics2D.gravity.y .

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

  • Возможно, пытаясь принять Mathf.Sqrt отрицательное значение в случае, которое rb.velocity.y * rb.velocity.y меньше, чем 4 * (Physics2D.gravity.y / 2 * -0.995f)

Вы могли бы проверить эти случаи, например

 if(Physics2D.gravity.y == 0)
{
    // probably do nothing or sanatize the value to something else
    return;
}

var ySqr = rb.velocity.y * rb.velocity.y;
var subs = 4 * (Physics2D.gravity.y / 2 * -0.995f);

if(ySqr < subs)
{
    // do nothing or sanatize the value
    // e.g. you could use the Mathf.Abs value instead
    return;
}

arriveTime = (1 - rb.velocity.y - Mathf.Sqrt(ySqr - subs)) / Physics2D.gravity.y;
 

или вы также можете просто проверить NaN после выполнения вычислений, например,

 if(predictedX == float.NaN)
{
    // probably do nothing or sanatize the value to something else
    return;
}
 

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

 arriveTime = (-1 * rb.velocity.y - Mathf.Sqrt(Mathf.Abs(rb.velocity.y * rb.velocity.y - 4 * (Physics2D.gravity.y / 2 * -0.995f)))) / Physics2D.gravity.y;
   
 

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