Search Unity

CineMachine - Base follow offset

Discussion in 'Cinemachine' started by daniel-griffiths, Apr 16, 2018.

  1. daniel-griffiths

    daniel-griffiths

    Joined:
    Jun 14, 2016
    Posts:
    27
    Hello,

    I am trying to change the follow offset of the camera via code based on whether i am in portrait or landscape.

    If anyone knows how to do this would greatly appreciated.
    Please advise.

    Many thanks

    Daniel
     
    owatui9987 likes this.
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Assuming that you are using an ordinary Transposer:
    Code (CSharp):
    1. CinemachineVirtualCamera vcam = ...;
    2. var transposer = vcam.GetCinemachineComponent<CinemachineTransposer>();
    3. transposer.m_FollowOffset = bla;
    If you're using a different thing in the Body section, replace "CinemachineTransposer" with the appropriate class.
     
    Last edited: May 6, 2021
  3. daniel-griffiths

    daniel-griffiths

    Joined:
    Jun 14, 2016
    Posts:
    27
    Perfect!

    Thank you

    Best

    Daniel
     
    Gregoryl likes this.
  4. duyanhpham235

    duyanhpham235

    Joined:
    Jul 21, 2019
    Posts:
    15
    Hi, I'm trying to change the offset of the aiming section via code but couldn't get it to work. The value did change when I printed it out but the camera's offset didn't change at all?. Do you have any idea why?
     
  5. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    vladzislavl10 likes this.
  6. duyanhpham235

    duyanhpham235

    Joined:
    Jul 21, 2019
    Posts:
    15
    Hi, Thanks for answering so quickly. I figured that out. Turns out, it didn't work because I get the trackedObjectOffset component on Awake() and made changes to that later on. I'm not sure why it doesn't work that way though?
     

    Attached Files:

  7. duyanhpham235

    duyanhpham235

    Joined:
    Jul 21, 2019
    Posts:
    15
    More importantly, I'm trying to achieve the following behavior:

    - I currently have 2 cameras, 1 freelook cam for third-person view on my character, 1 virtual cam for some special situations.

    - Normally, players will be using the freelook camera, but when those special situations do happen, I want to switch to virtual cam with the camera angle stay exactly the same as before switching. How can I achieve that?

    - For the virtual cam settings, I want it to only follow the character's position and not rotation. And no matter how crazy the character is rotating, the camera angle stays the same. I attached my current setting below.

    I'll try to record some video to show you exactly what I'm trying to achieve if these descriptions are not clear enough.
     

    Attached Files:

  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    It doesn't work the second way because you're just storing difference in a local variable. You want to set it in the Composer component.

    It's good for performance to get the vcam components in Start() instead of Update(), so you should fix that. Store the component in your class, and do _composer.m_TrackedObjectOffset = difference in Update().
     
  9. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    When you switch, you'll have to set the incoming vcam's offset to be outgoingVcamPos - targetPos, and use WorldSpace binding mode in the incoming vcam.
     
    Last edited: Jul 24, 2019
  10. duyanhpham235

    duyanhpham235

    Joined:
    Jul 21, 2019
    Posts:
    15
    Not sure what you meant by setting it in the Composer component. Can you rewrite it in the proper way please?
     
  11. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Code (CSharp):
    1. CinemachineComposer _composer;
    2.  
    3. void Start()
    4. {
    5.     _composer = vcam.GetCinemachineComponent<CinemachineComposer>();
    6. }
    7.  
    8. void Update()
    9. {
    10.     _composer.m_TrackedObjectOffset = difference;
    11. }
     
  12. duyanhpham235

    duyanhpham235

    Joined:
    Jul 21, 2019
    Posts:
    15
    I noticed a few things:

    - Setting the virtual camera to World Space and change only followOffset (and not trackedOffset) to (freelookPos - targetPos) gives me almost the exact same angle but not quite. It also doesn't behave like "Simple Follow with World Up" which is what I'm looking for.

    - Changing followOffset to (freelookPos - targetPos) with "Simple Follow with World Up" doesn' give me the right angle. Same result when changing both followOffset and trackedOffset to (freelookPos - targetPos).

    (UPDATE)

    - This is the result that I currently have after doing what you said. It's definitely better now but do you have any suggestion to make it better? I'm aiming to have the camera follow the character as stable as possible while it's flying after getting hit.

     
    Last edited: Jul 21, 2019
  13. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Thanks for the upload, but I don't really understand what I'm looking at, or how it was before, or exactly what you want.

    My current understanding is this:
    1. Player is being followed with a FreeLook
    2. When player is hit, you want to activate a special vcam that follows the player at a fixed worldspace offset, which is determined dynamically based on the freeLook position at the moment the player is hit
    3. You want the camera transition to be instantaneous, and invisible
    Is that right? If so, then you need to
    • Set the vcam's Transposer binding mode to WorldSpace,
    • Set the Aim to Composer, trackedObjectOffset = same thing as FreeLook's trackedObjectOffset
    • Set brain.defaultBlend = cut, or have a custom blend setting for vcam which is cut
    • When the player is hit:
      • Set vcam.GetCinemachineComponent<CinemachineTransposer>.m_FollowOffset to Camera.Main.transform.position - player.transform.position
      • Set vcam.PreviousStateIsValid=false
      • Activate vcam
    Still unclear: What should happen when FreeLook is re-enabled?
     
  14. duyanhpham235

    duyanhpham235

    Joined:
    Jul 21, 2019
    Posts:
    15
    Hey Gregoryl, sorry for late response. You understood it correctly. It's working as intended right now but I do have 1 more question. When the recoil camera is activated, we want it to zoom out as much as needed so that it fits both the person who gets hit and the one who shoot. How can I do that?

    Thank you
     
  15. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    You would need to scale the length of m_FollowOffset, taking into account the FOV, so that the frustum includes both targets. There's code in CinemachineFollowZoom that makes that calculation - have a look at it. Sorry I can't be more precise than that, I'm away and not on a machine that has code on it
     
  16. FeastSC2

    FeastSC2

    Joined:
    Sep 30, 2016
    Posts:
    978
    I simply want to offset the camera's final X and Z position so that the camera moves a bit towards the mouse's cursor.

    My camera is angled @ 55 degrees on my player and it uses the following component (FramingTransposer):
    upload_2020-11-25_0-39-57.png

    I used the m_TrackedObjectOffset but it only works when my character is facing forward. Apparently TrackedObjectOffset takes into consideration the orientation of the Transform it looks at.

    What can I do to displace the camera's position after it being moved by the Cinemachine Virtual Cam? (Like you would do with a normal gameobject using transform.position)
     
    Last edited: Nov 25, 2020
  17. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    You can't displace the camera, because the vcam will move it right back to where you said to put it. You have to tell the vcam to put it where you want it. With the FramingTransposer, you can dynamically adjust the ScreenX and ScreenY parameters. Alternatively, you can use an invisible game object as your actual target, and have a script that positions that in relation to the player.