Search Unity

Minimise Y movement in Follow Cam & Teleport

Discussion in 'Cinemachine' started by Deeeds, Apr 16, 2018.

  1. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    Imagine a character going from left to right, and right to left, and sometimes jumping up and down.

    I want the camera follow this guy, but only in the left and right, with a little lag, exaggerated by the fact the camera is looking at this hero, but I don't want the camera to follow in the up and down, nor look up and down.

    How to do this with Cinemachine?

    Teleport, in this same space, sometimes happens, from left to right, and vice versa, at which point their should be no noticeable change in the camera relative to the hero.

    Is this also possible?

    Any and all suggestions and mirth/mockery greatly appreciated.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    1. Give the vcam a big vertical dead zone.
    2. There is an API call to support teleporting, but only in CM 2.1.12 and up. Which version are you using?
     
    Deeeds likes this.
  3. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    I think I've found the Cinemachine Teleporter, a Warper function from the bottom of the page linked at the bottom of this...

    Code (csharp):
    1.  public override void OnTargetObjectWarped(Transform target, Vector3 positionDelta)
     
    Last edited: Apr 17, 2018
  4. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    I've got this working...

    THANK YOU!!!

    !!! Defender Style, Seamless Looping World Teleportation !!!

    here's the Eastern Portal, of which the Western is the same, but for the bool saying it's not the East Portal:

    Screen Shot 2018-04-17 at 5.17.23 pm.png

    And here's the Telporter Script.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Cinemachine;
    5.  
    6. public class backupTelporter : MonoBehaviour {
    7.  
    8.  
    9. public CinemachineVirtualCamera vCam1;
    10. CinemachineComponentBase myCamera;
    11.  
    12. Transform otherTransform;
    13. Rigidbody2D otherRB;
    14. Vector2 RB2D_Velocity;
    15. float RB2D_rate_Of_Spin;
    16.  
    17. Vector3 teleport_Destination;
    18. Vector3 teleport_origin;
    19. Vector3 teleport_origin_in_portalSpace;
    20. Vector3 teleportDistance;
    21.  
    22. public bool EastPortal;
    23. public GameObject Destination;
    24.  
    25. void Start ()
    26. {
    27.     myCamera = vCam1.GetCinemachineComponent<CinemachineComponentBase>();
    28. }
    29.  
    30. private void OnTriggerExit2D(Collider2D other)
    31. {
    32.     otherTransform = other.transform;
    33.     otherRB = other.attachedRigidbody;
    34.  
    35.     if ((EastPortal && otherRB.velocity.x > 0) || (!EastPortal && otherRB.velocity.x <0)){
    36.         DoTeleport(otherRB);
    37.         }
    38. }
    39.  
    40. void DoTeleport(Rigidbody2D RB2D_toBe_Ported)
    41. {
    42.     RB2D_Velocity = RB2D_toBe_Ported.velocity;
    43.     RB2D_rate_Of_Spin = RB2D_toBe_Ported.angularVelocity;
    44.     teleport_origin = RB2D_toBe_Ported.transform.position;
    45.     teleport_origin_in_portalSpace = transform.InverseTransformPoint(teleport_origin);
    46.     teleport_Destination = Destination.transform.TransformPoint(teleport_origin_in_portalSpace);
    47.     teleportDistance.x = teleport_Destination.x - teleport_origin.x;
    48.  
    49.     RB2D_toBe_Ported.Sleep();
    50.     RB2D_toBe_Ported.transform.position = teleport_Destination;
    51.     RB2D_toBe_Ported.WakeUp();
    52.     RB2D_toBe_Ported.velocity = RB2D_Velocity;
    53.     RB2D_toBe_Ported.angularVelocity = RB2D_rate_Of_Spin;
    54.     myCamera.OnTargetObjectWarped(otherTransform, teleportDistance);
    55.  
    56.     Debug.Log("Teleported Other!");
    57.     }
    58. }
    59.  
    Here's the camera settings:

    Screen Shot 2018-04-17 at 5.20.44 pm.png
     
    Last edited: Apr 17, 2018
    Gregoryl likes this.
  5. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    @Gregoryl Is there a way to do the above with a LookAt, and just a slight bit of slop in the way the Follow works, so there's some slight perspective change as the hero moves too fast for the camera Follow?
     
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    Possibly, but you might need to hack the code ever so slightly
     
  7. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    I've got it working... except I can't constrain the camera to a Y setting. The camera is transforming with the target's Y movement. Other than that, it's working well.

    Any idea how I can lock the vCam's y to a set "latitude"?
     
  8. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    @Gregoryl

    This sort of works, but has a few glitches, that are huge and disturbing, and has a little noise that's kind of cool:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Cinemachine;
    5.  
    6. public class constr : MonoBehaviour {
    7.  
    8. CinemachineVirtualCamera myCam;
    9. CinemachineComponentBase myBase;
    10. public Rigidbody2D  RB2D;
    11. CinemachineTransposer myTransposer;
    12.     void Start ()
    13.     {
    14.         myCam = GetComponent<CinemachineVirtualCamera>();      
    15.         myBase = myCam.GetCinemachineComponent<CinemachineComponentBase>();
    16.         myTransposer = myCam.GetCinemachineComponent<CinemachineTransposer>();
    17.     }
    18.    
    19.     void Update ()
    20.     {
    21.         myTransposer.m_FollowOffset.y = RB2D.position.y * -1;
    22.     }
    23. }

    Screen Shot 2018-04-18 at 3.25.07 am.png
     
  9. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    The big, disconcerting glitches, that are infrequent, is Cinemachine flipping the Z value of the camera for a couple of frames. Not me, I promise. I'm not touching the Z value.
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    This is beginning to exceed the imaginative capacity of my tiny cranium. Any chance that you can throw together a little package that demos this so I can have a look?
     
  11. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    I'm new to Unity. So not yet sure how to share, or make much of anything. I'm still working in the same project I first started in, just adding stuff...

    where/what/how to share a project?
     
  12. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    I'm assuming you're working in a test scene... with minimal artwork.
    If not, it would be a good idea to make that, with a simple shape for a player, and minimal or no scenery. Wire in the camera and player controls, and the teleport stuff, so that the camera behaves the same way and shows the issue.
    Save the scene.
    Now do this:
    upload_2018-4-17_16-12-39.png

    And in the resulting popup select all the stuff that needs to be included in the package: scene, scripts, and (if needed, textures, and other assets - try to have as little as is reasonable).

    upload_2018-4-17_16-15-34.png

    Then hit export, and send me the result, which I will import into an empty project (you can test that before sending it to me).
     
    Deeeds likes this.
  13. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739

    Thank you!!!!!

    This will come in very handy, soon... I'm sure to make more problems for myself!

    This one, I have managed to fix. I tried a bunch of stuff, two things worked best...

    1. Moved the offset maintainer to different updates, FixedUpdate seems to work best. I thought lateUpdate would work better, but it doesn't.

    2. Best change: Turned Binding Mode to "Lock to Target, No Roll". I completely forgot about this setting. This was the cause of the glitch. Now it can't flip around to the reverse Z position relative to the target, and never glitches.
     
  14. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    YESSIR !!!
     
  15. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    @Gregoryl

    Is "look ahead" incompatible with Warping? It wigs out, pretty hard. Goes the wrong way for a bit, by a good amount, and then tries to come back after a bit. Can't find a way to stop this wigging out.
     
  16. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    oh crap, I think you're right, they don't play nice. Will fix that. Thanks for letting me know!
     
    Deeeds likes this.
  17. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    No worries.

    In general, just wow, because it all "just works™"!

    THANK YOU!!!
     
  18. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    @Deeeds I take this back - in fact they should play nicely. Are you using the teleport code that you posted above? I don't trust it. OnTargetObjectWarped() expects a delta position in world space. Your code is doing some funny business with the positions... why doesn't it just pass (destTransform.position - srcTransform.position) as a parameter?
     
  19. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739

    Can you have a read through this, help me understand what @MelvMay is trying to say? It might also help explain why I'm doing the translation of the transform from its position in one portal to the other ie. the object is moving so fast that it's somewhere well outside the portal, not at an edge, by the time the physics engine realises its exited the portal and needs to be teleported.

    Rather than have the teleport push it back to a position inside the destination portal on teleport, I use that world position and transform it to origin portal coordinates, then use that in the destination portal coordinates to find the world space to teleport to.

    Both portals are the same size, orientation and shape.

    anyways... here's the physics discussion where I'm trying to find out how much granularity I can get with the new manual simulation of physics... could you help translate from MelvMay English to my moron designer language?


    https://forum.unity.com/threads/whe...ime-independent-of-fixedupdate-s-rate.526987/
     
  20. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    For the lookahead glitches, I would simplify the code, so that it does something like this:

    Code (CSharp):
    1. Vector3 posDelta = teleportDest.transform.position - teleportOrigin.transform.position;
    2. player.transorm.position += posDelta;
    3. vcam.OnTargetObjectWarped(posDelta);
    You don't need a fast framerate or anything. If the player is moving really fast and you don't get the trigger until it's well past the portal, it won't make any difference, you'll be warped to a point similarly past the destination portal.
     
    Last edited: Apr 18, 2018
  21. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    vcam.OnTargetObjectWarped(GameObject, posDelta);

    ;)

    On the rest.... S***. I feel like an idiot. I don't know how I missed something this obvious about posDelta with regards the two portals and the hero's position.

    I am a moron!

    UPDATE:

    OOPS!!!!

    vcam.OnTargetObjectWarped(Transform, posDelta);
     
  22. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    Sadly, no change to the porting and follow problem. posDelta working perfectly. posDelta on the right in these logs...


    Screen Shot 2018-04-19 at 2.00.26 am.png

    I must be doing something else wrong!
     
  23. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    You mean the lookahead is giving weirdness?
    (note I had a sign error in the code I posted, edited afterwards to correct)
     
  24. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739

    Yes, lookahead still freaking out. Goes backwards about half way between the teleport positions before over correcting and then returning to where it should be. Across about 7 or 8 frames, maybe more.

    I fixed the sign code. Just added a - to the posDelta. Thought it was my mistake, putting wrong foot in front of the other in the pos - otherposition bit.
     
  25. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    Here's what it looks like:

     
  26. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    hmmm...I'd like to take a look at that issue in more detail. As far as I can see from the CM code it should work without a hitch. Care to send me the project, to save us both some time?
     
  27. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    It's a mess of experiments... I'll make sure there's some warning lights on somewhere in it...

    I don't really know how to clean it up.

    Or where to store/send it too... email link? Private message?
     
  28. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    My folder structure might be done wrong. This is the only options I have... but you'll need some of the artwork... which don't show up here, at all:

    Screen Shot 2018-04-19 at 2.29.01 am.png
     
  29. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    Restarting Unity fixed the above problem. Package is 1.6MB ... where to host/send/how?
     
  30. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    Aaarrggh! I should have spotted the problem... in the code sample above you're doing
    Code (CSharp):
    1. myCamera.OnTargetObjectWarped(otherTransform, teleportDistance);
    that's wrong, you should be doing
    Code (CSharp):
    1. vcam1.OnTargetObjectWarped(otherTransform, teleportDistance);
    Your myCamera variable is of type CinemachineComponentBase, which is not useful in this context. You need to apply the operation to the entire vcam, not just a random component within it.
     
    Last edited: Apr 18, 2018
  31. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739
    THANK YOU!!!

    This works...

    But who is "he" you're referring to up there ^

    And my apologies for making this mistake... perhaps you can help me to not make the same mistake again...

    1. I'm still not clear about how a Script attached to an object knows about the object it's attach to, especially if it has a different class name to its "parent"... but leave that alone for now...


    2. when reading these docs:

    https://docs.unity3d.com/Packages/c...OrbitalTransposer.html?q=OnTargetObjectWarped

    I see OnTargetObjectWarped as being derived from MonoBehaviour, via CineMachineComponentBase, which is why I got that component and created the line to access that method via CineMachineComponentBase... looking at this document, how would I ascertain that I should be calling this method on the entire camera, or know that it was even possible to call it on the whole camera?

    Screen Shot 2018-04-19 at 5.20.59 am.png
     
  32. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,728
    @Deeeds sorry to refer to you in the third person - in my head I was talking to anyone who might come along and read this thread later, since I had already PM'ed you with the same information. I've corrected the post.

    The clue in the doc is in the description of the class as a component in the vcam pipeline. You were getting the glitch because you were applying the delta only to the body component of the pipeline; the aim component was never informed.

    It was just bad luck that you found this method. The real one to call was in the vcam, here: https://docs.unity3d.com/Packages/c...amera_OnTargetObjectWarped_Transform_Vector3_ as it will apply the delta to all the vcam components in the pipeline.

    CinemachineComponentBase is for vcam components, not for the vcam itself. You never need to access vcam components directly. The class is only exposed in case you want to make your own custom vcam components. You should be focusing on the classes CinemachineVirtualCamera and CinemachineVirtualCameraBase.
     
    Last edited: Apr 18, 2018
  33. Deeeds

    Deeeds

    Joined:
    Mar 15, 2018
    Posts:
    739

    "It was just bad luck that you found this method... " this makes a LOT of sense...

    I was wondering around, through the Cinemachine docs, trying to get a feel for what can and can't be done, when I found the warp function... I hadn't yet got to point where I had a holistic view of Cinemachine to even realise that CinemachineBaseComponent wasn't the entire camera... I kind of thought it was... as "Base Component" made me think it was the base component for a Cinemachine camera...

    I'm a moron.

    THANK YOU!!!