0
\$\begingroup\$

I would like to rotate an FPS camera slightly upwards during a shot as an effect of recoil, but the problem is that I have a mouse look script as well and I assume it prevents me from achieving the effect i want. So far I have tried using transform.Rotate(-10,0,0) and

transform.rotation = Quaternion.Euler(transform.rotation.x - 10, transform.rotation.y, transform.rotation.z);

both rotated the camera upwards but then the camera moved back downwards to the initial position. Does anyone know how I can rotate the camera and keep the rotation? Or if there is any better way to achieve this effect.

\$\endgroup\$
  • \$\begingroup\$ If the mouse is hidden why not add an offset and then use lerp to put the recoil back to were the mouse is pointing? \$\endgroup\$ – user3797758 Feb 26 '16 at 21:19
  • \$\begingroup\$ How can I do that? \$\endgroup\$ – Vadim Tatarnikov Feb 26 '16 at 21:20
  • \$\begingroup\$ It would help if you also showed your mouse look script. \$\endgroup\$ – DMGregory Feb 26 '16 at 23:34
  • \$\begingroup\$ I use the unity's default FPSController \$\endgroup\$ – Vadim Tatarnikov Feb 27 '16 at 8:17
1
\$\begingroup\$

Ok so based on the comment i made earlier here is how i would add offset to the camera. The code is just of the top of my head so it might need a bit of fine tuning:

//Inside the mouse tracking class
Vector2 offset = new Vector2();
float startTime = -1f.
    length;

//the code that controls the initial recoil
private void Hit()
{
    transform.rotation = Quaternion.Euler(transform.rotation.x - 10, transform.rotation.y, transform.rotation.z);

    offset.x = 10f;
    startTime = Time.time;
    length = Vector2.Distance(new Vector2, offset);
}

//replace the part were you get the mouse position with this method
Vector2 Recoil()
{
    if (startTime != -1f)
    {
        Vector2 mouse = Input.mouse.position,
            adjustedMouse = mouse + offset;

        //change the 10 to speedup/slow down the transition back to normal
        float dist = (Time.time - startTime) * 10f,
            fracJourney = dist / length;

        if (dist >= 1f)
        {
            startTime = -1f;
            offset.x = 0f;
        }

        return Vector2.Lerp(adjustedMouse, mouse, dist);
    }
    else {
        return Input.mouse.position;
    }
}

When you want to trigger the recoil call "Hit" which will setup all the variables for the Lerp. Then instead of checking the input class for the position of the mouse on screen, call the "Recoil" method which should pull the mouse up and then slowly lower it to the actual position of the gun.

You can read up on what I did here but for the sake of completeness: (Vector.Lerp description)

Linearly interpolates between two vectors.

Interpolates between the vectors a and b by the interpolant t. The parameter t is clamped to the range [0, 1]. This is most commonly used to find a point some fraction of the way along a line between two endpoints (e.g. to move an object gradually between those points).

I hope this works for you :)

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.