Unity Artificial Intelligence Programming
上QQ阅读APP看书,第一时间看更新

Controlling the tank

The player can rotate the Turret object using the mouse. This part may be a little bit tricky because it involves raycasting and 3D rotations. The Camera looks down upon the battlefield:

    void UpdateControl() 
    { 
      //AIMING WITH THE MOUSE 
      //Generate a plane that intersects the transform's  
      //position with an upwards normal. 
      Plane playerPlane = new Plane(Vector3.up,  
      transform.position + new Vector3(0, 0, 0)); 
 
      // Generate a ray from the cursor position 
      Ray RayCast =  
      Camera.main.ScreenPointToRay(Input.mousePosition); 
 
      //Determine the point where the cursor ray intersects  
      //the plane. 
      float HitDist = 0; 
 
      // If the ray is parallel to the plane, Raycast will  
      //return false. 
      if (playerPlane.Raycast(RayCast, out HitDist)) 
      { 
        //Get the point along the ray that hits the  
        //calculated distance. 
        Vector3 RayHitPoint = RayCast.GetPoint(HitDist); 
 
        Quaternion targetRotation = 
        Quaternion.LookRotation(RayHitPoint -  
        transform.position); 
 
        Turret.transform.rotation =  
        Quaternion.Slerp(Turret.transform.rotation,  
        targetRotation, Time.deltaTime *  
        turretRotSpeed); 
      } 
 

We use raycasting to determine the turning direction by finding the mousePosition coordinates on the battlefield:

Raycast to aim with the mouse
Raycasting is a tool provided by default in the Unity physics engine. It allows us to find the intersection point between an imaginary line (the ray) and a collider in the scene. Imagine this as a laser pointer: we can fire our laser in a direction and see the point where it hits. However, this is an expensive operation, so try to not exaggerate with the length and number of rays you fire in each frame.

This is how it works:

  1. Set up a plane that intersects with the player tank with an upward normal
  2. Shoot a ray from screen space with the mouse position (in the preceding diagram, it's assumed that we're looking down at the tank)
  3. Find the point where the ray intersects the plane
  4. Finally, find the rotation from the current position to that intersection point

Then we check for the key-pressed inputs, and move or rotate the tank accordingly:

      if (Input.GetKey(KeyCode.W)) 
      { 
        targetSpeed = maxForwardSpeed; 
      } 
      else if (Input.GetKey(KeyCode.S)) 
      { 
        targetSpeed = maxBackwardSpeed; 
      } 
      else 
      { 
        targetSpeed = 0; 
       } 
 
      if (Input.GetKey(KeyCode.A)) 
      { 
        transform.Rotate(0, -rotSpeed * Time.deltaTime,  
        0.0f); 
      } 
      else if (Input.GetKey(KeyCode.D)) 
      { 
        transform.Rotate(0, rotSpeed * Time.deltaTime,  
        0.0f); 
      } 
 
      //Determine current speed 
      curSpeed = Mathf.Lerp(curSpeed, targetSpeed, 7.0f *  
      Time.deltaTime); 
       
      transform.Translate(Vector3.forward * Time.deltaTime *  
      curSpeed); 
    } 
}