Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  6. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  7. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  8. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

How to shake camera with cinemachine?

Discussion in 'Cinemachine' started by Tak2017, Jul 29, 2017.

  1. Tak2017

    Tak2017

    Joined:
    Mar 30, 2017
    Posts:
    6
    Hello,Can anyone help me with this?
    I used to shake camera with script when the charactor was hit by attack,
    After using cinemachine the script doesn't work,How can I shake the camera with cinemachine?
     
    vlad010694 likes this.
  2. JakubSmaga

    JakubSmaga

    Joined:
    Aug 5, 2015
    Posts:
    383
    Use the Noise module.
     
    Last edited: Dec 10, 2017
  3. sebsmax

    sebsmax

    Joined:
    Sep 8, 2015
    Posts:
    61
    hey @Tak2017, got the same issue, this is what I've done:
    • In the freeCamera, go and add a noise pattern, put AmplitudeGain and FrequencyGain to 0.
    • Add the following code in your camera function
    • launch the code with a "StartCoroutine(_ProcessShake (5, 0.5f) );"
    Code (CSharp):
    1.  
    2.  
    3.         private IEnumerator _ProcessShake(float shakeIntensity = 5f, float shakeTiming = 0.5f)
    4.         {
    5.                 Noise(1, shakeIntensity);
    6.                 yield return new WaitForSeconds(shakeTiming);
    7.                 Noise(0, 0);
    8.         }
    9.  
    10.         public void Noise(float amplitudeGain, float frequencyGain)
    11.         {
    12.             cmFreeCam.topRig.Noise.m_AmplitudeGain = amplitudeGain;
    13.             cmFreeCam.middleRig.Noise.m_AmplitudeGain = amplitudeGain;
    14.             cmFreeCam.bottomRig.Noise.m_AmplitudeGain = amplitudeGain;
    15.              
    16.             cmFreeCam.topRig.Noise.m_FrequencyGain = frequencyGain;
    17.             cmFreeCam.middleRig.Noise.m_FrequencyGain = frequencyGain;
    18.             cmFreeCam.bottomRig.Noise.m_FrequencyGain = frequencyGain;      
    19.  
    20.         }
    21.  
    22.  
     
    vlad010694 likes this.
  4. Tak2017

    Tak2017

    Joined:
    Mar 30, 2017
    Posts:
    6
    Thanks very much! I'll try this!
     
  5. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    @Tak2017 Don't take the syntax in the example too literally. Have a look at Cinemachine/Examples/Scenes/Scripting/ScriptingExample.cs for the correct syntax for accessing CM camera component members.
     
    vlad010694 likes this.
  6. Tak2017

    Tak2017

    Joined:
    Mar 30, 2017
    Posts:
    6
    I want to shake strongly in very short time like 6 to 10 frames,not the handheld style.Thank you all the same~
     
  7. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
  8. Tak2017

    Tak2017

    Joined:
    Mar 30, 2017
    Posts:
    6
    Thanks for your reply!I'll Try this,and post my progess later,thank you!
     
  9. vlad010694

    vlad010694

    Joined:
    Nov 14, 2017
    Posts:
    1
    @sebsmax @Tak2017 @Gregoryl Thank you!

    Code (csharp):
    1.  
    2. CinemachineVirtualCamera vcam;
    3. CinemachineBasicMultiChannelPerlin noise;
    4.  
    5. void Start() {
    6.         vcam = GameObject.Find("CM vcam1").GetComponent<CinemachineVirtualCamera> ();
    7.         noise = vcam.GetCinemachineComponent<CinemachineBasicMultiChannelPerlin> ();
    8. }
    9.  
    10. public void Noise(float amplitudeGain, float frequencyGain) {
    11.         noise.m_AmplitudeGain = amplitudeGain;
    12.         noise.m_FrequencyGain = frequencyGain;    
    13. }
    14.  
     
    kirillrybin likes this.
  10. Meatgrind

    Meatgrind

    Joined:
    Jul 12, 2012
    Posts:
    41
    Duplicating my post here from https://forum.unity.com/threads/how-to-enable-camera-noise-via-script.495032/#post-3416215

    @Gregoryl You suggest to use the BasicMultiChannelPerlinNoise extension component, which is fine in this kind of setup where you have a Scene with one VirtualCamera that is always shaking.

    I'm looking for more of game-event driven camera shake to make short-duration events during play more impactful, like player getting damage, things breaking, final hits when defeating enemies, explosions happening.

    The thing is that there is a vast amount of Scenes, each with similarly large number of VirtualCameras, and some VirtualCameras are actually already using the noise component for something else that they need to emphasize.

    I'd like to setup a system where I can pretty much call CameraShake.Shake(someShakeTemplateParameter) where someShakeTemplateParameter is probably a ScriptableObject with various intensity and duration variables set up so I can call "CameraShake.Shake(playerHitShake);" or "CameraShake.Shake(hugeExplosion);" and such in code where enemies hit or bombs go off.

    I already threw together a class that tries to do a lot of things, like:
    • look for a CameraBrain to get the active VirtualCamera from
    • tracks Scene changes to re-look for a new CameraBrain and check for all other current references
    • tracks current CameraBrains VirtualCameraActivation event to check if it needs to Add or Get a new BasicMultiChannelPerlinNoise component for the current VirtualCamera
    • Hijacks the BasicMultiChannelPerlinNoise component and forces a new noise profile, new amplitude and new frequency values, storing the old values
    • restores the old values after a duration
    • etc.
    The system is not perfect by a long shot. It's easy to lose track of a VirtualCamera before restoring something and my quickly implemented system already managed to fail a couple of tests for tracking the VirtualCamera changes, so there's somewhere a on-standby VirtualCamera shaking wildly, while the active one no longer shakes when expected to.

    Yeah, I will probably try to improve my system to use your recommendation of VirtualCamera noise for camera shake, but it's a lot of work, breaks using the noise for other purposes, requires constantly adding/getting a ton of component references and I feel there has to be a better way.
     
  11. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    There is very much a better way. Cinemachine has moved forward since the recommendation of using BasicMultiChannelPerlinNoise for camera shakes, and I would no longer recommend that approach.

    Right now in development is the Cinemachine Impulse system, which does something very much like what you describe (i.e. scriptable-object Shake definitions, and the ability to broadcast shakes to all active cameras). It really is exactly what you need. However, it's not quite ready for prime-time so I can't let you give it a spin just yet. But it's pretty close.

    If you're in a hurry to get something up and running now, I would suggest the following approach:
    1. Forget about using the BasicMultiChannelPerlinNoise component, for all the reasons you outline. Throw that idea away.
    2. Use the CinemachineExtension API to write a camera shaker. I'll include a simple example below, that shakes the camera continuously. Use that as a starting point for your extension.
    3. Instead of shaking the camera continuously, have the shaker extension query a singleton for current active "shakes", and apply the signal to the vcam.
    4. The "CameraShake(shakeDefinition) method could live on the singleton. Your game code would call it to initiate shakes.
    5. The key is not to push the shakes to the vcams. Let them listen for shakes instead, via the CameraShake extension. Put that extension on all your vcams. It won't interfere with any Perlin Noise that's on the vcams.
    That would be a baby version of the Impulse system. Of course you could just wait a few weeks for the real deal instead of home-brewing. Here is the sample extension I mentioned:
    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3.  
    4. /// <summary>
    5. /// An add-on module for Cinemachine to shake the camera
    6. /// </summary>
    7. [ExecuteInEditMode] [SaveDuringPlay] [AddComponentMenu("")] // Hide in menu
    8. public class CameraShake : CinemachineExtension
    9. {
    10.     [Tooltip("Amplitude of the shake")]
    11.     public float m_Range = 0.5f;
    12.  
    13.     protected override void PostPipelineStageCallback(
    14.         CinemachineVirtualCameraBase vcam,
    15.         CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
    16.     {
    17.         if (stage == CinemachineCore.Stage.Body)
    18.         {
    19.             Vector3 shakeAmount = GetOffset();
    20.             state.PositionCorrection += shakeAmount;
    21.         }
    22.     }
    23.  
    24.     Vector3 GetOffset()
    25.     {
    26.         // Note: change this to something more interesting!
    27.         return new Vector3(
    28.             Random.Range(-m_Range, m_Range),
    29.             Random.Range(-m_Range, m_Range),
    30.             Random.Range(-m_Range, m_Range));
    31.     }
    32. }
    33.  
     
    Last edited: Mar 7, 2018
    DeviTobi and Alverik like this.
  12. Meatgrind

    Meatgrind

    Joined:
    Jul 12, 2012
    Posts:
    41
    Wow, that's a fantastic response! Thank you for staying civil in the face of my rant and providing such a prompt, informative and immediately helpful answer!

    We're running on a deadline, so I don't quite have the time to roll my own at this point, nor can I simply wait for two weeks, but your example will tide my needs over as a nice compromise. I'll use that to implement a quick temporary solution and hope that your Impulse system will be available in two weeks - if not, I'll scramble to improve the slap-patch solution, but at least now I don't have an immediate need to allocate much time for it. :)
     
    Gregoryl likes this.
  13. Smoole

    Smoole

    Joined:
    Nov 3, 2017
    Posts:
    5
    @Gregoryl Any updates on the Cinemachine Impulse System that you can share? Any ETA? :p
     
  14. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    Yes, it will be there in the next CM release, to coincide with Unite Berlin.
    It's possible that there will be some preview releases prior to then.
     
    Alverik and JakubSmaga like this.
  15. max_mcguire

    max_mcguire

    Joined:
    Sep 17, 2015
    Posts:
    3
    Did this feature make it into 2.1.12?
     
  16. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    No, but it's on the verge.
     
  17. sandBucket2

    sandBucket2

    Joined:
    Mar 26, 2016
    Posts:
    11
    Hey Greg, quick question on the code you posted:

    Which object do I attach this script? Would it be one of the virtual cams? Would I call this class in another script and pass it the virtual cam? Also how would I control the time to shake? Would I Slerp the total shake over a set amount of time using a while loop in a coroutine?

    Let me know and thanks!
     
  18. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    @sandBucket2 You just drop the script in your project, and it will show up in the virtual camera "Extensions" menu. Add it to the vcam from there.

    For making a pulse, you would need to set an amplitude and a duration. I would decay the amplitude over the course of the duration, not necessarily with a lerp, as that would look mechanical. Use some kind of exponential damping. You could do that animation in a coroutine, as you suggested. It will only shake the vcam it's attached to.
     
  19. sandBucket2

    sandBucket2

    Joined:
    Mar 26, 2016
    Posts:
    11
    Thanks! Also an offtopic question:

    I've tried to import the latest post processing stack (v2) off github but I keep getting this error after import: Assets/PostProcessing/CinemachinePostFX.cs(45,28): error CS0234: The type or namespace name `PostProcessing' does not exist in the namespace `UnityEngine'. Are you missing an assembly reference?

    I'm using Unity 2017 but I've heard that cinemachine works with the v2 stack on 2017. How would I go about fixing this?
     
  20. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    If you're using Post v2 then you can just delete the file that's generating the errors. It's for Post v1 and you don't need it.
     
  21. sandBucket2

    sandBucket2

    Joined:
    Mar 26, 2016
    Posts:
    11
    Thanks again, last question: are there any other files that I should delete from the cinemachine folder to prevent unwanted interactions between the cinemachine scripts? Also which version of the post processing stack v2 should I use for the cinemachine I've downloaded on 2017 Unity?
     

    Attached Files:

  22. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    Nothing more to delete afaik.

    At one point there was a mechanism for auto-detecting which Post version was installed. That was a little naive and seems to be backfiring, as it's depending on script defines which don't get cleaned up when stuff is uninstalled.

    Use whichever version of Post V2 has the features you need. CM is pretty agnostic. Probably the latest stable release is fine.
     
  23. sandBucket2

    sandBucket2

    Joined:
    Mar 26, 2016
    Posts:
    11
    Thanks, I got it to work :)

    I've been using cinemachine for a while now and I've noticed that it calls GUI.Repaint during runtime. I've seen from other threads that this should only happen during the editor and not during runtime, how would I go about fixing this?

    Here's the deep profile from runtime:
    upload_2018-5-20_10-45-42.png

    The GUI.Repaint() method is happening every frame and spikes every 10 seconds during runtime.
     
    Last edited: May 20, 2018
  24. sandBucket2

    sandBucket2

    Joined:
    Mar 26, 2016
    Posts:
    11
    Following up from my last post, I ended up commenting out 5 instances of #if UNITY EDITOR regarding OnGui on:
    -CinemachineVirtualCameraBase.cs
    -CinemachineComposer.cs
    -CinemachineBlendListCamera.cs
    -CinemachineStateDrivenCamera.cs
    -CinemachineClearShot.cs

    when I commented out those blocks of code, the GUI.Repaint() was gone and I started getting stable framerate, however, have I removed something important from the editor when I did that? Any loss of functionality to the virtual camera in scene view? I can't tell, everything seems fine.

    Its noted in the CinemachineVirtualCameraBase.cs that OnGUI() was called as "Support for the deprecated CinemachineDebugger". Since I commented out the #if UNITY EDITOR on those files, are there other things I need to comment out like delegates or declared actions?

    Let me know and thanks!
     
  25. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    The only things you're losing are the Composer Guides and some of the "current vcam" debug text in the upper left of the game screen. If you want the composer guides back then you need to uncomment OnGUI in CinemachineComposer.

    And remember, even if you don't comment anything out, Cinemachine won't ever call OnGUI in builds, since it's protected by #if UNITY_EDITOR.
     
  26. sandBucket2

    sandBucket2

    Joined:
    Mar 26, 2016
    Posts:
    11
    Hey Greg,

    Sorry about bumping this thread but I'm at the part where I add the camera shake.

    So I've noticed you mentioned that the script you provided shakes the camera continuously, therefore I assume that the PostPipelineStageCallback() method gets called every frame? Would I just add a public boolean called toggleShake and have PostPipelineStageCallback() check for the boolean each frame?

    Code (CSharp):
    1. protected override void PostPipelineStageCallback(
    2.         CinemachineVirtualCameraBase vcam,
    3.         CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
    4. {
    5.     if(toggleShake)
    6.     {
    7.         if (stage == CinemachineCore.Stage.Body)
    8.         {
    9.             Vector3 shakeAmount = GetOffset();
    10.             state.PositionCorrection += shakeAmount;
    11.         }
    12.     }
    13. }
    toggleShake would be set in another class within a coroutine lasting 1.5 seconds by doing:
    Code (CSharp):
    1.  
    2. vcam3.cameraShake.toggleShake = true;
    3. yield return new WaitForSeconds(1.5f);
    4. vcam3.cameraShake.toggleShake = false;
    5.  
    I'm not sure if that's the correct way to target the virtual camera's extension. Let me know how to go about doing this and thanks.
     
    Last edited: Jun 16, 2018
  27. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    Yeah, something like that should work.

    HOWEVER, you're much better off scrapping all this and using the new Cinemachine Impulse module that comes with CM 2.2.0, which has just been released :D
     
    Last edited: Jun 20, 2018
    sarum, Alverik and sharkapps like this.
  28. sharkapps

    sharkapps

    Joined:
    Apr 4, 2016
    Posts:
    85
    @Gregoryl that is great news! Is there any update on the availability of the GameRig plugin?
     
  29. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    The GameRig plugin is now part of the CM core. Is there specific functionality that you're looking for?
     
  30. sharkapps

    sharkapps

    Joined:
    Apr 4, 2016
    Posts:
    85
    Well I have known about Cinemachine for a while now, but am just now starting to figure out how to use it in a game.

    Hi @Gregoryl
    I want a camera that the user can rotate around the target and zoom in/out. Each target (vehicle) probably needs to have its own top/middle/bottom orbit and zoom values, depending on the size of the target. I am working on a script now that changes the orbit height and radius for the 3 rigs in the freelook camera.

    As I went through the Cinemachine documentation, i read about the planned Game Rig plugin and the Reactor camera type sounds like it might be ideal. Of course I will want to have Camera Shake as well.

    Is there more documentation on how to use Game Rig features somewhere?

    Best regards,
    Tony
     
  31. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    Last edited: Jun 20, 2018
  32. AskAnEnemyStudios

    AskAnEnemyStudios

    Joined:
    Aug 11, 2015
    Posts:
    11
    Hey @Gregoryl First and foremost thanks for this insanely awesome stuff. I've been waiting for the impulse system and finally updated to 2018 just for this. How on earth do you use the Impulse. I can't find documentation and that specific feature.
     
  33. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    Yes, the official doc for Impulse is still being baked. Until it's shipped, you have 3 resources at your disposal:
    1. The Impulse example scene that comes with the CinemachineExamples,
    2. This forum,
    3. Also, here is a preliminary overview doc that should help you wrap your head around his very powerful and versatile tool.
     

    Attached Files:

    Last edited: Jun 20, 2018
  34. AskAnEnemyStudios

    AskAnEnemyStudios

    Joined:
    Aug 11, 2015
    Posts:
    11
    Thanks man!!! ;)
     
  35. AskAnEnemyStudios

    AskAnEnemyStudios

    Joined:
    Aug 11, 2015
    Posts:
    11
    @Gregoryl Magic. Absolute F***ing magic. Thanks man. This is some unbelievably awesome tech. I would clap but my arms would fall off. Sincerely thanks for your work. :)
     
    Gregoryl likes this.
  36. sarum

    sarum

    Joined:
    Mar 2, 2014
    Posts:
    183
    very happy to hear that impulse has been released ... cool :)
    thanks guys !!

    on a side note .. any chances that you guys could release some Playmaker actions once in a while ? Some that are updated and in synch with the latest Cinemachine releases and features ... it would be very useful .. we are many :p

    have a good day
     
  37. unity_Bd4u0gbzOXOWtw

    unity_Bd4u0gbzOXOWtw

    Joined:
    Feb 21, 2018
    Posts:
    1
    Hello. Just downloaded Cinemachine and can't find the impulse script and cannot call any of Cinemachine methods through script because the environment can't find it. I tried to import in script with "using" but nope... giving errors. Am I missing something I believe?

    Edit 1: Just solved my problems but still struggling to make this work. Maybe need some time working with this, but it's amazing so far.
     
    Last edited: Jul 4, 2018
  38. GuardHei

    GuardHei

    Joined:
    Feb 10, 2018
    Posts:
    23
    @Gregoryl Great work! But I've got two questions after reading that User Guide.

    1. What is the difference between the Vector3 parameter Velocity in GenerateImpulseAt() method and the Amplitude Gain parameter of the script Cinemachine Impulse Source? If I want to adjust the strength of the impulse, which parameter should I change?

    2. What does the Direction Mode affect? I've tried both modes but can't find the difference.

    Looking forward to the official documentation!
     
  39. sarum

    sarum

    Joined:
    Mar 2, 2014
    Posts:
    183
    me too :)
     
  40. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    1,416
    Good questions both.

    1. The way to think about it is this: Imagine striking something, say a rubbery wall with a hammer. The vibrations in the wall will be mostly along the axis of the hammer motion path, so the direction of the strike is important.

    When you define an impulse signal, you have access to 3 worldspace axes, X, Y, and Z. If you craft an impulse signal to represent the hammer strike, you will want to give prominence to one of the axes, to reflect the property that most of the vibrations will be along the path of the hammer. In impulse, we assume that the "main" axis is Down, so you'll put more vibration in Y (that's what the "6D Shake" preset does, incidentally).

    So now you have a global signal that emphasizes the world Y axis, and a specific hammer strike that has some arbitrary direction. That's where the Velocity parameter comes in. It defines the direction of the impulse (the local "Down", if you will) for that specific instance. Impulse will rotate the signal to match the signal's Down to the velocity direction, producing a vibration that's correct for that specific impact.

    Now the amplitude. Setting Amplitude Gain on the signal will simply scale the whole signal, all the time, irrespective of the impact velocity. Setting the magnitude of the Velocity vector will also scale the amplitude, but it's per impact, not global. This allows you to set things up so that light impacts make smaller vibrations, and heavy impacts make bigger ones. Effectively the two scale values will multiply together. So the difference is that one is a global knob, the other is a per-impact tuning knob.

    2. Direction mode is very subtle. If you set it to Fixed, the direction of the vibration (the local rotation of the signal, as described above) will be in the direction of the velocity passed to the GenerateImpulse() method. This is the normal operation, what one would expect.

    RotateTowardsSource adds on top of that a subtle psychological effect: it will further rotate the vibrations to point a little more in the direction of the source. For radially symmetric vibrations, this change won't be noticeable, but for vibrations that emphasize a direction (like 6D shake), it has the effect of providing a subconscious indication to the player of where the vibration is coming from. We have found it to be quite effective when impacts are happening from various places and you don't want them to all feel the same.
     
    Last edited: Aug 3, 2018
    GuardHei likes this.
  41. GuardHei

    GuardHei

    Joined:
    Feb 10, 2018
    Posts:
    23
    Thanks! The explanation is really clear and detailed!:)