Home > Mobile >  How can I get a component of a rigidbodies velocity?
How can I get a component of a rigidbodies velocity?

Time:11-04

I'm trying to detect the y velocity in my rigidbody in order to determine whether the player can jump or not. For some reason the component I get from rb.velocity[2] does not match what I see when I log rb.velocity in console. Some help understanding how to get that vertical velocity component from the rigidbody would be very helpful.

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

public class Movement : MonoBehaviour
{
    public Rigidbody rb;
    public Vector3 xvector = new Vector3 (1, 0, 0);
    public Vector3 yvector = new Vector3 (0, 1, 0);
    public float strafeforce = 1f ;
    public float jumpforce = 15f;
    
    // Update is called once per frame
    void Update()
    {
        rb = GetComponent<Rigidbody>();
    }
    void FixedUpdate()
    {
        if (Input.GetKey("right") )
        {
            rb.AddForce(strafeforce, 0, 0, ForceMode.Impulse) ; 
        }
        if (Input.GetKey("left") )
        {
            rb.AddForce(-strafeforce, 0, 0, ForceMode.Impulse) ; 
        }
        if (Input.GetKey("up") )
        {
            rb = GetComponent<Rigidbody>();
            if (rb.velocity[2] == 0)
            {
                rb.AddForce(0, jumpforce, 0, ForceMode.Impulse) ;
            }
            Debug.Log(rb.velocity);
            Debug.Log(rb.velocity[2]);
        }
    }
}

So the problem is that the second value from rb.velocity doesn't match the value I get from rb.velocity[2] for some reason.

CodePudding user response:

In C# indexes start from 0. That means that index 2 would actually be the 3rd component of the vector (i.e. the z velocity). If you want the second component you should actually use rb.velocity[1].

However if you want to get a specific component, for example the y velocity, you can instead use rb.velocity.x, rb.velocity.y and rb.velocity.z. This makes the code easier to read, as you can see at a glance which axis you are trying to access.

CodePudding user response:

The difference only exists in the Log due to different ToString implementations.

Unity's default formatting for Vector3.ToString uses F1 which rounds all values to a single decimal

   public string ToString(string format, IFormatProvider formatProvider)
   {
       if (string.IsNullOrEmpty(format))
           format = "F1";
       return UnityString.Format("({0}, {1}, {2})", x.ToString(format, formatProvider), y.ToString(format, formatProvider), z.ToString(format, formatProvider));
   }

This is not the case for the default float.ToString.

Id you want to be sure they match in the log use e.g.

Debug.Log(rb.velocity.ToString("G9"));
Debug.Log(rb.velocity[2].ToString("G9"));

or actually simply

Debug.Log(rb.velocity.z.ToString("G9"));
  • Related