0
\$\begingroup\$

I have a static object. I have a moving player.

If the player is moving directly towards the object then I want to return the value of 1. If the player is moving directly away from the the object then I want to return the value of 0. If the player is moving somewhat between these two directions then I want to return a value proportionally relevant to the two previously mentioned values - between 0 and 1 depending on the direction. The direction that the player is facing is irrelevant, it's the velocity of the player that's important for my situation.

How do I calculate this value?

This is so frustrating, as I know that I've solved this exact problem in the past but I'm currently drawing a blank. It involves some trig and some dot product, but for now I'm clueless and would appreciate any help that's offered.

\$\endgroup\$
3
\$\begingroup\$

The dot product between two unit vectors is:

  • +1 when the vectors are pointing in the same direction
  • 0 when the vectors are perpendicular
  • -1 when the vectors are pointing in opposite directions

So, we can get this value just by normalizing our two direction vectors and dotting them, and then massaging the output into the 0-1 range.

In Unity-style syntax it would be:

float Towardness(Vector3 playerPosition, Vector3 playerVelocity, Vector3 obstaclePosition) {
     Vector3 movementDirection = playerVelocity.normalized;
     Vector3 towardObstacle = (obstaclePosition - playerPosition).normalized;

     float dot = Vector3.Dot(movementDirection, towardObstacle);

     return 0.5f + 0.5f * dot;
}

Or, if you want it to vary linearly with the angle between the vectors, we can use the fact that the dot product of two unit vectors is the cosine of that angle, and get the angle itself (in radians) via the arc-cosine function:

 return 1f - Mathf.Acos(dot)/Mathf.PI;
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.