Search Unity

Having issues trying to customize some Cinemachine scripts

Discussion in 'Cinemachine' started by Jamez0r, Jan 2, 2021.

  1. Jamez0r

    Jamez0r

    Joined:
    Jul 29, 2019
    Posts:
    206
    Hi guys, I'm switching from an orthographic camera to a perspective camera on my 2D game (for easier parallaxing), and I'm running into two issues - I have solutions for both of these issues, but I'm having problems actually implementing the solutions - I can't figure out how to customize/make custom versions of the Cinemachine scripts.

    1) I'd like to continue using the 2D Confiner even though I'm switching to a perspective camera. I found this post that @Gregoryl mentions how to do it (https://forum.unity.com/threads/perspective-vcams-with-2d-confiners.508804/#post-3324042), essentially customizing the CinemachineConfiner. My problem is that when I try to modify CinemachineConfiner, as soon as I save and Unity recompiles, the script gets reset back immediately:

    So instead I tried to make my own script, and copy the contents of the original CinemachineConfiner into it, and then customize it from there. But the code just shows up as all grey in Visual Studio.



    2) I'm using a CinemachineTargetGroup, and I noticed that when I change the "radius" of the target, it causes the camera to move on the Z-axis. I would like to keep my camera locked at Z = -10. I figured I could customize the CinemachineTargetGroup to just set the final Z position after it has done its normal position calculations, but I'm having the same issues as problem #1 above, where the script gets changed back after I edit it.

    Any ideas on what I could do? Thanks a lot!
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,720
    You can't change scripts within read-only packages because these packages can be shared by multiple projects. As you have discovered, Unity will revert your changes. The correct way to modify code in a package is to first embed the package into your project by copying the entire package to your project's local Packages directory. Then you will be able to modify the code without impacting other projects that might potentially use the package.

    However, that is really a last resort, and in your case I would not recommend modifying Cinemachine.

    1) You can use the new CinemachineConfiner2D extension, which works with perspective cameras. That should work for you without the need to modify any Cinemachine code. If you really insist on making your own script based on it, you can fix the grey-out issue by removing the
    #if !UNITY_2019_3_OR_NEWER
    line at the top.

    2) Changing CinemachineTargetGroup is unlikely to be the answer. Instead, you have to instruct your vcam to not move on the z axis. Can you show me the inspector for the vcam?
     
    gaborkb likes this.
  3. Jamez0r

    Jamez0r

    Joined:
    Jul 29, 2019
    Posts:
    206
    Thanks @Gregoryl for the reply and hope your holidays went well :)

    1) There's nothing better than simply updating a package and having a new component that does exactly what you need to do. The CinemachineConfiner2D works great! Thanks a lot for adding the perspective-cam functionality.

    One thing I was curious about - I'm using Unity 2020.2, and when I opened my package manager, Cinemachine version 2.7.1 wasn't listed. It only showed my current version 2.6.3 (even when I clicked "see other versions"). I then went into the advanced settings and Enabled Preview Packages, and 2.7.1 then showed up but it wasn't marked as Verified or Preview (screenshot below). Is that normal? Is it a Preview or a released version? Just curious about this - I updated and the new component works great.



    2) Here is the inspector for the VCam:



    Thanks again for the help, seriously appreciate it! :D
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,720
    1) It's not a bug. 2.6.3 is the verified version for 2020. CM 2.7.1 is a full CM release.

    2) Your problem is here. Change it to Zoom Only or None.

    upload_2021-1-4_15-58-32.png
     
  5. Jamez0r

    Jamez0r

    Joined:
    Jul 29, 2019
    Posts:
    206
    Ahh, understood. Thanks!


    Thank you - I understand what is going on in that section of the VCAM better now.

    For anyone that might also be in my situation - I'm working on a 2D game with perspective camera. To "zoom" I am changing the FoV value ("Lens Vertical FoV"), and I don't want any of the group-framing to affect the FoV or Z-position of the camera. I changed Group Framing Mode to None, which still centers the camera correctly on the X/Y axis based on the group targets' position/weight/radius, but no longer affects the Z-position of the camera.

    Thanks @Gregoryl - saved me a couple hours of work here!
     
    Gregoryl likes this.
  6. Liderangel

    Liderangel

    Joined:
    Jul 8, 2018
    Posts:
    101
    Hey, sorry to steal up your thread @Jamez0r but I'm about to do the same thing (copy the entire Cinemachine out of Packages). I don't really want to do it because what I'm looking to do is so simple that perhaps there is already a solution inside Cinemachine that we couldn't find.

    I want to also zoom using the Lens FOV on the CMVCAM, unfortunately the Cinemachine Brain only updates the Lenses if the Cinemachine Brain script is attached to the same one as the Main Camera (there is a GetComponent<Camera>() in the OnEnable()).
    I tried modifying the Brain's script to a GetComponentInChildren<Camera>() (since in our Hierarchy setup we have the Main Camera as a child of the Brain) and it did work, but then Unity reverted everything :(.
     
  7. Jamez0r

    Jamez0r

    Joined:
    Jul 29, 2019
    Posts:
    206
    I see your issue, and tested it out and had the same result - with the Brain on the parent of the Camera, the camera would follow the VCAM's position but not its lens fov. The only thing I could think to try was to place the Brain on the same object as the camera, and then move the Brain to the parent gameobject (by dragging the Brain component), but this did not work - as soon as it was moved the lens fov immediately stopped being applied.

    Maybe @Gregoryl could comment any other ideas, but I can't think of a different way to do it - maybe some sort of hacky way of setting the private m_OutputCamera using reflection... but that could be weird to do :confused:
     
    Liderangel likes this.
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,720
    Can I ask why you need to have the CM Brain on a child object?
     
  9. Liderangel

    Liderangel

    Joined:
    Jul 8, 2018
    Posts:
    101

    Due to our Screen Shake solution (it defaults to 0, 0, 0, but when it's on the same one as the Brain it doesn't). We tried migrating to the Impulse system, which is really advanced and fantastic to work with, but the work was too much due to the stage the project is, and this solution I found is so simple and takes like 5 seconds to implement.
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,720
    You can have your shake code directly modify the Camera's transform, even with the CM Brain on it, provided that you do it very late in the frame - specifically after CinemachineBrain has set its position. You can do that either by shaking in LateUpdate and setting the shaker script's execution order to be after CinemachineBrain, or by using
    CinemachineCore.CameraUpdatedEvent
    , which is invoked immediately after the camera has been positioned. At that point, you are free to modify the camera's transform for that frame.

    Wouldn't that be easier than copying and modifying the CM package?
     
  11. Liderangel

    Liderangel

    Joined:
    Jul 8, 2018
    Posts:
    101

    I tried both of these, and the later one did worked. But now I faced the issue that our own CameraController (which basically moves a CVCAM in relation to the Player) had no effect on the Main Camera that has the Brain due to the Shaker applying afterwards our Controller finished it's routine.

    But, fear not, @Jamez0r gave me a brilliant idea with the reflection, I just:

    Code (CSharp):
    1. typeof(CinemachineBrain).GetField("m_OutputCamera", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(FindObjectOfType<CinemachineBrain>(), mainCamera);
    And that's it, with that everything worked 100% perfectly. I'm not a big fan of the solution but it's a small one time thing (even to the point where this is the first time ever using Reflection in all my C# years, so I quite enjoyed the trip learning about that).
     
    Rigobert0 likes this.
  12. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,720
    If you're happy with the reflection solution, that's fine, but you should note that reflection may come with a performance penalty (even if you only use it once, at runtime it may impact performance after it has been used).

    If you write the shaker code correctly it should only perturb the camera position - not overwrite it completely - so that the CM Brain's action is preserved.

    However, we will make a note of the feature request to customize the camera object.
     
    Liderangel likes this.
  13. Liderangel

    Liderangel

    Joined:
    Jul 8, 2018
    Posts:
    101

    Even if the code is only on Start? Interesting.


    If the feature request comes to life it would be much appreciated certainly.
     
  14. Rigobert0

    Rigobert0

    Joined:
    Jul 10, 2019
    Posts:
    1

    We also would benefit for that feature request! The reflection solution worked so well and it was so easy/fast to implement that we would love to see a Get/Set for that target from the Cinemachine team to avoid that change of a performance penalty (which we haven't noticed at all but just in case).
     
    Liderangel likes this.