Search Unity

Using Cinemachine Dolly path in v2.0

Discussion in 'Cinemachine' started by Adam_Myhill, May 17, 2017.

  1. gurbrindersingh

    gurbrindersingh

    Joined:
    Feb 28, 2017
    Posts:
    32
    sure. I will zip a test scene to separate project and share.
     
  2. gurbrindersingh

    gurbrindersingh

    Joined:
    Feb 28, 2017
    Posts:
    32
    Here is a quick sample project to take a look into an issue.
     

    Attached Files:

  3. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Thanks for the project. The problem is that your path has speed discontinuities and a low resolution. You want to avoid situations like this, where the density of the track changes suddenly:

    upload_2021-6-10_8-53-39.png

    Adding a nonzero tangent to waypoint 1 makes a big difference:

    upload_2021-6-10_8-55-12.png

    Also increasing the path resolution helps to smooth things out:

    upload_2021-6-10_8-56-45.png
     
  4. gurbrindersingh

    gurbrindersingh

    Joined:
    Feb 28, 2017
    Posts:
    32
    Can you please post the screenshot from inspector for waypoint settings? Setting non zero tangent on waypoint 1 distorts the path for me. Or alternatively will you be able to upload the zip file back here if movement is working smoothly for you in this case?
     
  5. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Adjust point 1's z position to compensate.

    upload_2021-6-10_9-28-44.png
     
    gurbrindersingh likes this.
  6. gurbrindersingh

    gurbrindersingh

    Joined:
    Feb 28, 2017
    Posts:
    32
    Thanks for this tip @Gregoryl. This is working mostly fine for me in this case.
     
  7. gurbrindersingh

    gurbrindersingh

    Joined:
    Feb 28, 2017
    Posts:
    32
    Is it possible to offset the dolly cart from the center of the track to the width of the track? It will be very useful to allow an object move freely (suppose on x axis) and still follow the track.
     
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    The cart travels along the center of the path. Path width is for display in editor only. You can move the cart's child, however, and that will have the effect you seek.
     
    gurbrindersingh likes this.
  9. gurbrindersingh

    gurbrindersingh

    Joined:
    Feb 28, 2017
    Posts:
    32
    Okay, Thanks Greg!
     
  10. Blarp

    Blarp

    Joined:
    May 13, 2014
    Posts:
    269
    When I drag VCam into a timeline, it would be extremely nice if it just plopped the path markers in the timeline and I can drag them.

    Hitting record on every path is EXTREMELY annoying and I don't like it whatsoever. The workflow involves a ridiculous amount of clicking just to put the paths in the timeline, just to be deleted as I adjust the paths
     
    Gregoryl likes this.
  11. yazoubello

    yazoubello

    Joined:
    Jan 5, 2021
    Posts:
    9
    I can move camera on dolly track, but I can't seem to figure out how I can move the game objects on a track. Are there some tutorial for Kodi nox this? Thanks!
     
    Last edited: Jun 23, 2021
  12. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Add the CinemachineDollyCart behaviour to objects that you want to move on the track.
     
  13. SamRock

    SamRock

    Joined:
    Sep 5, 2017
    Posts:
    250
    I am using CinemachineDollyCart for a monster to follow the player (2.5D game, fixed path).

    Thanks to @Gregoryl inputs on other thread, I used "FindClosestPoint" to get the right position to move to. I was not able to control the speed of movement, so I used Lerp to make the monster slowly move towards player's location. All works great.

    Now, I am stuck at making the monster turn towards player's direction. When moving cart backwards, how do I make the object turn direction to look at the player? It seems the object assigned to the cart only looks at a fixed Forward.
    Is there a way I can control this, that like we do for a Vcam? Or do i manually set the LookAt setting?
     
  14. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Make your object a child of the cart
     
    SamRock likes this.
  15. adrianov

    adrianov

    Joined:
    Dec 23, 2015
    Posts:
    15
    Hi folks,

    I'm creating dolly paths and cameras in code, and it's been working pretty well but have just run into an issue where my dolly camera (set to auto dolly) does not move at all along the dolly track unless I've set the dolly path to `Looped`; the issue here is that setting it to `Looped` causes the camera to hop to different track sections at the start of the dolly move (when the start and lopped end of the track are close to one another) and makes my camera move strangely. I don't actually need the track to loop and assume that the auto dolly feature should work regardless of the path being looped or not. Any thoughts? @Gregoryl?
     
  16. adrianov

    adrianov

    Joined:
    Dec 23, 2015
    Posts:
    15
    Never mind. I had my Tracked Dolly Position Units set to Normalized. Setting it to Distance made the auto dolly work again with a non-looped track. Any reason why this is an issue, though? Seems an easy setting to set "incorrectly", breaking the expected behavior, but with no obvious reason.
     
    Gregoryl likes this.
  17. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Can you log a bug with a repro project? That would ensure that this issue gets tracked and addressed.
     
  18. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,932
    I understand that this was designed only for specific use-cases - eg a camera that follows a target, not a camera that itself is the primary focus of the scene (i.e. it's great for follow-cams on a car, but it's not intended for tourist-cams that roam a scene, which is why it struggles with them a bit), but I'm hoping that the current (CM 2.6.x+) versions can now handle this a bit better?

    Specifically: when trying to do the (preivously frequently asked) behaviour of "create a track, set waypoints for camera position + look-direction", what's the recommended approach? Is it still the same as the advice from 5 years ago, or are there better approaches now? e.g. maybe there is now a more advanced CM component that is able to do contextual 'position + aim' together, which would directly solve the problems for these use-cases?

    From what I can tell the main recommendations / options are:

    1. Make 2 tracks, one for the camera, one for the 'invisible thing to look at', and waypoint them to have same number of waypoints, and manually go through by hand and position the 'invis target' to be somewhere that causes the camera at wach waypoint to be correct. I think this is the least-bad option, but it still has obvious problems: it stops you from being able to control the speed of the dolly any way except in normalized units, and visualising it in editor is a nightmare (lots of unnecessary clicking back and forth to check any given waypoint)
    2. Make 1 invisible object per waypoint, position it close to the track, and tell CM to look at all the objects. I think this fails because either they're close to the track and interpolation is horrible, or they're far from the track and they conflict with each other
    3. Use the Timeline to try and make one or both the above less painful (but as far as I can tell it's still painful, just slightly less painfil. And it forces you to use the Timeline, which a lot of people don't/won't do)
    4. ... Something else? ...
    5. Stop using CM for this :) - Dollys weren't meant to be general purpose and trying to use them this way is kind of doomed to always be clunky. CM by design can handle movement but not aim, isn't able to do contextual situations where both have to be set together, and as that's a core design feature anything that tries to make "move + aim together" is always going to be difficult/hacky.
    6. Write some custom scripts to change the way CM works ??? but my guess is that anything that tries to remove CM's dependence on "postiion and aim are always separate" will just cause bugs with other parts of CM - probably not worth the pain.
     
  19. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    The Cinemachine Path components allow you to author a spline-based path through space, to be used for general purposes. The implementation does not encode any rotations other than the path tangent at any point, and the roll that can be associated with it.

    Your use case is that you want that plus extra data along the path to be used to set something, in this case the camera rotation. You can certainly make another component to hold this extra data, and you you could also make a custom CM extension to read it and apply it to the camera. You would set the vcam's Aim to Do Nothing, then in your custom extension, apply the computed rotation to the vcam's aim. Have a look at CinemachineCameraOffset.cs, to see an example of a Cinemachine extension that tweaks the camera's state. Use it as a basis for your own extension.
     
  20. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,932
    Thanks. So (reading the source code for the Offset class) ... looks like the correct approach is to ignore all calls to that callback until/unless "stage == Aim" (sounds sensible, but I can't seem to find any docs on this - is there a guide for this? API docs don't give any context for the calls), which is nice and simple.

    Experimenting with tangents ... I discovered that the tangents given by CineMachineSmoothPath are incompatible with the tangents used by CineMachinePath (directions appear similar, but they use incompatible weightings) - what is going on here? Which one is more 'correct'? Is the best route to ignore/discard both and write a standard "SplinePath" component? (feels like I'm doing something wrong to be discarding so much of CM just to get a working spline, but inconsistent definition of Tangent is a worrying starting point). NB: this is with CM v2.6.17, which UnityPackageManager is telling me is most recent - I'm assuming that's the best to use?
     
  21. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,932
    This seems to work, although I expected an 'aim' class to be directly setting the aim (I guess the problem is that we're not providing a valid alternative to "HardLookAt, POV, Composer, DoNothing" etc here -- wouldn't that be the correct approach? Is there a guide to implementing one of those and inserting it into the dropdown on CineMachineVirtualCamera?):

    Code (CSharp):
    1. using Cinemachine;
    2. using UnityEngine;
    3.  
    4. public class CMAimerPathwardsInCameraPlane : CinemachineExtension
    5. {
    6.     protected override void PostPipelineStageCallback( CinemachineVirtualCameraBase vcam_fake, CinemachineCore.Stage stage, ref CameraState state, float deltaTime )
    7.     {
    8.         if( stage == CinemachineCore.Stage.Aim )
    9.         {
    10.             if( vcam_fake is CinemachineVirtualCamera vcam )
    11.             {
    12.                 var dolly = vcam.GetCinemachineComponent<CinemachineTrackedDolly>();
    13.                 var waypointPathIndex = dolly.m_Path.ToNativePathUnits( dolly.m_PathPosition, dolly.m_PositionUnits );
    14.                 var tangentNormalized = dolly.m_Path.EvaluateTangentAtUnit( waypointPathIndex, CinemachinePathBase.PositionUnits.PathUnits ).normalized;
    15.  
    16.                 /** Source code implies this will be needed, since we're discarding the whole 'look at' data here ? */
    17.                 state.ReferenceLookAt = CameraState.kNoPoint;
    18.                
    19.                 /** Fill "correctOrientation" with your desired Aim direction ... */
    20.                 var tangentIn2DPlane = new Vector3( tangentNormalized.x, 0, tangentNormalized.z );
    21.                 var correctOrientation = Quaternion.LookRotation( tangentIn2DPlane, Vector3.up );
    22.                
    23.                 /**
    24.                  * Extensions aren't allowed to directly set Orientation (no setter), I think?
    25.                  * So we have to "pre-unset" the aim and then set it, via the "correction" var...
    26.                  */
    27.                 var wrongOrientation = state.RawOrientation;              
    28.                 state.OrientationCorrection = Quaternion.Inverse(wrongOrientation) * correctOrientation;
    29.             }
    30.             else
    31.                 Debug.LogError( "Unity CineMachine: the vcam is not a vcam; no idea why" );
    32.         }
    33.     }
    34. }
     
  22. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    It looks like you're trying to set the camera to look in the same direction as the path tangent. Is that what you want? If so, then you don't need any custom code - you can just put a passive vcam in a dolly cart. A passive vcam is a vcam that has DoNothing in Aim and Body.

    Another alternative would be to use TrackedDolly in a vcam, but with the Camera Up mode set to Path. That has the effect of making the camera look along the path tangent.

    upload_2023-3-3_16-0-58.png

    If you subsequently want to correct the rotation to force the camera to look parallel to the XZ plane, then you could write a simple general-purpose extension that does that without any dependency on other things in the vcam's pipeline - just nudge the camera's local up to be parallel to world up.

    To answer your question, you could package your logic above in an "Aim" component instead of an extension if you like. To do that, duplicate an existing aim component, say CinemachineHardLookAt.cs, rename it, and modify the "MutateCameraState" method. You can set CameraState.RawOrientation. Your custom Aim component would appear automatically in the vcam popups (as does your custom extension).

    Just to be clear: the vcam pipeline stages are invoked in the order declared in the enum. For each stage, your custom Body/Aim/Noise component or extension is allowed to look at and modify anything in the CameraState object passed in. There is no requirement that anything be done in any of the stages - procedural code is purely optional. If nothing is there at all, then the vcam will sit wherever its transform tells it to be.
     
    Last edited: Mar 3, 2023
    a436t4ataf likes this.
  23. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,932
    What I've ended up with, seems a good combination of 'smallest number of new scripts', and 'working the way CM wants to work':

    * Build a path, using a custom path component that works around the issues in SmoothPath (it can't be modified, all tangents are fixed) and Path (it can't be smoothed, all tangents are manual).
    * Put a DollyCart on there (NO cameras involved), and name the GameObject something like 'CartContainer' (its only purpose is to be a container for other GameObjects)
    * Create one vcam for each 'type' of look behaviour you need: e.g. 1 for 'look at target', 1 for 'look along path-tangent' (roller-coaster mode), 1 for 'look controlled by path' (keyframe mode)
    * Write new scripts to add the missing functionality in CM for any Aim modes you need that don't exist out-of-the-box
    * Put all the vcams as children of the CartContainer GO
    * Write a script to turn the vcams on/off during playback. NB: this also changes the params of the cameras where needed - e.g. when you need to 'LookAt' it first enables the LookAt_vcam, and then second changes the .LookTarget in that cam's settings. It's edge-triggered: it waits for an event to happen that requires a change-of-camera, then selects the appropriate vcam, and invokes vcam.MoveToTopOfPrioritySubqueue(); - CineMachine handles the rest

    Net effects:
    * number of vcams is small and manageable: it's directly proportional to the number of stylistically-different shots needed
    * each vcam does 'one thing only': instead of making one dolly-vcam with a custom 'AimChooser' script, that intelligently switches aim-modes during playback, and gets more complex the more modes we add ... each vcam has only one aim script and 0-or-1 custom extensions, with each extension doing only one thing
    * blending works as normal, for free (because all the vcams are live + enabled at all times)
    * performance isn't an issue (because 'number of vcams' is O(1) in number of shots/camera-views needed)

    Suggested improvements (probably already included in CM-v3):

    - [I am suspicious I've done something wrong on this part, but I've read through the CM docs a couple of times and didn't notice anything that said to do it differently]: 'Choosing which vcam should be live' should probably be a whole class/component -- the current 'integer priority' system should probably be the output here, not the input. Ideally this would be a set of swappable classes something like "CinemachineCameraSelector*". e.g. I should be able to add/use something as complex as "CinemachineSelectUsingVisualScripting" (uses a 2d visual script that looks like shader-graph). Or something as simple as "CustomSelector" which puts the selection/prioritization logic into a single callback methos.

    This would be attached to / referenced from the Brain component - so that it's easy to debug and see exactly why/where camera control / selection is happening. (at the moment it's buried in my scripts that have no direct connection to the Camera or the Brain or the vcams - I have to 'memorize' where my camera-choosing is happening).

    - Path/SmoothPath in v2 should be merged into one class. I've already done this locally because I couldn't stand having to choose between two partial implementations - one which can't be tweaked (Smooth's immutable tangents) and one which has no smoothing (Path) - but my implementation is hacky and CM ought to provide this by default as a stop-gap until people can move to v3.
     
    Gregoryl likes this.
  24. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    Hey, this is great feedback! Thanks for making the effort.

    I think your approach on the whole is optimal. You have grasped the "each vcam does one thing only" ethos of Cinemachine. Note that there is no reason to have more than one vcam active at any moment. CM can blend correctly out of deactivated vcams (internally it puts them on artificial life-support for the duration of the blend).

    For the camera selector, indeed you can make a script whose output is vcam priorities and whose input is game events. No reason why you can't attach that to the main camera object alongside the CMBrain. Is that more-or-less what you've done? In the CM samples, there is a simple script that does something like that, displaying an on-screen GUI for the user to prioritize a vcam.

    In CM3, the CM path implementation (which was always a stop-gap) has been replaced by the standard Spline authoring system provided by Unity 2022 and up.

    Would you be willing to share your custom path implementation with me? I'd like to have a better understanding of the changes you made. Did you do a complete reimplementation with CinemachinePathBase, or did you just add a method to auto-adjust the CinemachinePath tangents? CinemachinePathBase was conceived in order to allow users to create their custom path implementations.
     
  25. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,932
    Yeah, I noticed this during testing, it's a useful behaviour (although it is also confusing - Unity objects are supposed to stop affecting the scene once they go inactive - so for v3 I'd recommend disabling it by default and putting a tickbox/enum in Brain to switch between "BlendInactiveCameras" / "DiscardInactiveCameras").

    For this use-case (make the scene-camera follow a track, control what its looking at, all simulated using 'vcams-in-a-cart') ... I put the custom vcam-selector script on the DollyCart gameobject itself -- that gives me a selfcontained "this GameObject fully encapsulates the private set of vcams + the logic to switch between them, and none of the rest of the scene needs to know or care how its working internally".

    Ideally: CM would have a reference that:

    1. If there's only one "VirtualCameraSelector" instance in the scene, automatically points to that (like Camera automatically becoming Camera.main if its the first cam in scene)
    2. ... Otherwise: user has to select which VCS implementation to use, by drag/dropping a GO/MB onto that field

    ... because that allows us to have the 'selector' logic wherever in the scene makes most sense - but at least the Brain is aware of it - and allows us to switch between different logics (or even have different logics per-brain). Right now I'm having to use Update() to simulate the effect of a Brain looking at its field and invoking "VCS.ChooseVCamNow()")

    Sure, but right now it's horrendously ugly. Give me a week and I'll do a more sane version (I have to ship something in next few days, so I'm on a tight deadline right now :( ).

    My hack:
    1. Create a new Waypoint class (it's really nasty that there are two same-named but incompatible and almost-identical classes in CM already, both with this name :() - { v3 bodyPosition, v3 bodyTangent, v3 lookDirection }
    2. Subclass CinemachinePathBase, store a List<NewWaypoint>
    3. (add some convenience methods to convert 'current SceneCamera to NewWaypoint' (stores bodyPosition + lookDirection))
    4. Add a 'SynchToCinemachinePath' method: deletes the Waypoint[], creates a new one of same size as the List<>, copies the data from the NewWaypoint instances to the CM-Waypoint objects
    5. [what comes next is a bit convoluted / bad code design: depending on context, I either setup the tangents as listed below by auto-generating them ... or I use the stored tangents inside the NewWaypoint objects ... right now: for a blank new path it prefers to auto-gen; if it finds any non-zero tangents it assumes you want to keep the tangents)
    6. ... AND: when its finished, it runs the SmoothPath code for setting tangents (I copy/pasted the code across from SmoothPath, although I had to fix a compiler error where SmoothPath is allowed to []-index a Vector4 and non-Unity code is not (although my decompiled source from Vector4 I could see the []-indexing, I couldn't compile against it)).
    7. ... corrects the tangents: SmoothPath and Path have incompatible values/interpretation of 'tangent magnitude' -- if you take a SmoothPath and copy the tangents to a Path then they are correct directions but length is wrong. I don't know why/how, but I did a quick hack of reducing them to more sensible values. NB: this can't be done with a scalar, so I wrote some dirty heuristics that look at how close the path-nodes are in World-Space, and then clamps the tangents to be small enough that the bezier control points are sensible positions)
    ... NB: that final step (6) produces some less-than-ideal output -- but it's good-enough for a proof-of-concept. On my todo list is to delete all of the CinemachinePath* code and just use an off-the-shelf spline library since I don't think it's worth debugging whatever is wrong with the CMPath* (or: maybe its not wrong, but the time it would take to debug my own code and get it working ... would be better spent integrating standard splines and getting the benefits of them, I bleieve)
     
  26. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    The paradigm in Cinemachine is to use the concept of "Manager Cameras" for this. A manager camera is a CMCamera that owns a "private army" of other CMCameras that it selects from according to its internal criteria. These other CMCameras are generally children of the manager camera object. ClearShot, BlendList, and MixingCamera are examples of this. You can make another one that does what you need. To the CMBrain, the manager camera looks like an ordinary CMCamera with its own priority, the internals are hidden. You can make it live by activating it or raising its priority or by putting it in a timeline.
     
    Last edited: Mar 14, 2023
    a436t4ataf likes this.
  27. a436t4ataf

    a436t4ataf

    Joined:
    May 19, 2013
    Posts:
    1,932
    That sounds like a good paradigm, but I didn't notice it in the docs (is it in there?). I don't remember reading about 'manager cameras' at all -- but it would IMHO be worth a page on this technique (if there isn't one already)
     
    Gregoryl likes this.
  28. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
  29. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    I really, really don't grok this but I'm close to having it work so I hope someone can fill in the final gap (hopefully there is only one). I want a ship gameobject to sail around when I push a button. I created a "ship path" with a CinemachineSmoothPath and have the course laid out. I have a "ship cart" with a Cinemachine Dolly Cart that references that path. With that I can join the world and the animation runs automatically, once.

    Now I need the on-demand part. I assume I need a Playable Director and a Timeline (maybe not) but I don't know how to get the timeline to reflect the data in the ship path. Is there a way to generate the timeline from the path?
     
  30. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    If the ship is sailing at a constant speed, you can just set the Dolly Cart's Speed property to nonzero, and it will move without an animator. Start and stop it by enabling/disabling the DollyCart behaviour.

    If you want to drive it from a timeline, then create a Timeline on an empty GameObject, add an Animation track to it, drag in the DollyCart behaviour, and animate its Position setting. To start and stop, you can Activate/Deactivate the Timeline object.
     
    tleylan likes this.
  31. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    Oh gosh thank you. I'll start with manipulating the cart and if that works will try something more advanced.
     
  32. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    If you have a moment... I can enable/disable the dollycart and the ship moves along the path. However once it has completed the path it cannot run a second time. Is there a "reset path" option that might accomplish this? This may be a reason to move it onto the Timeline.
     
  33. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    You can set its Position property back to 0.
     
  34. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    I didn't think about a position reset, thanks. And this isn't going to be easy for you to explain I realize. But I created an empty gameobject, I added an animation track to it. I dragged the DollyCart onto the the animation track (the name reflects the change).

    An animator was added to the cart but I don't know how to specify animation of the position setting.
     
  35. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    618
    This is what you get for being knowledgeable :) Quick question, is there anything I can monitor to know when the path has completed? The dollycart doesn't seem to have any indicator. That would give me a good place to reset the position.
     
  36. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    First click this button to lock the timeline window to the timeline object:

    upload_2023-4-19_9-40-51.png

    Next, click this button to start recording the track:

    upload_2023-4-19_9-41-26.png

    Then create keyframes by dragging the time bar and setting values in the Cart inspector

    upload_2023-4-19_9-42-44.png
     
    tleylan likes this.
  37. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    7,711
    You can write a script to monitor the cart position and send an event when it reaches the end. You can use Normalized position units in the cart, and wait for the position to be 1.
     
    tleylan likes this.