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\$
4
  • \$\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\$ Commented Feb 26, 2016 at 21:19
  • \$\begingroup\$ How can I do that? \$\endgroup\$
    – John Smith
    Commented Feb 26, 2016 at 21:20
  • \$\begingroup\$ It would help if you also showed your mouse look script. \$\endgroup\$
    – DMGregory
    Commented Feb 26, 2016 at 23:34
  • \$\begingroup\$ I use the unity's default FPSController \$\endgroup\$
    – John Smith
    Commented Feb 27, 2016 at 8:17

1 Answer 1

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 :)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .