Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Limited Orbital Camera

Discussion in 'Cinemachine' started by SeaCapn, Nov 11, 2017.

  1. SeaCapn

    SeaCapn

    Joined:
    May 20, 2017
    Posts:
    2
    There doesn't seem to be a very effective way to confine the orbital camera to a certain heading. Currently we are trying to set up a targeting system where the player's view is confined to a slice of the orbital camera whilst locked on using a target group. We've tried using the confiner, however that had some strange results. Namely that it looped. Are we going about this the wrong way? If not this would be a great feature for any behind the shoulder games.
     

    Attached Files:

  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Yes it would be a good idea to have limits on the orbit range. We will include this in an upcoming version. In the meantime, you could probably do it quite nicely by clamping the input channel. Normally, it goes form 0 to 1. If you make it go from 0.167 to 0833 then you will get the behaviour that you're looking for.

    Cinemachine provides a delegate that you can override in order to intercept the user input. See CinemachineCore.GetInputAxis().
     
  3. SilasBaker

    SilasBaker

    Joined:
    Sep 27, 2015
    Posts:
    1
    Thanks for getting back to us! I tried overriding the axis input and sending 0 when the angle of the camera was greater than the angle we wanted, however, I ran into the issue where if the camera went too far, or managed to get outside of that range (which happened a lot) we lost input control because it only sent 0.

    This is what I tried:
    Code (CSharp):
    1. float angle = Vector3.Angle(playerBackwards, projectedCameraDir);
    2.  
    3.         if (axisName == "Mouse X")
    4.         {
    5.             float axis = UnityEngine.Input.GetAxis(axisName);
    6.             float value = angle > minAngle ? angle < maxAngle ? axis : 0 : 0;
    7.             return value;
    8.         }
    9.         else if (axisName == "Mouse Y")
    10.         {
    11.             float axis = UnityEngine.Input.GetAxis(axisName);
    12.             float value = axis;
    13.             return value;
    14.         }
    I looked into the AxisState and found a variable called Value, which seems to be what I might want to limit. I found that it is confined by a min and a max that is set through SetThresholds(). I tried changing the min and max values passed to it but chaos and spinning ensued. The other strange thing, is that "Value" in the inspector is always 0 for the x axis on all of our free looks, yet for Y it appears to update in inspector fine.
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    @SilasBaker I think my first answer was a little hasty, and that I misled you. Sorry about that. It's not the input value that you want to limit, but rather the axis value.

    So first thing: if your FreeLook binding mode is set to "simple follow with world up", then the 0 heading is defined by the camera position relative to the target. That means that the X axis value is 0 when the camera is where it is (i.e all the time). Heading clamping is meaningless in that mode, and messing with the value will make it spin.

    You need to change the binding mode to something else, then the heading becomes meaningful and you can clamp it. From your picture it's not clear whether the Z axis you drew is in world-space, or target space. I'll assume it's target space. In that case, set the binding mode to "lock to target with world up". That will cause the X axis 0 value to mean: directly behind the target.

    Next, you need to clamp the xAxis value every frame. Unfortunately setting min and max limits won't work because you want to block out a section in the middle of the range, not at the ends. Here is a simple script that does the job. Add it to your FreeLook.
    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3.  
    4. public class ClampFreeLookX : MonoBehaviour
    5. {
    6.     CinemachineFreeLook mFreeLook;
    7.     [Range(0, 360)]
    8.     public float deadZoneSize = 60;
    9.  
    10.     // Use this for initialization
    11.     void Start()
    12.     {
    13.         mFreeLook = GetComponent<CinemachineFreeLook>();
    14.     }
    15.    
    16.     // Update is called once per frame
    17.     void Update()
    18.     {
    19.         float halfDeadZone = deadZoneSize / 2;
    20.         float axis = mFreeLook.m_XAxis.Value;
    21.         if (axis > 180)
    22.             axis = Mathf.Max(axis, 180 + halfDeadZone);
    23.         if (axis < 180)
    24.             axis = Mathf.Min(axis, 180 - halfDeadZone);
    25.         mFreeLook.m_XAxis.Value = axis;
    26.     }
    27. }
     
  5. Mad_Mark

    Mad_Mark

    Joined:
    Oct 30, 2014
    Posts:
    484
    I am trying to do a spaceflight simulator. I have a cockpit model viewed using the MainCamera placed within the model, uGUI world-space canvas, panels and buttons. It works great.

    I added two Virtual Cameras, one for the cockpit, and one for the exterior cut-scene that I am trying to make that kicks in when the player hits a trigger collider and selects "Yes" when prompted to land.

    The cutscene works great. The cockpit camera that is now a virtual camera does not. I have change its binding mode to Lock To Target, so that when I move up/down/side-to-side, the camera follows tightly. The cockpit canvas is set as the Look At target, and the model is set as the follow target. That part seems to be working.

    Single frame in edit mode:
    upload_2018-1-12_9-56-15.png
    As soon as I add power to the engines and start moving forwards, the v-cam sits back, and is propelled through the cockpit chair. Then it pops in and out, in and out of the chair.

    Frame1 in play mode:
    upload_2018-1-12_9-57-48.png

    Frame2 in play mode:
    upload_2018-1-12_9-58-34.png

    Is there a way to lock the z axis of the virtual cam so that it remains stationary in relation to the cockpit?
    Is there a better, or recommended way to use this new tool? (This is my first ever use of Timeline & Cinemachine.)

    Mark
     

    Attached Files:

  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Can you show me the inspector for the cockpit cam?
     
  7. Mad_Mark

    Mad_Mark

    Joined:
    Oct 30, 2014
    Posts:
    484
    Here is the Inspector view of the virtual cockpit cam.
    upload_2018-1-12_11-28-22.png
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Given that you have no damping on the Transposer, you can just set the Body method to Do Nothing, and parent your vcam directly to the Follow target.
    Likewise, in the Composer, it looks like you have no damping at all, and if the LookAt target doesn't move relative to the Follow target, you can also put Do Nothing oin the aim, giving you 100% control over the vcam's transform. Try that, and see if you still have problems.
     
  9. Mad_Mark

    Mad_Mark

    Joined:
    Oct 30, 2014
    Posts:
    484
    "Do Nothing" is a drop down selection somewhere?
    I have Hard Constraint, Composer and Group Composer under AIM, and Hard Constraint, Orbital Transposer, Tracked Dolly, and Group Transposer under Body.

    (All settings shown previously are as a result of troubleshooting. I am trying to solve my own problem. Don't consider them my chosen settings. That's why I'm here...)

    Mark
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Looks like you have an old version of CM. Head over to the asset store and grab the latest. Remember to delete the old CM install before installing the new one.

    In the new version, you'll find Do Nothing as options in both Aim and Body.