Hi.
I am working on a script that gives my FPS weapon a more realistic ‘sway’ effect while looking around.

In this script I have used the mouse input and localPosition to create the effect…

var speed : float = 1;
var maxAmount : float = 1;
private var newPos : Vector3;
private var localPos : Vector3;
private var movementX : float;
private var movementY : float;
function Start(){
localPos = transform.localPosition;
}
function Update (){
movementX = Input.GetAxis("Mouse X") * Time.deltaTime * maxAmount;
movementY = Input.GetAxis("Mouse Y") * Time.deltaTime * maxAmount;
newPos.x = localPos.x - movementX;
newPos.y = localPos.y - movementY;
newPos.z = localPos.z;
transform.localPosition = Vector3.Lerp(transform.localPosition,newPos,speed*Time.deltaTime);
}

I have decided that changing the position of the object isn’t the right way to create a realistic effect. I have tried to use localRotation and Quaternion like this…

var speed : float = 1;
var maxAmount : float = 1;
private var newRot : Quaternion;
private var localRot : Quaternion;
private var movementX : float;
private var movementY : float;
function Start(){
localRot = transform.localRotation;
}
function Update (){
movementX = Input.GetAxis("Mouse X") * Time.deltaTime * maxAmount;
movementY = Input.GetAxis("Mouse Y") * Time.deltaTime * maxAmount;
newRot.x = localRot.x - movementX;
newRot.y = localRot.y - movementY;
newRot.z = localRot.z;
transform.localRotation = Quaternion.Lerp(transform.localRotation,newRot,speed*Time.deltaTime);
}

This script doesn’t have any effect of the weapon, it just stays ‘static’, even if I crank the speed up to 999. So can someone please help me with this problem and show me the right method to go about this?

According to the docs, Input.GetAxis() returns a value between -1 and 1, which means you’re only adding fractions of degrees to your rotatation. Try multiplying it by 360 and see if that fixes it.

This is a recurrent problem in Unity: the Editor fools us by showing the transform.localEulerAngles under the caption Rotation, making everybody think that the XYZ components of a quaternion are the rotation angles around the basic axes. They actually have a totally different meaning, and should never be directly modified.

I changed your script to use localEulerAngles instead:

var speed : float = 1;
var maxAmount : float = 1;
private var newRot : Vector3;
private var localRot : Vector3;
private var movementX : float;
private var movementY : float;
function Start(){
localRot = transform.localEulerAngles;
newRot = localRot;
}
function Update (){
movementX = Input.GetAxis("Mouse X") * Time.deltaTime * maxAmount;
movementY = Input.GetAxis("Mouse Y") * Time.deltaTime * maxAmount;
// accumulate Mouse X and Y axes in newRot - notice that Mouse X is the
// horizontal movement, what means rotation around Y, and Mouse Y actually
// must affect the rotation around X:
newRot.y = (newRot.y - movementX) % 360; // keep the angles in the 0..360 range
newRot.x = (newRot.x - movementY) % 360;
// localRot follows newRot with some delay:
localRot = Vector3.Lerp(localRot, newRot, speed*Time.deltaTime);
transform.localEulerAngles = localRot; // update actual object rotation
}

We must never directly Lerp transform.localEulerAngles to the desired rotation, because it may return weird XYZ combinations at some angles - make an initial copy of it, Lerp this copy and use it to update transform.localEulerAngles.