How to make character run to enemy?

Hi,

I have a bug in my script. When player press skill key but he is not in range to attack character is starting to run to enemy to attack, but when enemy is starting to move character is getting crazy and running in random directions.

Can some one help me?

Method movo to enemy:

if (player.oponent != null)
        {
            if (runtToEnemy)
            {
                //Char moving
                if (Vector3.Distance(transform.position, player.oponent.transform.position) > 3)
                {
                    Quaternion newRotation = Quaternion.LookRotation(player.oponent.transform.position - transform.position, Vector3.forward);
                    newRotation.x = 0f;
                    newRotation.z = 0f;
                    Debug.Log(newRotation);
                    transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * 20);
                    playerMove.controller.SimpleMove(transform.forward * playerMove.speed);
                    animation.CrossFade(playerMove.run.name);

                    if (Vector3.Distance(transform.position, player.oponent.transform.position) <= range)
                    {
                        runtToEnemy = false;
                        player.resetAttackFunction();
                        player.specialAttack = true;
                        inAction = true;
                        skillKey = false;
                    }
                }
                //Char not moveing
                else
                {
                    animation.CrossFade(playerMove.idle.name);
                }
            }
        }

99% of the time you won’t be setting the w/x/y/z values of a quaternion directly, both because there’s no need to and because it’ll almost always end up making things worse (those values don’t work how most people think they do). You’re also setting the “upwards” value to “forward” in the LookRotation function, which depending on how the game works may be correct, but I can’t tell from here.

My suggestion is to use the transform.LookAt(player.oponent.transform.position) function and skip all of this complicated-ness entirely, but it seems that you want to slowly change the rotation of the player as you’re moving. Try cutting out the Vector3.forward from the LookRotation entirely, and then cut the 0f assignments to x and z and see if that works. These things are usually a lot simpler than people make them.

Another problem may be that you’re using the local-space direction in a world-space function (SimpleMove). In order to fix this, you simply need to use the TransformDirection function on the player object’s transform, and specify which local direction is “forward”. Can’t test it myself, but consider the following changes:

 if (player.oponent != null)
         {
             if (runtToEnemy)
             {
                 //Char moving
                 if (Vector3.Distance(transform.position, player.oponent.transform.position) > 3)
                 {
                     Quaternion newRotation = Quaternion.LookRotation(player.oponent.transform.position - transform.position, Vector3.forward);
                     Debug.Log(newRotation);
                     transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, Time.deltaTime * 20);
                     

                     Vector3 forwardDirection = transform.TransformDirection(Vector3.forward);
                     playerMove.controller.SimpleMove(forwardDirection * playerMove.speed);
                     animation.CrossFade(playerMove.run.name);
 
                     if (Vector3.Distance(transform.position, player.oponent.transform.position) <= range)
                     {
                         runtToEnemy = false;
                         player.resetAttackFunction();
                         player.specialAttack = true;
                         inAction = true;
                         skillKey = false;
                     }
                 }
                 //Char not moveing
                 else
                 {
                     animation.CrossFade(playerMove.idle.name);
                 }
             }
         }