Search Unity

Overriding Axis inputs

Discussion in 'Cinemachine' started by ian00playdead, Aug 8, 2018.

  1. ian00playdead

    ian00playdead

    Joined:
    Sep 20, 2017
    Posts:
    6
    Hey gang. I've written a script to override the axis inputs on a FreeLook camera.

    Seems to be working well, but I'm noticing if I blend to another camera, as soon as the blend is complete (and the FreeLook camera's rig goes blue-ish), its response to those inputs becomes very slow. Not gone, just much slower.

    Near as I can tell I'm still providing the same values to the axes and the same deltaTime to UpdateCameraState. Likewise as soon as I start blend back to this FreeLook camera, its response to those inputs immediately goes back to normal.

    I'm still somewhat new to Cinemachine, apologies if I'm missing something obvious. Wondering if there's some countervailing force on the FreeLook's axes that only shows up when it's not the active camera. Anyway any help would be much appreciated. Thanks!
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    This is due to the standby update mode. For Performance, Cinemachine by default doesn't update the standby vcams every frame, it uses a round-robin algorithm. Normally this isn't a problem because standby vcams, by definition, are not feeding the main camera.

    If for some reason you need the vcam to update every frame even when in standby, you can change the update mode to "Always":

    upload_2018-8-9_9-31-21.png
     
  3. ian00playdead

    ian00playdead

    Joined:
    Sep 20, 2017
    Posts:
    6
    Hey Gregory, really appreciate you hitting me back.

    Afraid this doesn't seem to have fixed things for me though. Once the camera's done blending away from it, the freecam's movement is still very slow. I've tried to disable everything else I was doing to update the camera "by hand" in order to overwrite its input settings, to make sure that's not having an effect. I'll keep poking.

    Meanwhile I don't suppose there's a demo scene or script showing off a freelook cam w/ overwritten axis inputs done properly? I feel like there might be a few people in this boat, as most I know don't stick with the named axis inputs of Unity for too long.

    Anyway I don't actually know that this is critically important, things are still behaving pretty well, it was just nice to be able to see where a freeLook cam's position would be were it live.
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Could you post the code showing how you do the axis override? And also the FreeLook inspector, showing the axis settings. Thanks.
     
  5. ian00playdead

    ian00playdead

    Joined:
    Sep 20, 2017
    Posts:
    6
    Here's the script I have riding along on the FreeLook.

    Should mention it's set up in a slightly strange way so that it will update both in edit and play mode. I'm trying to mimic the behaviour of a previous home-brew camera script, which has lead me down some strange avenues, and may well be the source of my troubles.


    Code (CSharp):
    1. [ExecuteInEditMode]
    2. public class FreelookOverride : MonoBehaviour
    3. {
    4.    private CinemachineFreeLook _freeLook;
    5.    public CinemachineFreeLook freeLook
    6.    {
    7.       get
    8.       {
    9.          if (_freeLook == null)
    10.             _freeLook = GetComponent<CinemachineFreeLook>();
    11.          return _freeLook;
    12.       }
    13.    }
    14.  
    15.    private InputMotor _stickInput;
    16.    public InputMotor stickInput
    17.    {
    18.       get
    19.       {
    20.          if(_stickInput == null && stickSettings != null)
    21.             _stickInput = new InputMotor(stickSettings);
    22.          return _stickInput;
    23.       }
    24.    }
    25.    
    26.    public InputSettings stickSettings;
    27.    
    28.    private float prevTimeSinceStartup;
    29.  
    30.    protected void Update()
    31.    {
    32.       var dt = Time.realtimeSinceStartup - prevTimeSinceStartup;
    33.      
    34.       if (!Application.isPlaying)
    35.          UpdateAxisInput(dt, true);
    36.  
    37.       prevTimeSinceStartup = Time.realtimeSinceStartup;
    38.    }
    39.      
    40.    protected void FixedUpdate()
    41.    {
    42.       UpdateAxisInput(Time.fixedDeltaTime);
    43.    }
    44.  
    45.    public void UpdateAxisInput(float dt, bool manualUpdate = false)
    46.    {
    47.       if (freeLook == null || stickSettings == null) return;
    48.      
    49.       stickInput.Tick(InputManager.input.stickRight);
    50.      
    51.       freeLook.m_XAxis.m_InputAxisValue = stickInput.X;// * gain;
    52.       freeLook.m_YAxis.m_InputAxisValue = stickInput.Y;// * gain;
    53.  
    54.       if (manualUpdate)
    55.       {
    56.          freeLook.m_XAxis.Update(dt);
    57.          freeLook.m_YAxis.Update(dt);
    58.          
    59.          freeLook.UpdateCameraState(Vector3.up, dt);
    60.       }
    61.    }
    62. }
    And here are my axis settings:

    upload_2018-8-16_16-54-32.png
     
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Sorry, I misled you before. Looking at the FreeLook code, I see that the axes' m_InputAxisValue is reset to 0 when the vcam isn't live, and that's why the axes are not responsive. Calling vcam's update won't help, nor will setting the standby mode to Always, as you have discovered.

    Looking at your code, I'm thinking that calling x_axis.Update() and y_axis.Update() ought to do the job, not sure why it isn't working for you. Are you calling with manualUpdate set to true? Certainly you should remove the call to freeLook.UpdateCameraState(Vector3.up, dt), which is probably doing more harm than good.

    Also, why are you doing this in FixedUpdate rather than LateUpdate? Is your Skeleton target animating on the physics clock?
     
  7. ian00playdead

    ian00playdead

    Joined:
    Sep 20, 2017
    Posts:
    6
    Hey sorry for my slow reply!

    Yeah I'd noticed a discrepancy between the inspector value displayed for the Y axis and the X axis, wasn't sure what to make of it.

    I am a little worried about manually calling UpdateCameraState, but I sort of need to in order to replicate the behaviour of the existing camera I'm trying to emulate. Our character controller is responsive to stick inputs even outside of play mode, allowing you to reposition both the character and the camera. I (think I) need that call there to keep that dream alive. So yes I am calling with manualUpdate set to true, but only in edit-mode.

    And yes the Skeleton target is updating with physics. I don't think the camera necessarily needs to, I was just being a conformist. I'll change that.
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    The camera should update on the same clock as the target so it's best to leave that part as it is.

    Are you sure you need the call to UpdateCameraState()? If you set the standby update mode to Always, it will get called in the appropriate place every frame (that's the point of it), so you shouldn't call it here. You just need to make sure your axes are responding to the input value, which is why you need to call the axis Updates, otherwise the input value just gets reset to 0 if vcam isn't live. But that's all you should have to do. Are you saying it doesn't work when you try that?