Recoil function: smoothly rotation

Hello!
I am writing recoil function. Here is the code: (recoil() called each shot)

	public GameObject RecoilCamera;
	public float RecoilPlus,RotationSpeed;	


void Recoil(){    
		RecoilCamera.transform.Rotate (RecoilPlus,0,0);
	}

How do I rotate it smoothly?

Thanks in advance, any help is appreciated

You probably don’t need to do an actual slerp or lerp here. I’d write it a little more like the stuff below. Whatever method you use you’ll need to know the base ‘unrecoiled’ rotation, and the time you’ve been recoiling for.

your code would be something like:

  • if base_rotation is your camera’s unrecoiled rotation
  • recoil_start_time is when you started recoiling
  • recoil_length is how long you want to recoil for
  • recoil_size is how much you want to rotate by

I would go along the lines of, each frame:

//how long we've been recoiling
float time_recoiling = Time.time-recoil_start_time;

//a value from 0 to 1, which is 0 at the start of a recoil, and 1 at the end of the recoil
float interpolator = time_recoiling / recoil_length;

if(interpolator >= 0 && interpolator <= 1)
{
    //cosine wave interpolator - starts at 1, goes smoothly through to -1 then back to 1
    float cos_interpolator = Mathf.Cos(interpolator*Mathf.PI*2.0f);

    //tweak it so it goes from 0, to 1 then back to 0
    cos_interpolator = 1-(cos_interpolator+1)/2;

    //now set the rotation to be the base rotation, plus some x axis rotation based on our interpolator
    RecoilCamera.transform.rotation = base_rotation*Quaternion.Euler(cos_interpolator*recoil_size);
}
else
{
    //maybe do something if not recoiling? depends on your game!
}

Note this code has 2 purposes:

  • it applies a change in angle over time as requested
  • it also uses a cosine function, to ensure the recoil smoothly transitions in and out, rather than jumping around. you could fiddle with how you choose that interpolator to get the effect you want.

a simpler interpolator if you don’t want the cosine might just be:
interpolator = interpolator < 0.5 ? interpolator*2 : 1-(interpolator-0.5)*2;

that’s like a triangle - it zips up then straight back down. you could even get cleverer and make it transition differently going up than down. Whatever happens, you’re just trying to pick a value that goes from 0, to 1, then back to 0 again. I often use excel to work out these graphs!

hope that helps - sorry if the code isn’t perfect - no compiler here :slight_smile: