Search Unity

Why when using Vector3.Dot the dot value is never more then 1 ?

Discussion in 'Scripting' started by Chocolade, Sep 4, 2021.

  1. Chocolade

    Chocolade

    Joined:
    Jun 19, 2013
    Posts:
    933
    Code (csharp):
    1.  
    2. private void Update()
    3.     {
    4.         var heading = lookObj.position - transform.position;
    5.         var dot = Vector3.Dot(heading, -lookObj.forward);
    6.  
    7.         if (dot > 1)
    8.  
    lookObj is the target and transform is the player and the dot value is 0.9953859 it's never 1 or more.

    I want to do something when the player is facing a target or to do something else when not facing that target. but the first condition is never true.
     
  2. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    you don't seem to understand what dot product does.
    why would you want the result to be greater then 1?
    what is the meaning of this result in your head.

    the only way to get a result greater than 1 is to dot multiply two vectors of which one is greater in magnitude then 1 and both are codirectional. but what exactly do you infer from this?

    if you're using the dot product properly, you're doing it with the unit vectors anyway, and in that case the result is never less than -1 and never greater than +1. that's literally the whole point of it.

    because of
    a · b = ||a|| ||b|| cos θ


    this helps you quite easily detect the orthogonality (or collinearity) of two vectors.
    nearing 0 indicates orthogonal directions.

    this means if you have a look direction, and there is a vector between two objects, you can check whether these are collinear (or how much), by checking how far their dot product is from the zero.

    logically to discern how far something is from zero, you need to know the extremes, so work with unit vectors to ensure that the extremes are -1 and 1 and not some random magnitudes based on current distances.
     
    Last edited: Sep 5, 2021
    U_ru_Ru likes this.
  3. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    Code (csharp):
    1. const float THRESHOLD = 0.9f;
    2. var heading = (lookObj.position - transform.position).normalized;
    3. var dot = Vector3.Dot(heading, transform.forward); // both are unit length
    4. if(dot < THRESHOLD) Debug.Log("don't look away"); // you don't want -1, that would mean you've turned your back
     
    Chocolade likes this.
  4. Chocolade

    Chocolade

    Joined:
    Jun 19, 2013
    Posts:
    933

    I tried it this way :

    Code (csharp):
    1.  
    2. private void Update()
    3.     {
    4.         var heading = (lookObj.position - transform.position).normalized;
    5.         var dot = Vector3.Dot(heading, transform.forward); // both are unit length
    6.         if (dot > THRESHOLD)
    7.         {
    8.             if (lookObj != null)
    9.             {
    10.                 t1 += Time.deltaTime / 0.5f;
    11.                 value1 = Mathf.Lerp(0f, 1f, t1);
    12.  
    13.                 animator.SetLookAtWeight(value1, value1, value1, value1, value1);
    14.                 animator.SetLookAtPosition(lookObj.position);
    15.             }
    16.  
    17.         }
    18.         else
    19.         {
    20.             t += Time.deltaTime / 0.5f;
    21.             value = Mathf.Lerp(1f, 0f, t);
    22.  
    23.             animator.SetLookAtWeight(value);
    24.         }
    25.     }
    26.  
    When I rotate the player facing the target than :

    First time the dot is more than 0.9 but than the next frame the dot change down to 0.83 before it complete the first lerp it's starting the lerp in the else. and I didn't change the player rotation he is still facing the target(lookObj).

    The THRESHOLD variable is at the top of the script and it's value is set to 0.9f
     
  5. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    ok this can't work, you're violating the common sense of lerping at this point.

    look,
    Time.deltaTime
    gives you the time since the last frame. it's usually something small (like 1/60th of a second).
    this is why we accumulate these values, as time measurement. but you're dividing this by 0.5, which means you're effectively doubling the time step for no particular reason.

    so after 2 seconds,
    t1
    will be equal to 4.

    then you take a lerp, which is a function that takes two values and interpolates between them by some percentage, which is traditionally named
    t
    not because it has to be time, but because it usually has to do with animating. it's just a percentage, a dimensionless value that is used to determine where exactly the result should land between a and b.

    naturally you want to use a
    t
    between 0 and 1. if you go beyond these values, then you're extrapolating, which is valid, but rarely needed (and also prohibited by this function, you need to use LerpUnclamped). however, your lerp has 0 and 1 as the end values, and this is really mind-boggling. if you wanted a value between 0 and 1, well
    t
    was already that value, why would you need a lerp?
    Mathf.Lerp(0f, 1f, 0.618034f)
    is exactly 0.618034f. incredible right?

    so whatever it is that you're trying to do here, you're doing it wrong.

    here let me unroll this for you
    after 250 milliseconds,
    t1
    will be equal to 0.5 and
    value1
    will be 0.5
    after half a second,
    t1
    will be equal to 1 and
    value1
    will be 1
    after 2 seconds,
    t1
    will be equal to 4 and
    value1
    will be 4

    I'm sure you wanted something meaningful out of it but this is just pointless.
    edit: in fact, I just remembered that if you don't use LerpUnclamped,
    value1
    will just slam into 1 and stay that way.

    THRESHOLD was just an example to illustrate a point. you're supposed to experiment with a value that suits you better.
     
    Last edited: Sep 5, 2021
  6. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    if you can just communicate what exactly do you need, that would be most helpful.