Search Unity

RTS Camera

Discussion in 'Cinemachine' started by ADoby, Jun 2, 2017.

  1. ADoby

    ADoby

    Joined:
    Dec 10, 2012
    Posts:
    21
    Hey,

    I tried to implement a RTS-Camera using the Free-Look Component.
    Using the v2.0 Release Candidate.

    Adding External Input was not as bad as I have thought.
    But when trying to add features like zoom to position or rotate around position it gets problematic.

    I think those features would be nice to have in the main file instead of trying to add it afterwards.
    Adding it afterwards intruduces many problems like jittering or other bugs.

    Nice-to-have Features:

    => Easily Add Input from outside (AddInput(float amount) for every axis)
    => Drag (Move the Camera on Axis,
    => Zoom at all (Changing Radius and HeightOffset)
    => Zoom to position (Needs to change position and above)
    => Rotate Around position (Needs to Rotate and change position)

    Does someone have a working code for adding zoom to position to the free-look camera?
     
  2. Adam_Myhill

    Adam_Myhill

    Joined:
    Dec 22, 2016
    Posts:
    342
    Hi @ADoby . . RTS cameras, they are an interesting challenge for sure. They seem like a relatively straightforward problem but there are sure some devils in the details to make them great. We spent a long time on DoK getting them to feel right - height, FOV, acce/decel.. a lot of things have to be balanced.

    We are going to discuss making a default RTS camera rig, it's a good idea. We also have a new feature which is in testing that keep multiple objects on screen - a dynamic framing component. We will make a post when it's updated in the CM 2.0 release candidate (we really need to finish the documentation and example scenes instead of making new features but it's just too much fun)

    In the meantime, there are a few tricks which will help. Have CM target / follow a dummy object which you move programatically. You can snap this object to wherever and use CM's damping to smooth things out if needed. You can use an Orbital Transposer on the Body and then rotate the heading to get orbits around this dummy object(s) - you might want to have a separate dummy for the target and one for the follow.

    This is a bit of a 'marionette' rig for CM where you drive the camera with code-placed-animated dummy targets. I hope that helps and we'll let you know how it goes with a custom CM RTS rig.
     
  3. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    @ADoby Just checking in to see if you've got the RTS camera going. If you follow Adam's suggestions, it should be pretty straightforward, and you should not be getting any jittering or other issues.
     
  4. ADoby

    ADoby

    Joined:
    Dec 10, 2012
    Posts:
    21
    @Gregoryl The RTS-Camera itself works fine.
    I have only two problems left.
    One is based on Mouse ScrollWheel Input for Zooming, which I have to figure out myself.
    It is a problem to find the start and end of input, when it doesn't have a clear start and end like a scrollwheel with damping.

    The other is a timing problem which leads to jumping of the camera for one frame.
    My current workaround for Zoom-To-Cursor:

    When Input Starts:
    1. Raycast the world to get the current cursor position in World
    2. Place a plane at that position (to get movement only in x-z coordinates)
    Every Update (After Camera did Update Position):
    3. Let the Cinemachine Rig update its position
    4. Raycast against the created plane to get the difference the cursor made in world coordinates
    5. Move the "follow" transform in the oposite direction

    With this I end up locking the cursor to its position in world coordinates (zoom to cursor)

    But for some reason the camera movement seems to happen one frame before I can calculate the differences.
    I have to investigate why that is.
    Maybe something with the Smart Updating Feature.

    We wanted to add these features outside (with modules) instead of creating one big super camera script.
    But it creates problems with timing and stuff.
     
  5. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    @ADoby I'm not sure I entirely understand what you're trying to do. Just to confirm, here is what I've understood so far:
    • Using FreeLook to make an RTS camera
    • X axis of the FreeLook circles the target
    • Y axis on the FreeLook zooms in and out
    • You have created an invisible target for the FreeLook to follow and look at
    • You want the scroll wheel to control the Y axis
    Is this right so far?
    Here is what I don't understand:
    • What is controlling the X axis?
    • What is controlling the cursor position?
     
    deargamemaster likes this.
  6. ADoby

    ADoby

    Joined:
    Dec 10, 2012
    Posts:
    21
    @Gregoryl
    No sorry, that is probably my failure explaining it.
    I have:
    • The FreeLook Cinemachine Component
    • The FreeLook Component works as is, x axis defines active rig, y axis rotates around the follow transform
    • I added Components to create external input (like multitouch gestures for rotating)
    • I added a Component that changes the Radius and HeightOffset of ALL Rigs based on a zoom value (changed by scrollwheel or pinch gesture)
    • I added a Component that rotates the follow transform around the cursor position instead of using the y-axis of freelook to create the Rotate-Around-Cursor feature. This is toggleable.
    • I added a Component that drags the follow transform around using the cursor delta
    The zoom components Zoom-To-Cursor feature works as follows:
    1. Whenever Input starts I raycast the current input world position and create a plane on that point with normal Vector3.up.
    2.1. The input changes all rigs heightoffset and radius first then
    2.2. While Input is on (you are zooming) I raycast against the created plane to calculate the deltamovement your cursor did in 3D-space
    3. I move the follow transform in the oposite direction so that the cursor stays at its world position
    => Tada, zoom to cursor position

    The zoom component does not work correctly, probably because it needs to wait for the CinemachineRig to update the rigs.

    I hope this is more informative.
     
    838nHex likes this.
  7. ADoby

    ADoby

    Joined:
    Dec 10, 2012
    Posts:
    21
    @Gregoryl If you want to have a look at it, I can send you a package.
    Not in public i guess :p
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    @ADoby Still trying to understand zoom-to-cursor.
    Let's assume you're using a mouse.
    So you point somewhere in your game view and move the scroll wheel. The behaviour you want is that the camera centers itself around the world point where you first started scrolling, and the radius/height adjusts in accordance with the scrolling direction? Is that right?
     
  9. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Yes, it would help a lot if you send me a package.
     
  10. Daerst

    Daerst

    Joined:
    Jun 16, 2016
    Posts:
    275
    @Adam_Myhill @Gregoryl Any news on the RTS rig? I'd be interested in a camera that you can move when moving the mouse cursor the screen borders and with WASD, scroll to zoom, orbit the dummy target when scroll wheel is pressed, center on a transform when pressing space and (probabyl the most tricky part) handle height differences in the scene gracefully. This means not clipping into buildings, and keeping a good distance to terrain of varying height for example.
     
  11. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    Hi there; I'm trying to get something similar to what @Daerst above is describing, although a bit simpler. I'm aiming for a looking down camera with a fixed perspective (not completely), so I've set it up like that:

    upload_2018-2-9_22-53-1.png

    Now, whenever I "zoom" in and out, the camera rotates slightly on the Y axis with the following values
    Code (csharp):
    1.  
    2. altitude | rotation
    3.    8     |   0.331
    4.    16    |  -0.733
    5.    42    |   0.662
    6.  
    that rotation ping pongs between the key values of the rig (meaning it goes from 0.33 to -0.733, then back to 0.662) and I just don't understand why. These values are consistent regardless of altitude values.

    Anything that I'm missing in the configuration here that would lock the Y axis in place when zooming in/out ?

    ------------

    And while I'm on the subject: say I want to restrict rotation on specific angles (eg have the camera stick to the angles 0, 90, 180, 270) but still take advantage of the Free Look rig helper, is there already something like that, or I should explore having a composite object with multiple virtual cameras and blend between them?
     
    Last edited: Feb 10, 2018
  12. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
  13. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    @Gregoryl Ah fantastic, that was exactly that. Setting to Hard Look at fixed that slight rotation. I'll have a look at the thread you just linked, which seems to be exactly what I needed. Cheers!
     
  14. Xerioz

    Xerioz

    Joined:
    Aug 13, 2013
    Posts:
    104
    Gonna revive this thread because I'm stuck with the same issue.

    We never got a proper answer on how we could achieve zoom to cursor using cinemachine.
    I have my own implementation using standard camera which works same way as ADoby described, but I'd like to move to Cinemachine's virtual cam.
     
  15. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Anything that works with a standard camera will also work with a vcam. No need to rewrite your working code. Just replace the Unity Camera component with a vcam (with "Do Nothing" in Aim and Body so it won't interfere with your camera controller). Then, make a new Unity Camera - with a CinemachineBrain - at the root and you're done.

    Thanks to the Brain, the Unity Camera will now be driven by the vcam's transform. You can add noise, collision, or any other extension to your vcam and it will work fine. Blends to other vcams and Timeline integration will work too.

    See this thread for a pretty picture: https://forum.unity.com/threads/multiple-raw-pos-for-one-vcam-possible.525199/#post-3455994
     
  16. Xerioz

    Xerioz

    Joined:
    Aug 13, 2013
    Posts:
    104
    I fixed my issue by changing camera's fov and pos directly instead of messing with vcam's properties.

    The issue was the fact that vcam would only update at the end of the frame ( or so it seems ), so I couldn't execute my zoom-to-mouse code properly.

    This zoom method required changing the camera's position ( and fov in my case ), do raycast, then translate it to correct its position. When I tried doing that to vcam, it didn't update camera's view projection matrix, so the raycast still used old camera's properties, from the previous frame, resulting in a stuttery translation and a really unsatisfying zoom.

    What would be a great-to-have-feature is the ability to manually update vcam, that would solve a lot of issues and allow advanced users to do some wicked vodoo magic.
     
  17. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    @Xerioz Ah, I understand the issue now.
    The Camera's transform is updated in LateUpdate, by CinemachineBrain. To do something after the update, you would do it in the LateUpdate() of your script, then set the script execution order to make your script execute after CinemachineBrain.
     
  18. Ash-Blue

    Ash-Blue

    Joined:
    Aug 18, 2013
    Posts:
    102
    If anybody fell upon this via a Google search I've built an orthographic RTS Cinemachine camera example repo you can find at the link below. It demonstrates how to setup the camera, use forward movement projection, and work with other Cinemachine cameras on the fly.

    https://github.com/ashblue/cinemachine-rts-camera-test
     
    Soulice and Ipolitas like this.