I'm developing a 3D game in LWJGL. I have a player class and a monster class and I need the monster class to chase the player when the player is within a certain distance. For that I have the monster directional vector (let's call it monDirVector) and the directional vector that points from the monster to the player (let's call it dirToPlayer)

So the way my monster class works is that it increments its current rotation to match a target angle (this way I can simulate the walking + turning animation). Given this I need to calculate the target angle so that the monDirVector overlaps the dirToPlayer making the monster walk right towards the player.

How would I go about this?

Here's a diagram for better understanding of what I need. enter image description here

I pretty much need to get the cº angle and assign it as the target angle for the monster. The aº is the monster current rotation and the bº is the angle between the two vectors. Both of these are known. Please notice that the monster can be oriented any way and the player can be in any quadrant relative to the monster. This stands for a problem because I can't simply subtract the angle towards the player to the current rotation of the monster.

I would really apreciate if someone helped me.


Working with angles can be really tricky, you have to properly define your coordinate system, the convention whether clockwise direction should be positive or negative and especially what range of angle values will take. So assuming that all angles are measured in the range -180 to 180 degrees (as implied by your diagram), then this will give you the desired results

// Pseudo Code
    float a = monster.getAngle();
    float c = player.getAngle();

    // Convert both angles in the 0 to 360 degree range for a clean workflow
    if (a < 0) a += 360;
    if (c < 0) c += 360;
    float desiredAngle = c - a;

    // Compute its acute counterpart
    if (desiredAngle > 180)
        desiredAngle -= 360;
    else if (desiredAngle < -180)
        desiredAngle += 360;

    // Advance the monster towards player by a predefined value
    a += Math.Min(deltaAngle, Math.Abs(desiredAngle)) * Math.Sign(desiredAngle);

    // Convert this angle back in the -180 to 180 degree range
    if (a > 180) a -= 360;
    else if (a < -180) a += 360;

The deltaAngle will be a small positive value (say 3 degrees) by which the moster will rotate itself in each frame.

On a side note, I would recommend against using this approach as it will only provide realistic results as long as the monster has fixed speed (when OTOH a running monster should have hard time changing its rotation as fast as a walking monster and thus providing unrealistic results). Instead use the steering behaviour for autonomous agents.

| improve this answer | |
  1. Subtract a and c.
  2. If the result is negative, multiply by -1.
  3. Assuming you are interested in the acute angle, if the result is >180, subtract 2 * (result - 180)
| improve this answer | |

Correct me if I am wrong, but your question could be simplified as whether to turn right or turn left towards the player. I inferred this as you are able to get the delta angle but not the direction of the delta angle. Another assumption I have is that this is 2D vectors. (Though it can easily be expanded into 3D)

Obtaining the direction is a rather simple. Consider the following 2 cases where blue and red are the possible target vectors.

enter image description here

  1. Obtain the right vector by rotating the forward vector by 90 degrees.
    This is simply <x,y> -> <-y,x>
  2. Dot the right vector against the target vector and take the sign of the result.
    This would result in 1 for the blue vector and -1 for the red vector
    You can turn your monster left if the result is -1 and right if the result is 1
  3. Keep turning the monster until the angle between target and forward is 0
| improve this answer | |

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.