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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Easy way to multiply values in a vector?

Discussion in 'Scripting' started by Marscaleb, Apr 27, 2017.

  1. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    996
    Is there an easy/efficient way to multiply the values in a vector, or otherwise perform simple arithmetic to a vector?

    Here's the basic situation I'm in:
    I'm using a vector I obtain from another function and applying it to my current function's rigidbody's velocity.
    But I want to make some simple tweaks to those values; I want to multiply them by DeltaTime and another local variable (to control speed.)

    Now if I was adjusting the values of the vector individually, it would simply be a matter of writing a line to multiply those values before they are assigned to the vector.
    But since I'm retrieving the values of the vector from another function, I don't have the same access to the variables that form the vector's values.
    Now I *could* create two new float variables, get their values from the vector, and then modify them, and then apply them back into the vector. But that just sounds terribly inefficient! That adds two extra variables to the memory and then an extra six cycles to the function's execution. Isn't there some way I can easily multiply all the values of a vector by a single value?
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,384
    Vector arithmetic defines scalar multiplication, as well as vector summation, dot product, and cross product.

    Code (csharp):
    1.  
    2. Vector3 v = new Vector3(....); //get a vector
    3. v *= 3f; //scales it by 3
    4. v += someVector; //sums a vector
    5.  
     
    dginovker likes this.
  3. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    This shows that when you take a vecter3 and multiply it by a number. it multiplies each of the vectors, .x , .y, .z by the number

    Code (CSharp):
    1.        
    2.         float speed = 5;
    3.         rb = GetComponent<Rigidbody>();
    4.         rb.AddForce(transform.forward);
    5.         Debug.Log("force : " + rb.velocity);
    6.         Debug.Log("+ speed : " + (rb.velocity * speed));
    force : (0.0, -3.3, 0.0)
    + speed : (0.0, -16.7, 0.2)
    force : (0.0, -5.3, 0.3)
    + speed : (0.2, -26.5, 1.3)
     
  4. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    996
    Ahhh... I don't know why I didn't just try to actually multiply the vector instead of just assuming it wouldn't work.
    Did it used to not work that way? A lot of things are working easier than I expect and I swear things used to be different a few years ago.
     
  5. EXTREMEGAMESTUDIOS

    EXTREMEGAMESTUDIOS

    Joined:
    Jan 26, 2022
    Posts:
    2
    is there a way to do this to individual axis
     
  6. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Vectors are structs or so-called "data types". They live on the stack and propagate as concrete data, instead of being considered through a pointer to something lying on a heap.

    That said, it is completely reasonable to extract their components on the fly, do whatever is needed, then reassemble the new thing back.

    For example
    Code (csharp):
    1. var myVec = new Vector3(.127f, .148f, .459f);
    2. myVec.Normalize();
    3. myVec = new Vector3(3f * Mathf.Round(myVec.x), 0f, Mathf.Round(myVec.z));
    4. Debug.Log(myVec.ToString());
    In my practice I've discovered a few interesting patterns that can be used with vectors in order to minimize repetition and allow better chaining of commands, so there are ways and ways to streamline the common vector manipulation. But there is nothing particularly wrong with deconstructing them and then building new ones on the fly. It just looks ugly sometimes (and may be prone to errors).

    For example this is the above code written my way (perhaps not the most useful example but still...)
    Code (csharp):
    1. myVec = myVec.normalized.x_z().Lambda( (i,v) => Mathf.Round(v) ).ScaledBy(x: 3f);
    Edit:
    If you're interested here the extensions are defined as follows (you must make an extension class for this to work, because we can't edit the actual Vector3 class)
    Code (csharp):
    1. public static Vector3 x_z(this Vector3 v) => new Vector3(v.x, 0f, v.z);
    2.  
    3. public static Vector3 Lambda(this Vector3 v, Func<int, float, float> lambda)
    4.   => new Vector3(lambda(0, v.x), lambda(1, v.y), lambda(2, v.z));
    5.  
    6. public static Vector3 ScaledBy(this Vector3 v, float x = 1f, float y = 1f, float z = 1f)
    7.   => new Vector3(x * v.x, y * v.y, z * v.z);
    8.  
    9. // aka component-wise multiplication for two vectors
    10. public static Vector3 ScaledBy(this Vector3 v, Vector3 other)
    11.   => new Vector3(other.x * v.x, other.y * v.y, other.z * v.z);
    All in all, if you want to multiply X by 3 in a readable manner, you can do this
    Code (csharp):
    1. myVec = myVec.ScaledBy(x: 3f);
    But nothing stops you from implementing ScaleX or something similar. Whatever the case, you can't avoid having to access the individual component, multiplying it, and then reassembling all components into a new Vector3 to reflect this change. This is how structs work.

    Edit2:
    In fact, because structs in C# are confusing for beginners, let me clarify the above example of multiplying the whole thing by 3, because it's actually coded like this under the hood
    Code (csharp):
    1. public static Vector3 operator *(float lhs, Vector3 rhs) => new Vector3(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
    2. public static Vector3 operator *(Vector3 lhs, float rhs) => new Vector3(rhs * lhs.x, rhs * lhs.y, rhs * lhs.z);
     
    Last edited: Jan 29, 2022
    Olipool likes this.