Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

velocity.magnitude always returns 0

Discussion in 'Scripting' started by puddleglum, Nov 21, 2020.

  1. puddleglum

    puddleglum

    Joined:
    May 11, 2020
    Posts:
    380
    for some reason iv tried magnitude and sqrmagnitude but it always returns 0 and i dont know whats wrong.
    Code (csharp):
    1.  
    2.  public Rigidbody2D rb;
    3.     void Start()
    4.     {
    5.  
    6.         rb = GetComponent<Rigidbody2D>();
    7.     }
    8.  
    9.     void Update()
    10.     {
    11.         Debug.Log(rb.velocity.sqrMagnitude);
    12. }
    13.  
     
  2. Stevens-R-Miller

    Stevens-R-Miller

    Joined:
    Oct 20, 2017
    Posts:
    664
    You'll need to give us more of your code if we're going to help you. What makes you expect that the velocity would not be zero when Line 11 executes?
     
    matkoniecz and Bunny83 like this.
  3. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Yeah, if this is the entire script, then the sqrMagnitude is 0 simply because nothing is telling the Rigidbody2D to move.
    If there's more to this script, please post the rest of it.
     
  4. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    Or, more generally:

    The odds of a bug in vector.magnitude or vector.sqrMagnitude is negligible, because those are extremely simple functions that have been used by a huge number of people over a period of many years. If Unity is telling you the magnitude is zero, that's because the vector is zero.

    If you weren't expecting the vector to be zero, that's a problem with the vector, not with how you're getting the magnitude. You need to back up and look at where the vector came from and figure out why it's zero.
     
  5. puddleglum

    puddleglum

    Joined:
    May 11, 2020
    Posts:
    380
    well i have a seperate movement script if thats what you mean. i mesure the players rigidbody and when the player presses a movment key it moves forwards. when its moving forwards backwads or any other direction the velocity stays at 0. i will give you all the code attached to my player which is only 2 scripts so.


    heres my other script
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class WalkScript : MonoBehaviour
    7. {
    8.    
    9.     public GameObject Player;
    10.     private SpriteRenderer SpriteRen;
    11.  
    12.     // Start is called before the first frame update
    13.     void Start()
    14.     {
    15.      
    16.         SpriteRen = GetComponent<SpriteRenderer>();
    17.  
    18.     }
    19.  
    20.     // Update is called once per frame
    21.     void Update()
    22.     {
    23.      
    24.      
    25.         transform.Translate(Input.GetAxis("Horizontal") * 45f * Time.deltaTime, 0f, 0f);
    26.         transform.Translate(Input.GetAxis("Vertical") * Vector3.up * 45f * Time.deltaTime);
    27.         if (Input.GetAxis("Horizontal") > 0)
    28.         {
    29.             SpriteRen.flipX = true;
    30.         }
    31.         if (Input.GetAxis("Horizontal") < 0)
    32.         {
    33.             SpriteRen.flipX = false;
    34.         }
    35.      
    36.  
    37.  
    38.     }
    39.  
    40.  
    41. }
    42.  
     
  6. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    I'm guessing this script and the other one posted in the OP are the attached to the same GameObject?
    If so, the
    velocity
    /
    sqrMagnitude
    of the Rigidbody2D is 0 because you're moving the object using its Transform component instead.

    If you want movement similar to
    Transform.Translate
    , but using a Rigidbody2D, set the
    isKinematic
    field to true on the Rigidbody2D and use the MovePosition method.
    Once movement is done with the Rigidbody2D, its
    velocity
    /
    sqrMagnitude
    value will be updated.

    Make sure Rigidbody2D movement is done inside FixedUpdate, also.

    Generally speaking, any time you want to move an object with a Rigidbody/2D component, you almost always use the body's
    AddForce
    /
    MovePosition
    methods. If you move using the Transform instead, the object will not interact with colliders.
     
    Stevens-R-Miller likes this.
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    As @Vryken correctly points out above, you are moving it by the transform direclty so its velocity just stays whatever it was.

    NOTE: if you are using physics and you want collisions and triggers, NEVER touch the transform properties.

    Instead, use the .MovePosition() and/or .MoveRotation() properties on the Rigidbody (or Rigidbody2D) instance itself.

    Reason: touching the transform bypasses the physics system completely, and the physics views it essentially as a magical "teleport" without any chance to do collisions, etc.
     
  8. puddleglum

    puddleglum

    Joined:
    May 11, 2020
    Posts:
    380
    ok that makes actualy alot of sense. i just used the transform.translate cause it looks smooth and im a noob and dont know how to properly make anything
     
    Last edited: Nov 22, 2020
  9. puddleglum

    puddleglum

    Joined:
    May 11, 2020
    Posts:
    380
    how can i use it with my current set up using
    Code (csharp):
    1.  
    2. (Input.GetAxis("Horizontal") * 45f * Time.deltaTime, 0f, 0f);
    3.  
    or is that imposible
     
  10. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Gather the input(s) from the axis, condition it properly (scale or clip it to what you want), then set the Rigidbody's .velocity to that value. This will let the physics move your object per that speed.

    When setting the .velocity component in the Rigidbody, do not use Time.deltaTime, as the physics system will be doing the moving for you, and it knows how to timeslice.
     
  11. puddleglum

    puddleglum

    Joined:
    May 11, 2020
    Posts:
    380
    ooh ok
    thanks :)
     
  12. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    656
    Yeah, as others has hinted at, moving physical objects (Objects with rigidbodies) around by their transforms simply teleports them. There is no way Unity can know an object's velocity from that (Unless it kept track of where the object was last frame, and where it is now, and then extrapolated it from that. Which it don't).
    So as soon as you put a rigidbody on an object, you kinda tell Unity that it is in charge of moving the object. All you then have to tell Unity, is the velocity, and Unity will update the transform for you based on that (Just remember that velocity is in units/second, and so you don't have to think of deltaTimes and such, as Unity will do that for you).
    To try and have it both ways just confuses the system, and keeps Unity out of the physical loop.
     
  13. puddleglum

    puddleglum

    Joined:
    May 11, 2020
    Posts:
    380
    ok ye so i realize now that the way i was doing it was excluding unity's physics system.