- Home /
 
The question is answered, fixed it myself
Adjust custom PlayerControls to be used by enemies
I have a question about how to adjust a custom Player Control scripts to be used for enemies too. I'm working on a top down 2D game, and the player can drive a few types of tanks, each with their own max speed & turn speed. 
 I want the enemy tanks to handle/move in the same way, so I thought, that's easy: the only thing I have to change is that horizontal and vertical input needs to be calculated instead of getting that as player input. My current code in FixedUpdate:
 // player input
 h = -Input.GetAxis("Horizontal");
 v = Input.GetAxis("Vertical");
 
 // Calculate speed from input and acceleration (transform.up is forward)
 Vector2 speed = transform.up * (v * tankInfo.acceleration);
 rb.AddForce(speed);
 
 // Create rotation
 float direction = Vector2.Dot(rb.velocity, rb.GetRelativeVector(Vector2.up));
 if (direction >= 0.0f)
 {
     rb.rotation += h * tankInfo.steering * (rb.velocity.magnitude / tankInfo.maxSpeed);
 } else
 {
     rb.rotation -= h * tankInfo.steering * (rb.velocity.magnitude / tankInfo.maxSpeed);
 }
 
 // Change velocity based on rotation
 float driftForce = Vector2.Dot(rb.velocity, rb.GetRelativeVector(Vector2.left)) * 2.0f;
 Vector2 relativeForce = Vector2.right * driftForce;
 rb.AddForce(rb.GetRelativeVector(relativeForce));
 
 // Force max speed limit
 if (rb.velocity.magnitude > tankInfo.maxSpeed)
 {
     rb.velocity = rb.velocity.normalized * tankInfo.maxSpeed;
 }
 
               
Then I updated the script to have a Target (Transform) in Inspector and if the target is set, the scripts needs to calculate the h and v values and use those values to go to the 'target'. The vertical input seems to be working OK:
 // for vertical(up / down) input
 Vector3 diff = target.position - transform.position;
 diff.Normalize();
 v = Mathf.Clamp(diff.y, -1, 1);
 
               
The main problem is calculating the (normalized) rotation amount. I tried Googling and it gave me a few things to try out. I tried Vector2.Angle, Mathf.Atan2 + Mathf.Rad2Deg, Quaternion.RotateTowards and then only use`z` rotation for h input, Quaternion.Euler, I can't get it to work. 
What am I doing wrong? It seems that I'm not using the right functions, or that the functions/my code don't take the current rotation / transform.forward into account. If somebody can point me in the right direction (pun intended) that would be great, or even a link to something where this kind of stuff is explained would help.
Answer by basboogaard89 · Aug 28, 2021 at 09:39 AM
To answer my own question, I guess the code that I tried earlier was indeed wrong, maybe code for 3D games, too much math, I don't know. The code below works for me, at least static forward movement:
 if (target == null) {
     // Get player input
     h = -Input.GetAxis("Horizontal");
     v = Input.GetAxis("Vertical");
 } else {
     // calculate input
 
     // vector from this object towards the target location
     Vector3 vectorToTarget = target.position - transform.position;
 
     // rotate that vector by 90 degrees around the Z axis
     Vector3 rotatedVectorToTarget = Quaternion.Euler(0, 0, 90) * vectorToTarget;
 
     // get the rotation that points the Z axis forward, and the Y axis 90 degrees away from the target (resulting in the X axis facing the target)
     Quaternion targetRotation = Quaternion.LookRotation(forward: Vector3.forward, upwards: rotatedVectorToTarget);
 
     // Don't know why the previous code says 'facing the target' as it's 90 degrees too much
     Vector3 euler = targetRotation.eulerAngles;
     euler.z -= 90;
 
     if (Vector2.Distance(transform.position, target.position) > 2)
     {
         h = Mathf.Clamp(euler.z - transform.rotation.eulerAngles.z, -1, 1);
         v = 1;
     }
 }
 
 // ... (apply force and rotation to RigidBody2D)
 
              Follow this Question
Related Questions
Enemy AI Movement To A Target(Player) In A 2D Game 3 Answers
How do I implement A* pathfinding to my 2d game, without tiles? 4 Answers
2D Enemy AI issues... 1 Answer
Help with 2D AI scripting 2 Answers