After a battle flag has gone off and the player has entered an enemy's battle zone I want to keep track of the player when it moves and make sure the enemy's Z-axis is always pointing towards the player.

Upon the player entering the battle zone, the enemy automatically marks the player as its target However there is a chance that the Z-axis may not be pointing towards the enemy's target when the battle is first initiated. I decided to shoot a ray cast from the Z-axis of the enemy when the battle flag goes off and rotate the enemy until the ray and the player intersect thus telling me that enemy's Z-Axis is lined up correctly.

the enemy always has a reference to its current target. My idea was that as once the enemy spots its target initially, it can save the position of the most recent spotting and then take the delta of the CurrentTargetPosition.x and the LastSpottingPosition.x If the delta is positive rotate right and if the delta is negative rotate left.

THE ISSUE: my math or logic must be flawed somewhere because although it works sometimes, other times the enemy will randomly rotate itself in the opposite direction and the ray cast will essentially take the long route to hit the player instead of the shortest route as intended. Also the Local Origin of the enemy and the player are at different height respectively but I dont think that should matter in my case Code Below.

//create ray from enemy position orgin and point it on the Z-Axis
        Ray ray = new Ray(CurrentEnemyTransform.position, CurrentEnemyTransform.forward);
        RaycastHit hit;

        if (Physics.Raycast(ray, out hit, 50f))
            Debug.DrawLine(ray.origin, hit.point);

            //ray hits current enemy target
            if (hit.transform == CurrentTargetTransform)
                //check if enemy has seen its target before while in this battle
                //or is it the first time
                if (enemy.hasTargetLastPosition)
                    //replace old last seen position with most recent spotting
                //or add the first spotting of target while in this battle
                else enemy.AddTargetLastPosition(hit.transform.position);
            //ray is not intersectiing with the enemy's current target so rotate to look for it
            if (hit.transform != CurrentTargetTransform)
                //check if enemy has seen its target once before in battle
                if (enemy.hasTargetLastPosition)
                    //since last spotting has my target moved more to the left or right?
                    if (enemy.targetLastPosition.value.x > CurrentTargetTransform.position.x)
                        //rotate right
                        CurrentEnemyTransform.Rotate(-Vector3.up, 5f, Space.Self);
                            //rotate left
                    else CurrentEnemyTransform.Rotate(Vector3.up, 5f, Space.Self);
                //never seen target yet during this battle so default rotation to right till you found it
                else CurrentEnemyTransform.Rotate(-Vector3.up, 5f, Space.Self);
  • \$\begingroup\$ I answered, but I can help more if you supply more information. Is this a 2D or 3D problem? \$\endgroup\$
    – Kyy13
    Feb 26, 2018 at 15:22
  • \$\begingroup\$ This is a 3D problem in unity engine \$\endgroup\$
    – Cosmik11
    Feb 26, 2018 at 19:33

1 Answer 1

if (enemy.targetLastPosition.value.x > CurrentTargetTransform.position.x)

does not tell you which direction to rotate in. You are just determining whether the player has moved left or right. You need the difference between the angles of the vectors formed between the target and the enemy at the current and last position.

Imagine the following scenarios where E is the enemy and T is target:



If T moves in the positive x direction, then E must rotate clockwise.




If T moves in the positive x direction, then E must rotate counterclockwise.

So you can see that dx is not always the same sign as dtheta.


vector1 = CurrentEnemyTransform.forward;
vector2 = normalize(targetPos - enemyPos);

Then you need to rotate from vector1 to vector2 in 3d space. I'm not an expert at Unity, but I believe it works like this...

[get quaternions for vector 1 and 2]

dq = Quaternion.rotateTowards(quat1, quat2, dTheta);

CurrentEnemyTransform.forward = dq * CurrentEnemyTransform.forward;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .