Search Unity

  1. The 2022.1 beta is now available for testing. To find out what's new, have a look at our 2022.1 beta blog post.
    Dismiss Notice

FPS recoil by cinemachine impulse source

Discussion in 'Cinemachine' started by Yuki_Rain, Mar 14, 2020.

  1. Yuki_Rain

    Yuki_Rain

    Joined:
    Jul 25, 2017
    Posts:
    12
    I'm making a FPS game, I like to move camera back(relative to local coordinate) to simulate powerful recoil.
    So I do the following:
    1.AK47 is a gun model with arm, and the virtual camera follow it.
    2.gameobject named "Impulse" has Cinemachine Impulse Source component, and raw signal is Recoil Noise.asset.
    3.Recoil Noise.asset only set Position Z with Frequency 4 and Amplitude 1.
    4.call _impulseSource.GenerateImpulse method.
    Code (CSharp):
    1.         //_impulseSource.GenerateImpulse();
    2.         _impulseSource.GenerateImpulse(transform.forward); // transform is gun model itself
    I try these two method, and the camera just move along with Z(world coordinate) and back, no matter what direction My gun model facing to.
    So my question is how to make camera move back(relative to local coordinate of gun model).
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,559
    The impulse signals are emitted in world-space. However, the emitter can control the direction of impact, and you can use that to get the effect you're looking for. The direction of impact is the Y axis of the signal, so that's the one you should put your impulse on.

    Here's how I set it up in my test scene for recoil:

    1. Define a "Recoil" impulse signal with the primary movement being on the Y axis. You can add some other smaller rotations and displacements on other axes for variety if you like, but for this illustration I'm just showing you a simple recoil and ease back. My signal looks like this:

    upload_2020-3-16_9-34-36.png

    X and Z have 0 amplitude. Note that the Y is a constant 1. This is just an example, you can make the signal more complex (e.g. with bounces) if you want.

    2. Put an impulse source on the gun. Create the recoil shape by adjusting the attack/sustain/decay.

    upload_2020-3-16_9-37-36.png

    3. Emit the impulse when the gun fires. Important: to get the right primary direction, emit it towards Camera.main.forward. Here is what my test code did:

    Code (CSharp):
    1. public class ImpulseRecoilTest : MonoBehaviour
    2. {
    3.     void Update()
    4.     {
    5.         if (Input.GetKeyDown(KeyCode.Return))
    6.             GetComponent<CinemachineImpulseSource>().GenerateImpulse(Camera.main.transform.forward);
    7.     }
    8. }
     
  3. Yuki_Rain

    Yuki_Rain

    Joined:
    Jul 25, 2017
    Posts:
    12
    Thanks a lot!
    So the key is set signal.asset Position Y only, and use the camera forward direction in Impluse function.;)
     
    Gregoryl likes this.
  4. NateReese77

    NateReese77

    Joined:
    Jun 14, 2017
    Posts:
    26
    Hello! I'm having a little trouble with aligning the Impulse with my Camera view. For instance, i want to have some z movement on my recoil, but when my character turns, the Z movement is different as its aligned to World Space. I am using GenerateImpulse with the Camera Forward for the Velocity. I've also tried GenerateImpulseAt, but that doesn't let me set orientation either. Thanks!
     
  5. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,559
    Is your impulse signal mainly on the Y axis? If it is, then it should shake the camera along the camera forward axis, since that is the velocity you give it.
     
  6. Yuki_Rain

    Yuki_Rain

    Joined:
    Jul 25, 2017
    Posts:
    12
    use camera.transform.forward as param in Impluse function
     
  7. jefferson-bitcake

    jefferson-bitcake

    Joined:
    May 25, 2021
    Posts:
    2
    ok, I can see that working for the recoil as the Y signal does seem to only move the camera on the forward axis no matter the orientation. However, the X and Z signals are not well behaved like this. Depending on the orientation of the camera the X signal changes widly the axis it affects. How could I get a "2d camera shake" on the X/Z plane of the camera (assuming Y is forward)?
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    5,559
    To shake the camera in the camera XY plane, put the shake in the X/Z axes of the signal, and use the camera Z direction as the direction of the impulse when you emit it. The shake should appear in the camera XZ plane.
     
  9. Yuki_Rain

    Yuki_Rain

    Joined:
    Jul 25, 2017
    Posts:
    12
    I found another way to simulate shake in Cinemachine, it's simple, predictable, easy to control.
    • add component CinemachineCameraOffset(in your virtualCamera GameObject),which will apply offset for your virtualCamera
    • modify the x y z component to simulate shake
     
unityunity