So, I'm putting together an FPS, and everything's now working pretty good, but now, I want to know, what's a good way to have a gun that "bobs" while moving. So, while I"m running, the gun will shake a bit as I run. Animations would be good, but I'm more comfortable doing it in code. What's the best way to do it?
What I do is transform between two "sway points" to get the appearance of walking. When I reach point 1, i start going towards point 2 and vice versa. I call this function while the player is moving.
function walkSway () {
if(swayTarget == 1){
//swayTarget is which of the two points I'm going towards
if (Vector3.Distance(transform.localPosition, walkSway1) >= .01){
curVect= walkSway1 - transform.localPosition;
//if the gun isn't at sway point one, transform towards it (the speed at which it transforms depends on the speed of the player) .
transform.Translate(curVect*Time.deltaTime*swayRate*player.GetComponent("FPSWalker").speed,Space.Self);
} else {
//if it has reached sway point 1, start going towards sway point 2
swayTarget = 2;
}
} else if(swayTarget == 2) {
if (Vector3.Distance(transform.localPosition, walkSway2) >= .01){
curVect= walkSway2 - transform.localPosition;
// curVect is just the temporary vector for the translation
transform.Translate(curVect*Time.deltaTime*swayRate*player.GetComponent("FPSWalker").speed,Space.Self);
} else {
swayTarget = 1;
}
}
}
I define the 2 sway points at start based on my "sway factor", which is a vector3. It is the distance (x, y, and z) which I want the gun to sway by. ( I call this function in Start())
function defineSwayPoints () {
walkSway1 = transform.localPosition + swayFactor;
walkSway2 = transform.localPosition - swayFactor;
}
I also have a function to return the gun to normal position when not walking:
function resetPosition () {
if (transform.localPosition != startPosition){
curVect= startPosition - transform.localPosition;
transform.Translate(curVect*Time.deltaTime*2,Space.Self);
}
}
Then all you need to do if you have those functions is put this in Update or LateUpdate:
function LateUpdate() {
if(FPSWalker.walking){
walkSway();
} else {
resetPosition();
}
}
And this into the FPSWalker script:
static var walking : boolean = false;
//add this into FixedUpdate()
if((Mathf.Abs(moveDirection.x) > 0) && grounded || (Mathf.Abs(moveDirection.z) > 0 && grounded)){
//if the player is moving, walking is true
if(!walking){
walking = true;
}
} else if(walking){
walking = false;
}