Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Player freelook Camera with rotation and World Space

Discussion in 'Cinemachine' started by alec100_94, Jun 20, 2023.

  1. alec100_94

    alec100_94

    Joined:
    Jan 9, 2017
    Posts:
    26
    Hi there, I have always had a hard time setting up Cinemachine correctly in a way that makes sense for our 3rd person action/rpg and have always felt like I am missing something. Have been trying to set it up from scratch again recently (using Cinemachine 3) and am equally as confused.

    What I am trying to achieve is a 3rd person freelook camera, where the camera will follow both the players and position, and more subtley the rotation. Similar to the camera setup in Dark Souls, where the user can navigate the environment quite comfortably without ever moving the mouse/right stick, but can still look around freely if they wish.

    Lazy Follow (f.k.a. Simple Follow with World Up) Binding Mode is close to this behavior, but it is still not exacty what I am looking for, as I would like a little more control over the follow, and ideally to keep the camera "anchored" in co-ordinate/assigned space as opposed to being relative to itself (have seen drift introduced from Simple Follow in past).

    I would ideally like to build something (an extension, modifier, update script) that yeilds similar results to Lazy Follow but for World Spacebinding modes. My movement code is relative to camera forward so the other Lock to Target options (except On Assign) cause spinning when attempting to move (still not fully clear on the usefulness of these). I would like to control over how and when the rotation is tracked vs not tracked, potentially realtive to the targets distance from the center of the screen (yellow dot). I guess I'm looking for a more "Advanced Follow" as opposed to Lazy/Simple Follow.

    The problem is I have no clue how to implement this through Cinemachine and can't really figure out any way to track the player in even roughly the way I want other than just switching the Binding Mode to Lazy Follow, and there seem to be very few resources out there detailing such a thing.

    Hopefully I can get some help understanding how this works in Cinemachine, and maybe it can help others too. To me this seems like a relatively standard use-case, but seems incredibly difficult to pull off in a sane way in Cinemachine unless I'm missing something (possibly am).
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,233
    Can you describe the desired behaviour more specifically? It sounds like you just want world space binding mode.
     
  3. alec100_94

    alec100_94

    Joined:
    Jan 9, 2017
    Posts:
    26
    Thanks for the prompt reply. I want something similar to world space, but I would still like my camera to turn (with my character) when pressing the A and D keys without any look input on the "X-Axis" (more similar to how Lazy Follow works).

    If you see the clip below, with First Lazy Follow and then World Space Binding modes as an example, with no Input on the X-Axis as an example. With lazy follow I can turn and run in the other direction wheras in world space this is not possible without manually rotating the camera (at least by default):


    What I am confused about is how to write a custom script that will rotate the camera to track the target in a similar way to Lazy Follow with the World Space binding mode, but to give me more control over how (and when) the rotation is tracked.
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,233
    Thanks for the explanation, but I'm still a little confused. Maybe you can give a concrete example.

    Let's say the character is facing away from the camera, and you hold the D key. Since motion is relative to the camera, the player will turn and run to the right. If the camera tracks the player position but not the rotation (worldspace binding mode), then the player will continue to run in a straight line in the chosen direction. If the camera slowly rotates to align itself with player forward, then the character will turn along with the camera, spoiling the motion. Is that what you want? If not, then what?
     
  5. alec100_94

    alec100_94

    Joined:
    Jan 9, 2017
    Posts:
    26
    I would like to track the rotation as well, but remain in World Space Binding mode. So you could fully explore a 3D world without ever needing to touch the Mouse. I want something quite similar to Lazy Follow, but I'd like a little bit more control over how it tracks than that (like controlling how agressively it tracks and only start to track once it reaches a certain distance from the centre).

    I'm not sure if the video above worked before, but that might help to clarify. I'm a bit unclear if this was the intended use-case for Lazy Follow, or if there's a way to track the players rotation in world space?

    To maybe put it in simpler terms World Space (where rotation can only be adjusted manually) is not the behaviour I want, but I would ideally still like everything to be calculated in fixed space (as opposed to relative). Lazy Follow is much closer, but not exactly the behavior I want either (and that is in relative space only). Am trying to work out what I'd need to do to take more control over it.
     
    Last edited: Jun 20, 2023
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,233
    I'm really having trouble understanding what you want. Because you are interpreting WASD in camera space, turning the camera while the player is moving will force the player to change WASD direction in order to maintain the same direction of motion. Are you ok with that? It will make navigation very difficult for the player.

    I did see your video, but it doesn't help me understand the behaviour you want. It just shows behaviour you don't want.

    If you want custom control, one way to do this is to make an invisible object child of your target, whose rotation you control with a custom script. Use that as a follow target and set the binding mode to LockToTarget. That way, your custom script ultimately controls the direction of the camera offset.

    Another way is to write a custom script to drive the recentering yourself (e.g. only recenter when the angle is outside some range).

    I don't know what you mean by relative space and fixed space. There are 3 types of binding in CM:
    1. World Space: the vector specifying camera offset from target is interpreted in world space
    2. Target space (the various flavours of Lock to Target): offset vector is interpreted in target local space
    3. Lazy Follow: offset vector is interpreted in camera space
    Automatic recentering can be implemented in any of these modes.
     
    Last edited: Jun 21, 2023
  7. alec100_94

    alec100_94

    Joined:
    Jan 9, 2017
    Posts:
    26
    Now I am confused by some of what you just said. To re-iterate what I effectively want is something similar to Lazy Follow, where the camera will rotate on the x-axis and player will move with it, so holding A/D would effectively result in a circular motion (again like Lazy Follow), but I'd like to do this in World Space or Target Space with a little more direct control over how the target is actually tracked. What I meant before by "fixed" and "relative" was that I want it to be in a determistic space (World or Target) as opposed to calculated in relative Camera Space (like Lazy Follow is).

    As for the recentering options, in my case the camera never moves on the x-axis in World Space, so it is by that logic already centered. If there was a way to center it behind the player (i.e. reset to the targets forward vector) then I think that is close to what I'd be looking for. I think there used to be a "Recenter to Target Heading" option in CM2.x, but can't seem to find that in CM3. My target is a direct child of my Player and hence has the same rotation, so any child of that would need to be updated every frame, and I'm not sure what with as its ultimately the players rotation that I'm trying to track.
     
    Last edited: Jun 20, 2023
  8. alec100_94

    alec100_94

    Joined:
    Jan 9, 2017
    Posts:
    26
    In terms of a real world example of what I'm trying to do, it's exactly what Dragon Quest XI does when you set the camera mode to Automatic. Another game with very similar behaviour is Ni No Kuni II. Pretty sure a lot of Souls like games do the same thing, but I don't have one to test. It's a pretty common thing in a lot of games, maybe I'm just doing a bad job at explaining the behaviour, and my understanding of how it would work under the hood.
     
    Last edited: Jun 21, 2023
  9. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,233
    Let's set aside for a moment how it would work under the hood, and concentrate on what it is. Once that is clear, we can move on to figuring out how it would work.
    Currently Lazy Follow is the only way to do this without specific code in your motion controller to walk in a circle.
    That's the part I don't understand. Why will World or Target space help you? What control do you need? Can you describe specifically? Maybe you can get it in Camera space also.
    Unless the player moves the mouse, right?
    You are right, this functionality is missing in CM3. It's an oversight, I would call it a regression. We will address it for the next pre-release.
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,233
    Thanks for the examples, but I don't have those games handy and can't look at them. If you could find a video, that would really help. Or you could try to describe what the camera does in response to player movement. It's a good exercise to do this in any case, because it crystallizes the requirements in one's mind.
     
  11. alec100_94

    alec100_94

    Joined:
    Jan 9, 2017
    Posts:
    26
    Okay, so here's a quick video of the automatic camera movement in Dragon Quest XI (again with no mouse input) which is pretty much exactly what I'm trying to achieve. It is fundamentally quite similar to Lazy Follow, But tracks the target a little less agressively. Maybe my initial thoughts on how to implement this in Cinemachine (through World Space) were a little off. Or maybe that still is the way to go with some additional math in my character controller.

    My biggest concern with staying in Camera Space is that it could introduce drift over time, and makes it more awkward to control the camera directly. I would also eventually like a toggle in the menu for automatic camera controls (again like Dragon Quest XI), and to me it would make sense to keep the same binding mode for both.

    Again it seems like relatively "Standard" stuff, and I would've thought it would be quite trivial to implement without using LazyFollow (which seems like it is designed for a more tailored use-case) but maybe my understanding of that is slightly off.

     
  12. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,233
    Thanks for the video, it's very helpful.

    To me it looks exactly like Lazy Follow. I don't see where it's less aggressive. Can you elaborate?

    I don't think you need to worry about drift. It's not an issue with Lazy Follow. In what way is it more awkward to control the camera? And what kind of control are you looking to do?

    What would the other mode be?
     
  13. alec100_94

    alec100_94

    Joined:
    Jan 9, 2017
    Posts:
    26
    I think the speed it follows at is a bit slower than Lazy Follow, causing a larger circular motion when holding. I agree its not far off which is why I've kept comparing it to Lazy Follow as the closest thing Cinemachine has. I guess I effectively want Lazy Follow with the ability to change and tweak the values a bit more, it might already provide this, but if so I've not seen it. Damping and Deadzone in the rotation composer help a bit, but they often produce results where the character is not centered (again no way for it to snap back to the centre automatically).

    In terms of the control and drift, I meant to control through code. Lazy Follow doesn't really have the concept of camera center so recentering it (or manually setting it to an arbritary position) will never be trivial (though you could use target forward as a reference point for the player). Maybe the drift is less of an issue than I had initially thought, but I remember there being an issue in an older version of Cinemachine with then Simple Follow with World Up, and a drift being introduced after a long play session (around 40 minutes) in a large 3D world, but that issue could be completely fixed now.

    The other camera control mode I'd potentially want to implement in the game would be a more traditional freelook where the camera doesn't auto-rotate (effectively what World Space does). I guess a possible solution would be to have the option toggle between Lazy Follow and World Space at runtime.

    My wider thoughts (and it might be a bit of misundertstanding on my part, in terms of how its been presented), is that Lazy Follow (or Simple Follow in previous versions) is the "Basic" binding mode, designed to get something up and running quickly and not truly suitable for anything outside of prototyping, and that World Space (or one of the Lock to Target variants) would always give more control to the developer over the Camera's behaviour. This may be a complete misconception though, and a version of Lazy Follow might be what I'm looking for here.
     
  14. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,233
    Settings in the Rotation Composer control the camera aim, not the position. If you want it to follow more slowly (which is a bit ambiguous, tbh) you might increase the Position Damping in the Orbital Follow. That will make the camera catch up to the player more gradually (although you'll have to be careful when the player is moving towards the camera, not to make that lag too great). If that's not what you want to control, then please try again to explain.

    Yes, there were at one time some drift issues, but they should not be there anymore. Lazy Follow is safe. Yes also, target recentering isn't (currently) a built-in concept in Lazy Follow mode, but it is fairly straightforward to implement it with an add-on script (there is one in some old post somewhere, I'd have to dig it up). The good news is that recentering will be available with the next CM3 preview and it will work out of the box for Lazy Follow, so you won't have to re-implement it. Thanks to you for bringing that up, by the way.

    Better would be to just have a second vcam with different settings that you activate as needed. Blending between heterogeneous vcams with different settings and binding modes is designed to work smoothly. Make sure to enable the "Inherit Position" blend hint.

    I don't agree with you here. The different binding modes each have their specific usecases, and each one is meant to be fully functional. The only missing element in Lazy Follow was target recentering, and that is being addressed... unless you can think of another missing piece.
     
  15. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,233
    And thanks @alec100_94 for all your feedback, we really do appreciate it.
     
  16. alec100_94

    alec100_94

    Joined:
    Jan 9, 2017
    Posts:
    26
    Okay thanks again, that makes a lot of sense, and its good to know that Lazy Follow is considered to be a primary use case, and that more features to plug the gaps in recentering are being worked on (I think I might actually have an old version of the re-centering script). Also the idea of additional virtual camera's makes sense too, I hadn't really thought to use it like that, but I could easily combine a couple to create even just the "default" behaviour (without changing a menu setting), which might give me back some more of the control I was looking for. I will try and adjust my camera settings based on all of the information above, using the Lazy Follow binding mode, and hopefully get the behaviour I'm looking for.

    I think the previous name of Simple Follow (in CM2), combined with some of the issues I've seen in the past confused me a bit. I also think the new name of "Lazy Follow" combined with the documentation (about how a human would physically track a target), is still a little bit ambiguous to what its practical use-case is, After discussing it with you here I'd see it as more of an "Automatic Follow".

    Based on this conversation, I'd think most Third Person Action/Adventure games would probably want either World Space (Maybe Lock on Assign) or Lazy Follow for their main camera? It would be good if this was communicated a little better through the docs, as historically I've defintely found setting up Cinemachine and getting the behaviour I want (or close to) quite intimidating compared to what could potentially be an incredibly simple Camera Follow script.

    I think having less binding modes could help clear up some of the confusion too. Providing additional options for yaw/pitch/roll variants of "Lock to Target" so there is less in the drop down would make the choice much less confusing IMO.
     
    Last edited: Jun 21, 2023
  17. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,233
    I agree that the multiplicity of binding modes is problematic, but it's hard to come up with an alternative that's better. The fact is that there are many different ways to follow something, and we need to have them covered. The only one that I would question is Lock to Target on Assign. I've been itching to get rid of that one altogether and tell people just to use Lock to Target. Why do you think Lock to Target on Assign is important?
     
  18. alec100_94

    alec100_94

    Joined:
    Jan 9, 2017
    Posts:
    26
    From my understanding Lock to Target on Assign is the only mode that effectively gives you World-Space like behaviour in a user-defined space (still allowing you to specify custom world up and forward vectors). I would maybe rename it to "Lock to Target Space" or simply "Target Space", but I think its still valuable (especially if you're trying to do something with inverted gravity, or non-standard co-ordinate system).

    In terms of the other lock to target options, they still confuse me a bit, I get roughly what they do but they seem pretty useless if you want have movement relative to the camera, at least without a highly custom heirarchy and additional scripts. I would personally solve the problem of the 3 "Lock to Target" modes with an additional drop-down that appears when "Lock to Target" is selected, for "Lock to Target Style" (or similar). That way no functionality is lost, its just a little bit less ambiguous.
     
    Last edited: Jun 23, 2023