- Home /
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);
}
}
}
Answer by Lysander · Nov 11, 2014 at 07:00 AM
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);
}
}
}
I'm creating click to move (with camera looking from top) game. I have tried to remove quaternion ant use transform.LookAt() function. But it still not helped. So the problem is this line:
player$$anonymous$$ove.controller.Simple$$anonymous$$ove(transform.forward * player$$anonymous$$ove.speed);
If that's the case, the problem might be with the exchange from local to world spatial directions. Ins$$anonymous$$d of calling Simple$$anonymous$$ove with the transform.forward, try assigning the forward direction from the transform (local space) into a vector3 in the world space using transform.TransformDirection(localspace direction) and then use that for the Simple$$anonymous$$ove function ins$$anonymous$$d. I'm nearly late for work and can't really write out code right now, but the unity docs should have the proper formatting.