Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

rigidbody.velocity assign attempt for 'Sphere' is not valid. Input velocity is { NaN, NaN, NaN }

Discussion in 'Scripting' started by ml785, Jul 8, 2021.

  1. ml785

    ml785

    Joined:
    Dec 20, 2018
    Posts:
    119
    Hi,
    I'm trying to use someone's code for firing a projectile at a target.
    I've placed the code on a Sphere with a Rigidbody. (I have tried Kinematic and non-Kinematic)
    But I am getting this error:

    rigidbody.velocity assign attempt for 'Sphere' is not valid. Input velocity is { NaN, NaN, NaN }.
    UnityEngine.Rigidbody:set_velocity (UnityEngine.Vector3)
    ProjectileFire:Start () (at Assets/ProjectileFire.cs:42)


    Any ideas how to resolve?
    This is the script in question:


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ProjectileFire : MonoBehaviour
    5. {
    6.  
    7.     [SerializeField]
    8.     Transform target;
    9.  
    10.     [SerializeField]
    11.     float initialAngle;
    12.  
    13.     void Start()
    14.     {
    15.         var rigid = GetComponent<Rigidbody>();
    16.  
    17.         Vector3 p = target.position;
    18.  
    19.         float gravity = Physics.gravity.magnitude;
    20.         // Selected angle in radians
    21.         float angle = initialAngle * Mathf.Deg2Rad;
    22.  
    23.         // Positions of this object and the target on the same plane
    24.         Vector3 planarTarget = new Vector3(p.x, 0, p.z);
    25.         Vector3 planarPostion = new Vector3(transform.position.x, 0, transform.position.z);
    26.  
    27.         // Planar distance between objects
    28.         float distance = Vector3.Distance(planarTarget, planarPostion);
    29.         // Distance along the y axis between objects
    30.         float yOffset = transform.position.y - p.y;
    31.  
    32.         float initialVelocity = (1 / Mathf.Cos(angle)) * Mathf.Sqrt((0.5f * gravity * Mathf.Pow(distance, 2)) / (distance * Mathf.Tan(angle) + yOffset));
    33.  
    34.         Vector3 velocity = new Vector3(0, initialVelocity * Mathf.Sin(angle), initialVelocity * Mathf.Cos(angle));
    35.  
    36.         // Rotate our velocity to match the direction between the two objects
    37.         //float angleBetweenObjects = Vector3.Angle(Vector3.forward, planarTarget - planarPostion);
    38.         float angleBetweenObjects = Vector3.Angle(Vector3.forward, planarTarget - planarPostion) * (p.x > transform.position.x ? 1 : -1);
    39.         Vector3 finalVelocity = Quaternion.AngleAxis(angleBetweenObjects, Vector3.up) * velocity;
    40.  
    41.         // Fire!
    42.         rigid.velocity = finalVelocity;
    43.  
    44.         //Alternative way:
    45.         //rigid.AddForce(finalVelocity * rigid.mass, ForceMode.Impulse);
    46.     }
    47. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,514
    That's a lot of math... line 32 for example divides by a cosine, which could be zero at angle == 90 or 270... and lord knows what else it is doing there.

    What are you trying to do? Likely it can be done with a lot fewer steps than whatever is going on up there.

    Here's my turret aiming stuff:

    Turret aiming/rotating:

    https://forum.unity.com/threads/vector-lookat-unprecise.858511/#post-5658304

    General aiming / vector differences / deltas:

    https://forum.unity.com/threads/find-1st-target-with-spherecast.947718/#post-6181047

    Beyond that if you want to debug the code above, break line 32 into its 27 or so constituent steps and reason about each one along the way.

    How to break down hairy lines of code:

    http://plbm.com/?p=248

    Break it up, practice social distancing in your code, one thing per line please.

    Beyond that initial speculation, to help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?

    Knowing this information will help you reason about the behavior you are seeing.

    You can also put in Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    If you are running a mobile device you can also view the console output. Google for how on your particular mobile target.

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494
     
    Bunny83 and ml785 like this.