Search code examples
c#unity-game-enginegame-development

How can I avoid the "transform.position assign attempt for 'Ball' is not valid. Input position is { NaN, NaN, NaN }."?


I have been trying to code a replica of Atari Breakout in Unity (the game where you bounce a moving ball on screen with a controllable paddle at the bottom to break blocks). In my script for the ball, I added some code to control the angle at which the ball bounced off the paddle based on where the ball was in relation to the paddle when it collided with it. Here is the code:

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

public class Ball : MonoBehaviour
{
    public float speed = 5;
    float deltaX;
    float deltaY;
    double angleConst = 7 * System.Math.PI / 8 / 1.8;

    // Start is called before the first frame update
    void Start()
    {
        transform.position = new Vector2(Random.Range(-6, 6), -1);
        deltaX = Random.Range(-1 * (float)System.Math.Sqrt(speed), (float)System.Math.Sqrt(speed));
        deltaY = (float)System.Math.Sqrt(speed - System.Math.Pow(deltaX, 2));
    }

    void OnTriggerEnter2D(Collider2D col)
    {
        if(col.gameObject.tag == "Player")
        {
            // ball's horizontal position on the paddle
            double positionDiff = GameObject.Find("Paddle").transform.position.x - transform.position.x + 0.9;

            deltaX = (float)System.Math.Sqrt(speed * System.Math.Cos(positionDiff * angleConst));
            deltaY = (float)System.Math.Sqrt(-1 * speed * System.Math.Sin(positionDiff * angleConst));
        }
        else if(col.gameObject.tag == "Horizontal")
        {
            deltaY = -1 * deltaY;
        }
        else if(col.gameObject.tag == "Vertical")
        {
            deltaX = -1 * deltaX;
        }
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        transform.Translate(Vector2.right * deltaX * Time.fixedDeltaTime);
        transform.Translate(Vector2.down * deltaY * Time.fixedDeltaTime);
    }
}

Once I added the Math.Sqrt functions in the reassignments of deltaX and deltaY if the object collided with was the "Paddle," the following error would continuously appear over and over again until the program is stopped once the ball came in contact with the paddle: "transform.position assign attempt for 'Ball' is not valid. Input position is { NaN, NaN, NaN }."

Before I added the square roots, the script worked and no errors showed up. I've read up on the error and came across a lot of people saying it could be a dividing by zero error, but I don't see any potential for that in my script. What is causing these inputs to return as NaN?


Solution

  • A quick patch to this would be to simply replace the value passed to Mathf.Sqrt() with its absolute value as giving it a negative number outputs NaN if I am not mistaken. However I would advise, for future development, looking into Unity's built in Vector2 and Vector3 methods and functions as much of what you are trying to do can be simplified with an a pre-existing method. Unity Vector2 documentation, Unity Vector3 documentation