Search Unity

Virtual Camera Look Around Function (Hotline Miami-like)

Discussion in 'Cinemachine' started by TimHellmann, Oct 31, 2017.

  1. TimHellmann

    TimHellmann

    Joined:
    Mar 6, 2011
    Posts:
    66
    Labpets_Camera_Offset.png Good morning, good afternoon, good evening, good night, dear wonderful developers.

    I want to go a bit into detail with the VCAM functionality. The camera is focused on my player character. It is 2.5D, the virtual camera is of course linked to the Cinemachine Brain and follows the player's Vector2 position. That already works very nicely, also when switching between VCAMs.

    Now I want to add a look around function. That look around should be limited by an invisible 'circle' around the player, similar to what Hotline Miami did. Can simply be an offset limit float that is calculated from the mouse / C-Stick position.

    Sadly, a method like ScreenToWorldPoint is not available for Cinemachine / Virtual Cameras as far as I could see, as I cannot move the VCAM via code manually. I think I might use the Body->Transposer offset values for that but could not figure out how to do so. So has anyone successfully implemented a function like this yet? Could you help me building it?

    I attached an image to show you what I would like to achieve. The circle is the camera offset limit (say 1.0f from transform.position), the + should be the actual camera focus / position / lookat based on the example inputs.
    Thanks in advance.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,724
    Given that the Cinemachine vcam is driving a Unity camera, you can always just get the camera and use its ScreenToWorldPoint method. However, I don't think you're going to need it for this.

    I would attack this by adding a custom CinemachineExtension to offset the camera from the target. Here is some code that does that.
    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3. /// <summary>
    4. /// An add-on module for Cinemachine Virtual Camera which post-processes
    5. /// the final position of the virtual camera.
    6. /// </summary>
    7. [ExecuteInEditMode]
    8. [SaveDuringPlay]
    9. public class CameraOffsetter : CinemachineExtension
    10. {
    11.     [Tooltip("How much to offset the camera, in camera-local coords")]
    12.     public Vector3 m_Offset = Vector3.zero;
    13.     protected override void PostPipelineStageCallback(
    14.         CinemachineVirtualCameraBase vcam,
    15.         CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
    16.     {
    17.         if (enabled && stage == CinemachineCore.Stage.Aim)
    18.             state.PositionCorrection += state.RawOrientation * m_Offset;
    19.     }
    20. }
    I'm assuming you're using Cinemachine 2.1. Drop this into your project as CameraOfsetter.cs, then use the vcam inspector's Extensions dropdown to add the new extension.

    All you have to do is to drive m_Offset based on the mouse/ C-Stick position. Let us know how that works for you.
     
  3. TimHellmann

    TimHellmann

    Joined:
    Mar 6, 2011
    Posts:
    66
    Thank you for that first code draft, Gregory.
    Assuming I have one Cinemachine Brain as a parent (also holding the Unity Camera component) and multiple vcams as children that all focus an individual player characters, I just add that script to the brain, is that correct?

    I'll let you know how it works as soon as we tested it.
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,724
    No, that structure is wrong.

    Unity camera has a CinemachineBrain component.
    Your vcams are NOT children of the main camera. They should live elsewhere.

    upload_2017-10-31_13-16-55.png

    On the vcam, add CameraOffsetter as an extension (via the vcam inspector).

    upload_2017-10-31_13-16-22.png

    You will need a script to drive the m_Offset of the offsetter. I would suggest just to put that as a component on the vcam, alongside the offsetter.