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.
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.
AimPointer
Unity Package. Then, from the Project view, open the mecanimPlayground level. You will see an animated character named MsLaser holding the pointerPrefab object.MouseAim.cs
.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); } }
crosshair
. Also, in Rect Transform, set its Width and Height to 16
and populate Source Image field with the crossAim sprite.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.
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.
18.222.155.187