Trying to figure out a method to measure object speed [BEGINNER]

Hello, i’m completely new to modern video game development and programming on my own in general. I have a very hard time learning new things and my attention span gives me trouble so bare with me a little bit.

I’ve got this bit of sample code, (some of it is unimportant, sorry)

public class CubeMover : MonoBehaviour {
    // Start is called before the first frame update
    void Start()
    {
        
    }

    [SerializeField]
    private float speed = 1;

    // Update is called once per frame
    void Update()
    {
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        Vector3 movement = new Vector3(horizontal, vertical);

        transform.position += movement * Time.deltaTime * speed;
    }

    private void OnCollisionEnter(Collision collision)
    {
        SceneManager.LoadScene("SampleScene");
    } }

basically what this is for is it moves the cube in-game using a transform method. Speed here is an invented multiplier for how fast it “transforms” the position from x,y to x,y

I want the cube, or anything really, to be able to measure the velocity of a second game object and make a decision based on that. I have a second object, a sphere, above the cube. It has a rigidbody and gravity. I want the velocity of the sphere, whatever it is at any given time, to be measured and compared with an > to the speed of the cube that the user controls.

What I’m trying to do is make it so that once the sphere reaches a velocity beyond the velocity of the user-controlled cube, then the game resets.

Make the speed a public field then reference the CubeMove class in de sphere script something like :

public class CubeMuve : MonoBehaviour{
	public float speed = 1f;

}

public class Sphere : MonoBehaviour {
	public CubeMuve cube;
	public float speed = .5f;

	void Update(){
		if (speed > cube.speed){
			//Do the thing 
		}
	}
}

or use a static field

public class CubeMuve : MonoBehaviour{
	//this can't be edited in the editor
	public static float speed = 1f;

}

public class Sphere : MonoBehaviour {
	public float speed = .5f;

	void Update(){
		if (speed > CubeMuve.speed){
			//Do the thing 
		}
	}
}

An interesting idea, but also a very volatile and dangerous condition to fail at the game. If the Sphere winds up in the air, its Rigidbody will accelerate it very quickly to high speeds. Similarly, if it receives any external force, then that applies an immediate change to its velocity (and, by extension, its speed).

That aside, because your sphere DOES have a Rigidbody, knowing what its current velocity is will be very simple:

// Inside the CubeMover script

// Assign this in the inspector
public Rigidbody sphereRB;

// ...

void Update()
{
	Vector3 sphereVelocity = sphereRB.velocity;
	float sphereSqrSpeed = sphereVelocity.sqrMagnitude;

	if(sphereSqrSpeed > speed * speed)
	{
		// Sphere is outrunning cube "speed" variable
	}
}

Why use sqrMagnitude instead of magnitude? Calculating the immediate speed requires a square root calculation, so avoiding that step is far more efficient. With that in mind, since all you need is to a comparison of greater/less than another value, it’s more efficient to square the other value when needed instead.

UPDATE
@Eno-Khaon @helter546

I get some funky error that I can’t understand, and this code in general just didn’t work out whatsoever but I’ve really gone about it the wrong way so I’ll keep thinking about it but if anybody has any input that’d be great.

I did learn one thing though:

You can in fact enable rigidbody to function normally while also moving an object using the transform method. I reset the code back to it’s barebones and kept the rigidbody with gravity on the cube and now the cube falls but moves as it falls, which makes me very happy to see that the engine works that way. Great engine.

For the cube:

public class CubeMover : MonoBehaviour
{
    // calls the rigidbody of the cube and gives it a name
    public Rigidbody cuberb;
    // names a public variable for the cube's velocity to be used later
    public float cuberbSqrSpeed;
    void Start()
        // defines what the variable cuberb even is
    { cuberb = GetComponent<Rigidbody>(); } 

    // not related to my issue, just a multiplier for upping the transform speed if I wished
    [SerializeField]
    public float superspeed = 1;

    // Update is called once per frame
    void Update()
    {
        // transform method to move the cube by the arrow keys
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        Vector3 movement = new Vector3(horizontal, vertical);

        transform.position += movement * Time.deltaTime * superspeed;

        // method used to establish the rigidbody velocity of the cube and turn it into something that the sphere script can work with
        Vector3 cuberbVelocity = cuberb.velocity;
        float cuberbSqrSpeed = cuberbVelocity.sqrMagnitude;
    }



    // just another unrelated part of the code where the game resets if it collides with anything I guess, not sure.
   private void OnCollisionEnter(Collision collision)
    {
        SceneManager.LoadScene("SampleScene");
    }
}

For the sphere:

public class UncatchableSpeed : MonoBehaviour
{
    // calls the rigidbody of the sphere and gives it a name
    public Rigidbody sphereRB;
    // calls the public float variable from the other script to be figured
    public float cuberbSqrSpeed;
    void Update()
    {
        // same exact method to establish the velocity of this object and make it work with the other one
        Vector3 sphereVelocity = sphereRB.velocity;
        float sphereSqrSpeed = sphereVelocity.sqrMagnitude;

        //our great shining goal
        if (sphereSqrSpeed > cuberbSqrSpeed)
        {
            SceneManager.LoadScene("SampleScene");
        }
    }
}

my private void oncollision no longer works, and maybe i’m asking it to do funky things.
but nothing the code is meant for works either. I’m confused.

I also can no longer control my cube using the transform method. So i’m at a loss.

I might go back to trying my hand at tutorials, but I can’t for the life of me sit through them for longer than about 45 seconds and nothing sticks in my head.

I also have come to understand that asking it to perform this thinking every single frame is a little odd, because naturally the moment the game starts, the sphere begins moving but the cube does not because it waits for my arrow key input. So naturally, having the code being called all the time when I just started the game is problematic.