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

Mouse/Joystick Control on Vertical Axis

Discussion in 'Cinemachine' started by tastelessbanana, Apr 17, 2018.

  1. tastelessbanana

    tastelessbanana

    Joined:
    Sep 27, 2016
    Posts:
    11
    Hi, I want to start off by thanking you guys for this amazing asset.
    I have a Virtual Camera that follows my player in a third person view. I have a script on my player that allows me to steer/aim on the x axis. What I want to do is use the mouse or joystick to have my player look up or down so the player can aim at targets. Before I used Cinemachine, I had the same script orbit script on my camera that only controlled the rotation on the y axis but it no longer works because I assume the virtual camera has taken over. Is there a way I can still add this feature without using a Free Look Camera? I haven't had any luck with a Free Look Camera yet.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    That's what a FreeLook is for. Why doesn't it work for you?
     
  3. tastelessbanana

    tastelessbanana

    Joined:
    Sep 27, 2016
    Posts:
    11
    When I use FreeLook I cant seem to steer the player with the mouse anymore. The mouse/right joystick only allows me to orbit camera around the player.
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    You can configure the FreeLook to use any input sources you want - the mouse X/Y is just the default setting.

    At this point you need to explain exactly what behaviour you're looking for, and then we can configure the FreeLook to do what you want. Are you wanting the player to always look down the camera's Z axis? If so, then you would need to allow the mouse X/Y to control the FreeLook, and have a simple script on the player to align it with the camera's forward, as projected onto the XY plane. Is that what you need?

    Alternatively, you could disable the mouse X on the freeLook (just delete "Mouse X" from the X axis field), and allow your script to control player heading with the mouse X.
     
  5. tastelessbanana

    tastelessbanana

    Joined:
    Sep 27, 2016
    Posts:
    11
    I think that's exactly what I need.
    Ultimately, I'd like to be able to use w and d to move my player forward and backwards and a and d to strafe my player left and right. Then I'd like to be able to steer my player and look up and down(while moving)with the mouse.
     
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Yeah, that's pretty classic. FreeLook is the way to go.
     
  7. tastelessbanana

    tastelessbanana

    Joined:
    Sep 27, 2016
    Posts:
    11
    I'm sorry, what would the "simple script on the player to align it with the camera's forward, as projected onto the XY plane" look like? I apologize because I'm sure it's a noob question.

    NVM, I think I got it working roughly how I want it. Thank you for your help today!
     
    Last edited: Apr 17, 2018
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Glad you got it working. Thinking about it a little more, I'd like to revise my suggestion in order to make it a little more versatile.

    Consider this situation: let's say now you have the FreeLook controlling the camera, and a script on the player that aligns the player to the current camera forward.

    Suppose now that you want to use Cinemachine to blend to another camera, say for a cutscene, that has a different perspective. Now you don't want to orient the player to the camera anymore. So what do you do? Disable the player script? That's one possibility, but I think I have a better solution.

    Instead of a script on the player that rotates to match the current camera forward, why not make a little extension on the virtual camera that rotates the target it's following? That way, the rotation only happens when that virtual camera is active. Neat, eh?

    Set up your FreeLook like this:

    upload_2018-4-17_13-48-8.png

    Then drop this custom Cinemachine Extension script into your project:

    Code (CSharp):
    1. using UnityEngine;
    2. using Cinemachine;
    3. using Cinemachine.Utility;
    4.  
    5. /// <summary>
    6. /// Rotate the Follow Target to look along the camera forward axis
    7. /// </summary>
    8. [ExecuteInEditMode] [SaveDuringPlay] [AddComponentMenu("")] // Hide in menu
    9. public class RotateTargetToMatch : CinemachineExtension
    10. {
    11.     public bool m_YRotationOnly = true;
    12.     protected override void PostPipelineStageCallback(
    13.         CinemachineVirtualCameraBase vcam,
    14.         CinemachineCore.Stage stage, ref CameraState state, float deltaTime)
    15.     {
    16.         if (stage == CinemachineCore.Stage.Aim)
    17.         {
    18.             var follow = VirtualCamera.Follow;
    19.             if (follow != null)
    20.             {
    21.                 Vector3 fwd = state.RawOrientation * Vector3.forward;
    22.                 if (m_YRotationOnly)
    23.                     fwd = fwd.ProjectOntoPlane(state.ReferenceUp);
    24.                 follow.rotation = Quaternion.LookRotation(fwd, state.ReferenceUp);
    25.             }
    26.         }
    27.     }
    28. }
    And select it as an extension on your FreeLook:

    upload_2018-4-17_13-49-35.png

    Now the follow target will always be rotated to match the camera, but only when the FreeLook is active. To make other vcams behave the same way, add the same extension to them. Bonus: if you have noise on the vcam, the noise will not be considered when aligning the player, giving you a nice added dimension of realism.
     
    Last edited: Apr 17, 2018
    sleep2death likes this.
  9. tastelessbanana

    tastelessbanana

    Joined:
    Sep 27, 2016
    Posts:
    11
    This is almost perfect. I need the camera when accessing the bottom rig to either collide with the floor or look up from the floor to avoid clipping. I have a collider attached to the freeLook cam but it seems to go a little crazy when colliding with the floor.
     
  10. tastelessbanana

    tastelessbanana

    Joined:
    Sep 27, 2016
    Posts:
    11
    Oh amazing, thank you so much for the previous revision!
     
  11. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    "Go a little crazy" can you elaborate?
     
  12. tastelessbanana

    tastelessbanana

    Joined:
    Sep 27, 2016
    Posts:
    11
    It seems to snap around a little while still clipping through the floor.
    Could I have my bottom rig focus on an empty game object above my player so it looks up when my player "looks up"?
    Then i could set my bottom rig above the floor plane to avoid clipping/colliding all together.

    Oh yeah! This is working very nicely. Again, thank you so much for your help today! this is an issue I've been wanting to resolve for a while now. Cheers!!
     
    Gregoryl likes this.
  13. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Setting your bottom rig above the floor would be a really good idea. And yes, you can have a different LookAt target for the bottom rig, as you describe.

    upload_2018-4-17_14-26-45.png
     
  14. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,658
    Actually you don't need a different target - you can just open up the composer for the bottom rig and set a different target offset:

    upload_2018-4-17_14-38-29.png
     
  15. tastelessbanana

    tastelessbanana

    Joined:
    Sep 27, 2016
    Posts:
    11
    Thanks, I'll try both to see which I like more. I assume both will have the same outcome.