Search Unity

Simple Waypoint System (SWS) - Move objects along paths

Discussion in 'Assets and Asset Store' started by Baroni, Dec 10, 2011.

  1. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Could you please post a screenshot of that, so I can take a look? I would guess that your waypoints are either placed too close too each other, or your world scale is very low.

    If you choose the "loop" type on the movement script, a "closed" checkbox appears which creates a segment from the last to the first waypoint automatically. Make sure that your first and last waypoint are not placed in the same position for this, because it is not necessary.
     
  2. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    @josefgrunig to follow up on this, I investigated the issue and took a deeper look at the underlying tween logic. Unfortunately I was not aware that DOTween does not support the GoToWaypoint method (used for startPoint) on non-linear easing, as written in the scripting reference.

    However, I can suggest a workaround (or two) depending on your use-case: leave the startPoint at 0 and use tween.fullPosition to manually send the object further along the path instead.

    1. If you know or would like to use a seconds value to send the object forward at a position in time, simply set splineMove.tween.fullPosition = yourTimeSeconds. For example if "yourTimeSeconds" is 2, your object will be set at a position with 2 seconds elapsed.
    2. If you would like to use a percentage value along the path, it get's a little bit more complicated, since we need to get the full duration in seconds first, but here's the code that does this:

    Code (CSharp):
    1.         IEnumerator Start()
    2.         {
    3.             splineMove move = GetComponent<splineMove>();
    4.  
    5.             //wait a few frames until the tween is fully initialized
    6.             while (!move.tween.IsInitialized()) yield return null;
    7.  
    8.             move.tween.fullPosition = move.tween.Duration() * 0.5f; //0-1, 0.5 = 50%
    9.         }
    Hope that helps to achieve what you're looking for, and sorry for the workaround required.
     
  3. josefgrunig

    josefgrunig

    Joined:
    Jan 23, 2017
    Posts:
    62
    Any update on this @Baroni? Thank you!
     
  4. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    I actually pinged you on the last post ;)
     
  5. josefgrunig

    josefgrunig

    Joined:
    Jan 23, 2017
    Posts:
    62
    Sorry @Baroni, was still on page #42 of the forum.
    Changing the position forward in time would probably skip the ease-in tween I suppose.

    It's not mandatory for me to start at a waypoint 1, I made this choice as a workaround of another problem: I placed the Follower exactly at waypoint 0 position, but for some reason for the first frames it gets in the opposite direction and only then it aligns to the path. Looking closely to the path I see it actually makes a curve at the very beginning. Is this correct? I need to precisely know were the path starts otherwise I have glitches in the animations.

    Attached a frame by frame video:
    http://www.grunig.eu/tmp/SWS_Path_Issue.mov
     
  6. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Yes, that would be the expected result, as the easing is applied on the full path, not only the start waypoint + remaining path.

    Thanks for the video. This issue is listed in the FAQ with the heading "On the first waypoint, my object goes back and forth before moving on the path normally.". To further explain the background for this: it happens because DOTween tries to calculate a smoothed out path with a pre-defined curve detail, taking the first 2 waypoints into account. If your world scale is very low and the waypoints are placed too close to each other, the curve detail is too high to calculate the first segment correctly. You can either try moving the waypoints more apart, or even removing the first waypoint (so then the first waypoint is further away) if it is not necessary.
     
  7. ml785

    ml785

    Joined:
    Dec 20, 2018
    Posts:
    119
  8. hm2337

    hm2337

    Joined:
    Jun 9, 2019
    Posts:
    9
    This asset does not have AI elements like Wander behavior, right? Because I was wanting to use a combination of 'Wander' and 'Waypoint' behavior, and the Waypoint creation in this asset look extremely useful. Sorry for noob question.
     
  9. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @ml785, there is no separate "plane controller" in the asset; in the screenshot the plane is using the regular spline script with a custom rotation on waypoints along the path (indicated by the small arrows on the path).

    @hm2337 The movement scripts come with a Looptype = Random setting, which is a semi-wandering behavior calculating a random path including each waypoint once, per loop. What most developers do is to use the navMove script (using Unity navigation and pathfinding), write their own wander+chase player behavior and use it in combination with the waypoint movement. E.g. for a move on path > see player, cancel path, chase player > search player > return to path behavior.
     
    ml785 likes this.
  10. ml785

    ml785

    Joined:
    Dec 20, 2018
    Posts:
    119
    -Can an AI jump from platform to platform along a spline?
    -Is this something that can be used in harmony with A* Pathfinding?
     
  11. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    If an object is moved using a SWS movement script, you can still do local transform updates on its child objects. For example, if a character consists of a "main" game object and the actual "character" game object as a child, you could do your jumping behavior on the local y-position of the child game object.

    Movement scripts are exclusive of each other, and also with physics. There can only be one script at a time controlling game object positions and rotations. If you wish to implement more advanced behavior such as patrolling and player chasing, you would disable one movement script and activate the other.
     
    ml785 likes this.
  12. SecretTomodachi

    SecretTomodachi

    Joined:
    Nov 24, 2019
    Posts:
    24
    Sorry for the silly question, but is it possible to create waypoint prefabs using this?
     
  13. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @SecretTomodachi, waypoints and paths can be prefabed and then instantiated at runtime at your desired position, if that was your question. The web player also has a sample for this in the runtime scene.
     
  14. SecretTomodachi

    SecretTomodachi

    Joined:
    Nov 24, 2019
    Posts:
    24
    Perfect! Thank you!
     
  15. aitanar

    aitanar

    Joined:
    Dec 23, 2020
    Posts:
    2
    Hey how would it be possible to add a function to this system that would detect if another game object with the same tag collided with this one and if so then it stops in it’s path, looks at it and plays an attack animation once and then goes back to moving along its path?
     
  16. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @aitanar, for most of this you would use general Unity functionality. To give you some input:
    • "detect if another game object with the same tag collided with this one": just a basic OnTriggerEnter, there is also a sample in the events example scene where an object collides.
    • "if so then it stops in it’s path": call the Pause() method on the movement script.
    • "looks at it and plays an attack animation once": I would recommend checking other public sources, as there are multiple ways to achieve this (not related to this asset).
    • "and then goes back to moving along its path": call the Resume() method on the movement script.
     
  17. josefgrunig

    josefgrunig

    Joined:
    Jan 23, 2017
    Posts:
    62
    Hi @Baroni, can I suggest a nice to have? It would be really great to have some sort of integration of the Followers with the Timeline Asset. I mean being able to drag the timeline and see the update in the editor of the paths position. Right now it's a pain to enter the play mode to debug paths. Thank you!!
     
  18. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @josefgrunig, thanks for the feature request! Actually I do have a somewhat similar feature request on my list, which is more like a slider in the inspector, for quickly previewing the object on the path by dragging the slider handler around. Could you elaborate what exactly you are looking to debug? Is it the position of the object, rotation or something else along the path? Or if you mention Timeline, all of that at a specific time at playtime?
     
  19. josefgrunig

    josefgrunig

    Joined:
    Jan 23, 2017
    Posts:
    62
    Hi @Baroni, I am making a path with a bird following it. The bird has a lot of different animation types, like flying straight, waving, attacking, landing. All those animation are applied by a timeline's animation track controlling the birds animator. By moving back and forth the time on the timeline I am able to see the animator updating accordingly but not the position of the bird on the path: this could be really helpful to adjust the birds animation according to it's path position (think of a landing at the end or waving when going up). I think its possible to create a timeline custom track and it would be great to have it associated to a specific path. Hope it clears the idea.
     
    Baroni likes this.
  20. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    429
    @Baroni There's a problem with your code for IsPaused() check in the splineMove script

    I see above that there's an issue with pasting asset code (might get my comment removed) so I'll keep my explanation general.

    Your method Pause(float seconds = 0f) only starts a Wait coroutine if the seconds variable is greater than zero.
    And your IsPaused() method only returns true if that coroutine is running.

    However, it's very likely that a splineMove might be paused but with no set time, and is just waiting for a Resume call (at any time). For example (my code):
    Code (CSharp):
    1. public void DoMove() {
    2.         if(m_splineMove.IsPaused()) {
    3.             m_splineMove.Resume();
    4.         } else {
    5.             m_splineMove.StartMove();
    6.         }
    7.     }
    Since I initially called m_splineMove.Pause(0f);
    with the current IsPaused() check, the above always calls StartMove()

    I've changed the IsPaused method to this:
    Code (CSharp):
    1. if ((tween != null && tween.IsPlaying() == false) || waitRoutine != null){
    2.                 return true;
    3.             }else{
    4.                 return false;
    5.             }
    which takes care of checking for a existing but paused tween as well as the Wait coroutine.
     
  21. aitanar

    aitanar

    Joined:
    Dec 23, 2020
    Posts:
    2
    Great, thank you! I think the part im having an issue with is when called from another script id like to move my game object to a specific waypoint(we'll say 3 for purpose of explaining), play the attack animation once and then resume moving along its path. right now i dont know how i would get the game object to stop what it was doing (whether it be delayed on a waypoint or walking to its next waypoint) look at waypoint 3 walk over to it with the appropriate walk animation and then once there to play the attack animation once before resuming on its path to the next waypoint. yes you have the GoToWaitpoint but that teleports the game object to that waypoint and i do not want that i want it to walk from where ever it currently is.
     
  22. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @jeromeWork, thanks for the detailed report and solution proposal! Indeed the IsPaused() method just checked for the coroutine (to be resumed automatically later) and not the otherwise paused state of the tween itself. The Resume() method played back the tween anyway, but in combination with the IsPaused() check it can cause issues and might not be the intended behavior. I revised the IsPaused() contents similar to your code snippet, thanks again.
    Code (CSharp):
    1. return waitRoutine != null || tween != null && !tween.IsPlaying();
    ---
    @aitanar
    Correct, GoToWaypoint() is not what you want to use. You will want to do this instead:
    Code (CSharp):
    1. yourMove.moveToPath = true; //start from current position
    2. yourMove.startPoint = 2; //third waypoint
    3. yourMove.StartMove(); //start movement tween
    You could either use a trigger at waypoint 3 to pause the movement script and execute your other animation code, or add a waypoint event to it at runtime, both showcased in the Runtime and Events example scenes. Hope this gets you on track.
     
  23. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    429
    @Baroni Got another one for you :)

    Your public method IsMoving() (in splineMove.cs) is oddly named
    /// Returns whether the movement tween is active.
    /// Also true when moving to path or paused.
    I've had to add a new method IsActuallyMoving()
    returns a bool based on
    if(tween != null && tween.IsPlaying())
     
  24. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    @jeromeWork that's on purpose though - the method returns whether there is a tween at all. It could be currently paused and scheduled to be resumed later, which would mean that "IsMoving" is technically still correct.

    P.S. the "tween" variable is public, you can add your own extension methods, depending on your use case and requirements, and do not need to modify SWS scripts directly.
     
    jeromeWork likes this.
  25. jeromeWork

    jeromeWork

    Joined:
    Sep 1, 2015
    Posts:
    429
    Yes, I should totally get into the habit of using extension methods! :)

    I think for me the naming is misleading. I was looking to check whether the object was actually moving on the path, and I think understandably went to the 'IsMoving()' method. The code is well commented so it's not a problem, but perhaps calling it IsActive() or IsInitiated() might better encompass the paused state.
     
    Baroni likes this.
  26. 52cwalk

    52cwalk

    Joined:
    Nov 23, 2013
    Posts:
    15
    After import the tool, I meet some error,please help me.
    upload_2022-3-17_16-22-22.png
     
  27. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    @52cwalk Do you have a "Transform" and "Path" script in your project that does not use namespaces? There could be a conflict with DOTween trying to find the correct script. You can easily try this out when importing SWS in a new project, where the errors should not occur.

    Please do not misuse reviews on the Asset Store for support.
     
    Last edited: Mar 17, 2022
  28. Andreas12345

    Andreas12345

    Joined:
    Oct 17, 2013
    Posts:
    526
    I have this setting:
    upload_2022-4-8_14-39-21.png
    But still the Player turns after a loop, i read the FAQ, but dont solved my problem, what can i do?
    Its closed loop checked Full 3d and Look Ahead 0
     
  29. Andreas12345

    Andreas12345

    Joined:
    Oct 17, 2013
    Posts:
    526
    I see the issue but i cannot fix it: upload_2022-4-8_17-4-30.png
     
  30. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    @Andreas12345 The two points in your last screenshot, are they placed by DOTween (not waypoints)? Unfortunately I could not see if you are using a bezier path, where you could decrease the detail on the last segment. You could also try placing the last waypoint nearly on top of the first and disable closed loop.
     
  31. Andreas12345

    Andreas12345

    Joined:
    Oct 17, 2013
    Posts:
    526
    i tried to disable closed loop how you suggested: DOTween place the white ones. I use standardPath and SplineMove script upload_2022-4-8_18-54-0.png
     
  32. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    @Andreas12345 I have heard of this issue before but was not able to reproduce this. Maybe you could send me scene that contains the issue in a private message?
     
  33. bakershah

    bakershah

    Joined:
    Jul 15, 2014
    Posts:
    17
    Hello,

    I am having a problem with getting one of my characters to face forward when they are moving on the spline.
    Attached are my settings and the issue in scene. I've tried locking rotations but every time No matter the direction the character is rotated at including children it resets to looking one way. Any recommendations on how to fix this?




    Screen Shot 2022-06-05 at 5.20.16 PM.png Screen Shot 2022-06-05 at 5.25.02 PM.png
     
  34. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @bakershah, thanks for posting here. Please see the FAQ on the following point: "My object has the wrong rotation when following a path.". The issue usually comes when using external models with a different forward orientation than SWS / DOTween expects. Please follow up if you continue having issues. Note: "LookAhead" is how far the object should simulate its path ahead of the path in a range from 0-1 (0-100%), not a rotatation setting.
     
  35. power_champ

    power_champ

    Joined:
    Oct 6, 2020
    Posts:
    10
    Hi all,

    Could anyone help with the correct procedure to swap from one path to another and begin (read teleport) at a specific waypoint?

    I imagine it is some combination of the following but I am not having any luck.

    Code (CSharp):
    1. splineMove.SetPath(newPathManager);
    2. splineMove.ResetToStart();
    3. splineMove.GoToWaypoint(indexToStartAt);
    4. splineMove.currentPoint = indexToStartAt;
    Any help appreciated.
     
  36. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @power_champ,

    the methods you are calling are somewhat exclusive to each other. For example, calling SetPath() and ResetToStart() in sequence does not have any effect since that would be basically "assign path & stop". Also, modifying variables like currentPoint should be done before creating the tween via SetPath().

    It's more simple than that, please try:
    Code (csharp):
    1. splineMove.startPoint = indexToStartAt;
    2. splineMove.SetPath(newPathManager);
     
  37. power_champ

    power_champ

    Joined:
    Oct 6, 2020
    Posts:
    10
    Thanks for the fast response, that has solved half my problem.

    Is it possible for the splineMove to resume from the new waypoint? Currently moves to waypoint 0 before continuing.

    splineMove.moveToPath also seems to restart it from waypoint 0 entirely.
     
  38. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    If you would like the object to teleport, you should keep or set moveToPath = false too (or avoid setting it to true) before calling SetPath(). With the code above, the object should then start moving on the new path at "indexToStartAt".

    I have tried this in example scene 7, with the path switch sample and it works as expected without moving to waypoint 0 first.
     
  39. power_champ

    power_champ

    Joined:
    Oct 6, 2020
    Posts:
    10
    Sorry, just found my problem. Something else was restarting the tween after the move...

    Thanks again for your help, much appreciated.
     
    Baroni likes this.
  40. Hinkel84

    Hinkel84

    Joined:
    Sep 20, 2021
    Posts:
    1
    I have a problem.

    I set up a simple path for a ship (the ship has to be rotated to -90 in the editor and prefeb, to be straight on the water).
    As soon as I hit play, the ship is rotated and not using the set up -90 rotation.

    Any way to fix that?
     
  41. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @caesar_sol, did you put your ship under a new parent object and rotate the child? If you rotate the main object, it will have no effect, since the movement script controls that. Rotated child objects will maintain their rotation.

    There is a note on the FAQ for this.
     
  42. TillmaniaLtd

    TillmaniaLtd

    Joined:
    Jan 29, 2013
    Posts:
    65
    Hey,

    Is it possible to create paths with waypoint via script at runtime?
     
  43. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @TillmaniaLtd, yes - if you already own SWS, please have a look at example scene 7, sample 1 or 7. Sample 1 instantiates a path prefab, while sample 7 creates it from scratch using absolute waypoint positions.
     
  44. TillmaniaLtd

    TillmaniaLtd

    Joined:
    Jan 29, 2013
    Posts:
    65
    Legend, looking now!
     
  45. SIV

    SIV

    Joined:
    May 7, 2014
    Posts:
    219
    Hello,

    Im using this system for board game, im stuck to make the path move backward instead of forward, i tried ti tick "reverse" at runtime but nothing change, what to do please ?

    I tried "GoToWaypoint" but it just zap to that waypoint instead of animating to it.
     
    Last edited: Jun 23, 2022
  46. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    Hi @SIV, the "reverse" checkbox is a boolean that is only checked when the tween starts. So if you toggle it at runtime, you have to restart the tween for it to have any effect.

    If the tween is already running, you should use methods instead. Specifically, try the Reverse method.
     
  47. SIV

    SIV

    Joined:
    May 7, 2014
    Posts:
    219
    I use Pause and resume each time so once the piece in the desired number i pause the spline and then throw dice again etc.
     
  48. TillmaniaLtd

    TillmaniaLtd

    Joined:
    Jan 29, 2013
    Posts:
    65
    Hey, Is there a way to stop the direction from snapping front back to front on a really sharp turn? And is there a way to make the path follow animation work with a root motion based animation?
     
  49. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,264
    This would work with the Reverse() method too, you just have to call it before Resume(). If you would like the object to move from its current position to a target waypoint, you would instead do:
    Code (csharp):
    1. splineMove.Stop();
    2. splineMove.startPoint = targetWaypointIndex;
    3. splineMove.moveToPath = true;
    4. splineMove.StartMove();
    When making use of path rotation, the object rotation is directly influenced by the path. Meaning if the path has sharp turns, the object will follow that rotation too. I can only guess that you might see an unnatural rotation if your waypoints are positioned too close to each other, or in a very small world scale. Try offsetting them a bit and see if this helps. If you would like to have more control over rotation, you could use the waypoint rotation feature - please see the separate example scene for this.

    Unfortunately not. Tweens create a more or less fixed animation which is playing back in an update loop. On the other hand, root motion uses a combination of physically influenced and generic speed input per bone. This would require a separate movement script to make use of, but the ones included are not feasible for this.
     
  50. SIV

    SIV

    Joined:
    May 7, 2014
    Posts:
    219
    It works but it goes directly to that point, for example if i set it 3 waypoints behind it from from current to -3 rather than -1 -2 -3