Rotating the character's torso to aim a weapon

When playing a third-person character, you might want her to aim her weapon at some target that is not directly in front of her, without making her change her direction. In these cases, you will need to apply what is called a procedural animation, which does not rely on premade animation clips, but rather on the processing of other data, such as player input, to animate the character. In this recipe, we will use this technique to rotate the character's spine by moving the mouse, allowing for adjustments in the character's aim. We will also use this opportunity to cast a ray from the character's weapon and display a crosshair over the nearest object on target. Please note that this approach will work with the cameras standing behind the third-person controlled characters.

Getting ready

For this recipe, we have prepared a Unity Package named AimPointer, containing a basic scene that features a character armed with a laser pointer. The package, which also includes the crossAim sprite that is to be used as a crosshair for aiming, can be found inside the 1362_07_09 folder.

How to do it...

  1. Create a new project and import the AimPointer Unity Package. Then, from the Project view, open the mecanimPlayground level. You will see an animated character named MsLaser holding the pointerPrefab object.
  2. From the Project view, create a new C# Script named MouseAim.cs.
  3. Open the script and add the following code:
    using UnityEngine;
    using System.Collections;
    
    public class MouseAim : MonoBehaviour {
      
      public Transform spine;
      private float xAxis = 0f;
      private float yAxis = 0f;
      public Vector2 xLimit = new Vector2(-30f,30f);
      public Vector2 yLimit= new Vector2(-30f,30f);
      public Transform weapon;
      public GameObject crosshair;
      private Vector2 aimLoc;
    
      public void LateUpdate(){
    
        yAxis += Input.GetAxis ("Mouse X");
        yAxis = Mathf.Clamp (yAxis, yLimit.x, yLimit.y);
        xAxis -= Input.GetAxis ("Mouse Y");
        xAxis = Mathf.Clamp (xAxis, xLimit.x, xLimit.y);
        Vector3 corr = new Vector3(xAxis,yAxis, spine.localEulerAngles.z);
        spine.localEulerAngles = corr;
        RaycastHit hit;
        Vector3 fwd = weapon.TransformDirection(Vector3.forward);
        if (Physics.Raycast (weapon.position, fwd, out hit)) {
          print (hit.transform.gameObject.name);
          aimLoc =  Camera.main.WorldToScreenPoint(hit.point);
          crosshair.SetActive(true);
          crosshair.transform.position = aimLoc;
        } else {
         crosshair.SetActive(false);
        }
        Debug.DrawRay (weapon.position, fwd, Color.red);
      }
    }
  4. Save and close the script.
  5. From the Hierarchy view, create a new UI | Image GameObject. Then, from the Inspector view, change its name to crosshair. Also, in Rect Transform, set its Width and Height to 16 and populate Source Image field with the crossAim sprite.
    How to do it...
  6. Attach the MouseAim.cs script to the MsLaser GameObject.
  7. Select the MsLaser GameObject and from the Inspector view's Mouse Aim component, populate the Spine field with mixamorig:Spine; the Weapon field with pointerPrefab; and the Crosshair field with the crosshair UI GameObject.
    How to do it...
  8. Play the scene. You will now be able to rotate the character's torso by moving the mouse. Even better, the crosshair GUI texture will be displayed at the top of the object that is being aimed at by the pointer.
    How to do it...

How it works...

You might have noticed that all the code for rotating the character's spine is inside the LateUpdate function, as opposed to the more common Update function. The reason for this is to make sure that all the transform manipulation will be executed after the original animation clip is played, overriding it.

Regarding the spine rotation, our script adds the horizontal and vertical speed of the mouse to the xAxis and yAxis float variables. These variables are then constrained within the specified limits, avoiding distortions to the character's model. Finally, the spine object transform rotation for x and y axes are set to xAxis and yAxis respectively. The z-axis is preserved from the original animation clip.

Additionally, our script uses a Raycast command to detect if there is any object's collider within the weapon's aim, in which case a crosshair will be drawn on the screen.

There's more...

Since this recipe's script was tailored for cameras standing behind the third-person controlled characters, we have included a more generic solution to the problem—in fact, a similar approach to the one presented in Unity 4.x Cookbook, Packt Publishing. An alternate script named MouseAimLokkAt, which can be found inside the 1362_07_09 folder, starts by converting our bi-dimensional mouse cursor screen's coordinates to the three-dimensional world space coordinates (stored in a point variable). Then, it rotates the character's torso towards the point location, using the LookAt() command to do so. Additionally, it makes sure that the spine does not extrapolate minY and maxY angles, otherwise causing distortions to the character model. Also, we have included a Compensation YAngle variable that makes it possible for us to fine-tune the character's alignment with the mouse cursor. Another addition is the option to freeze the X-axis rotation, in case you just want the character to rotate the torso laterally, but not look up or down. Again, this script uses a Raycast command to detect objects in front of the weapon's aim, drawing a crosshair on the screen when they are present.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.155.187