Search Unity

Can we update Path Position via script?

Discussion in 'Cinemachine' started by protopop, Feb 16, 2019.

  1. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    Im stuck on Unity 5.6 for the time being due to some 2017 incompatibilities.

    I can make a vcam and dolly in 5.6. But i can;t figure out a way to animate the Path position so that the dolly will play.

    Its there a way to access this? i already have
    public CinemachineVirtualCamera currentCamera;
    public CinemachineBrain cBrain;

    but i dont see .pathposition in any of them.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    var dolly = currentCamera.GetCinemachineComponent<CinemachineTrackedDolly>();
    dolly.m_PathPosition = bla;
     
  3. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    Thank you. I could not for the life of me find that:)

    I wrote this basic script to control it. What's nice is you can control the easing in Cinemachine, so i dont have to code a bunch of eases.

    Im looking forward to using Timeline once i can update to 2017, but for now i can use a few components like this for basic cinematics. plus i find Cinemachines Dolly interface is really intuitive. Maybe i can figure out how to add a basic blend by chining together components at the end of each one.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Cinemachine;
    5.  
    6. public class VCamControl : MonoBehaviour
    7. {
    8.  
    9.     public CinemachineBlendDefinition someCustomBlend;
    10.     public CinemachineVirtualCamera currentCamera;
    11.     public CinemachineBrain myBrain;
    12.     public CinemachineTrackedDolly cinemachineTrackedDolly;
    13.  
    14.     public float pathPosition = 0.0f;
    15.     public float speed = 0.1f;
    16.     public float pathLength;
    17.  
    18.     public Transform cameraTrasform;
    19.     public Vector3 cameraTransformOriginal;
    20.  
    21.     void OnEnable()
    22.     {
    23.         cameraTransformOriginal = myBrain.OutputCamera.transform.localPosition;
    24.         myBrain.enabled = true;
    25.         pathPosition = 0.0f;
    26.         cinemachineTrackedDolly = currentCamera.GetCinemachineComponent<CinemachineTrackedDolly> ();
    27.         pathLength = cinemachineTrackedDolly.m_Path.MaxPos;
    28.  
    29.     }
    30.  
    31.     void OnDisable()
    32.     {
    33.  
    34.         myBrain.enabled = false;
    35.         myBrain.OutputCamera.transform.localPosition = cameraTransformOriginal;
    36.  
    37.     }
    38.    
    39.     void Update()
    40.     {
    41.         if (pathPosition < pathLength) {
    42.             pathPosition += speed;
    43.             cinemachineTrackedDolly.m_PathPosition = pathPosition;
    44.         }
    45.     }
    46. }
    47.  
     
  4. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    Im using camera damping, so the camera arrives at the end of the path a few moments after the actual pathposition value reaches the end.

    Instead of switching vcams when i reach the pathposition max value, i should do it when the actual camera settles into the end.

    Do you know if there is some sort of CameraFinished or actual camera position o path value that i can read and use instead?
     
  5. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    You can add a trigger, and when the camera enters it, irrespective of how it gets there, you can do your thing.
     
    protopop likes this.
  6. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    Thats' a clever idea:) A script based checked would be simpler if anyone knows of one in the api, but a physical solution is a great failsafe. Thank you.
     
  7. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    Maybe something like if (Vector3.Distance(vcam.State.FinalPosition, waypoint.position) < threshod) ?
     
    protopop likes this.
  8. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    Its close:) Do you know how i can get a reference to the last waypoint on the dolly track?

    I tried cinemachineTrackedDolly.m_Path..... but theres no waypoint in there. Is it under something else?
     
  9. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    Use this method in m_Path:

    Code (CSharp):
    1.         /// <summary>Get a worldspace position of a point along the path</summary>
    2.         /// <param name="pos">Postion along the path.  Need not be normalized.</param>
    3.         /// <param name="units">The unit to use when interpreting the value of pos.</param>
    4.         /// <returns>World-space position of the point along at path at pos</returns>
    5.         public Vector3 EvaluatePositionAtUnit(float pos, PositionUnits units)
    6.         {
    7.             return EvaluatePosition(ToNativePathUnits(pos, units));
    8.         }
    9.  
     
    protopop likes this.
  10. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    Screen Shot 2019-02-18 at 1.18.13 PM.png

    Im stuck. The PositionUnitys and Evaluate keywords are red. It says it doesnt recognize them in thsi context.

    I already put using Cinemachine at the top.

    Do you know if i need to put another namespace?

    I feel like i am so close. I just cant seem to get the position of the last waypoint in a path.
     
  11. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    It's defined in the CinemachinePathBase class.
    Can you do dolly.m_Path.EvaluatePositionAtUnit(myPathPosition, dolly.m_Units) ?
     
    protopop likes this.
  12. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    Thanks for your help on this:)

    I got it working with this

    Code (CSharp):
    1. Vector3 finalWaypointPos = cinemachineTrackedDolly.m_Path.EvaluatePositionAtUnit (pathLength, CinemachinePathBase.PositionUnits.PathUnits);
    2.         distanceToTarget = Vector3.Distance (currentCamera.State.FinalPosition, finalWaypointPos);
    Im going to make a second option to handle free camera with a timer, since its completion cant be based on distance.

    Its no timeline, but i now have chaining DollyTracks swooping around with cuts and blends using this custom "Shots" component.
     
  13. protopop

    protopop

    Joined:
    May 19, 2009
    Posts:
    1,561
    PS its going in this game (ipad pro screenshots) :)

    protopop.jpg

    skrall.jpg
     
    harumaron and Gregoryl like this.
  14. monokraft

    monokraft

    Joined:
    Jul 9, 2018
    Posts:
    2
    Hi everyone,

    I have a simular question/request. I have a CinemachineTrackedDolly VCam setup in Unity 2020.2. On mouse click object I would like to update the path position of the VCam. The above script however doesn't seem to work for me (can't reference the dolly track). Is there an other way to move the camera along the dolly track OnMouseDown?

    Any help appreciated!
     
  15. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,730
    @monokraft Yes, you can do
    vcam.GetCinemachineComponent<CinemachineTrackedDolly>().m_PathPosition = bla
     
  16. monokraft

    monokraft

    Joined:
    Jul 9, 2018
    Posts:
    2
    Thanks Gregoryl! Could you provide me with a little more context on how to execute this line of code in a script?

    Thanks a lot!