Search Unity

Simple Waypoint System (SWS) - Move objects along paths

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

  1. justkedin

    justkedin

    Joined:
    Sep 19, 2013
    Posts:
    9
    OMG! Just what I really need. Thank you veeeeeeeery much sir Baroni!!! :')
     
  2. serkanos

    serkanos

    Joined:
    Jan 12, 2013
    Posts:
    28
    Vİdeo tutorial please !
     
  3. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    The package contains 5 pages of documentation (with images) and example scenes for each and every possible use case. Within 15 to 30 minutes you should know how to apply SWS' mechanics in your app. Is there anything specific you would like to know?
     
  4. g8minhquan

    g8minhquan

    Joined:
    Jun 18, 2014
    Posts:
    38
    I'm using SWS to make Enemy instances following paths in my 2D games and I have this issue, would you please show me how to fix it?
    The hierarchy of Enemy prefab contains a parent GameObject to handle SWS movements and collision detection. There is a child game object with a Sprite Renderer and an Animator with some Mechanim animations. While moving Enemy instances on paths, I notice that there is some jittering, it does not look very smooth.
    Is it because when moving the parent with SWS, it conflicts with the Animations of the child game object?
    Is there a way to solve it? I notice there is a script call MoveAnimator in the Helper folder. Is it supposed to be used in this situation? If yes, how do I use it?
     
  5. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    I can't figure out what's wrong based on your description, sorry. It could be related to your Mecanim animation or something completely different what's going on in your project. Would you please send me a small repro project (private message or email) so I can take a look at it.

    Our MoveAnimator script is used to trigger animations based on movement speed and direction of walker objects. E.g. if your object is not moving, it will fade in an idle animation. All of the "Ethan" space guy models in the example scenes have an MoveAnimator script attached to them.
     
  6. Ceciaman

    Ceciaman

    Joined:
    Jul 30, 2013
    Posts:
    52
    Thank's Baroni.
    Now work very well.

    I've used <splineMove> before...
    Another thing:
    How can i find Current point (in splineMove i used it, but now?)

    Ceciaman
     
  7. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    minimalMove does not have a currentPoint variable, as it does not consist of path segments specifically.
     
  8. g8minhquan

    g8minhquan

    Joined:
    Jun 18, 2014
    Posts:
    38
    Hi Baroni,
    Everything works, but the movement of the enemies are not very smooth. It feels like it's running at low frame-rate (though the actual game frame-rate is high at 60fps).
    In my game I need dozens of enemies to run at the same time, and I use splineMove mostly because I need some options in it. Do you think it could be a problem?
    I will try to send you a sample project later
     
  9. gringo2012

    gringo2012

    Joined:
    Jul 6, 2012
    Posts:
    46
    Hi. Great extension Baroni. Thanks for the continued development and updates.

    I have a few questions which probably are not that hard for you but so far I haven't found a solution.

    I am trying to have a train that pulls wagons race a curved looped line.
    The curved path is defined by me. The wagons should all start one after the other and they have varying widths.


    so let's say the locomotive is 10 meters wide, wagon 1 would start after these 10 meters. If wagon 1 is 6 meters wide, wagon 2 would start after 16 meters (width of locomotive + width of wagon 1)... and so on.

    So basically I need to add an offset to the position of each element that runs on this path.

    I know I could do something like this to set the offset for each wagon individually:
    Code (CSharp):
    1. transform.position = move.tween.GetPointOnPath(progress + progressOffset);
    but GetPointOnPath always takes a value between 0 and 1 (0=start, 1=end)

    Is there any way I can get the length of the curved path in unity units? This way I can calculate the offset based on real values.

    For example, for a curved path of 220 meters (or 220 unity units), an offset of 10 meters would equal a value of 0,045 added to GetPointOnPath.

    To cut short all of this theory my 2 questions are:
    1) Is there any way I can get the length of the curved path in unity units (callable in code. I know it is calculated in the inspector for the PathManager but it is not calculated for a curved path; it is just the sum between straight lines for each waypoint). The length should be calculated for a looped path.
    2) Is there maybe an easier way to calculate this offset required between elements sharing the same path?

    Thank you
     
  10. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hi gringo2012, thanks for chiming in!

    Both questions are more directed at the tween library HOTween, which is used in SWS and calculates curved paths internally. To be honest I don't know how HOTween's path formula calculates its splines, but I suggest that you ask this in the support thread of HOTween.
     
  11. KidSicarus

    KidSicarus

    Joined:
    Feb 3, 2014
    Posts:
    35
    Hello, Baroni.

    Any chance to get SWS.PathManager.GetPathPoints as a PlayMaker action?

    Thanks!
     
  12. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hi KidSicarus,

    do you need the array or would it be sufficient to have an action which accesses one Vector3 value at an index specified by you? I couldn't figure out how to use PlayMaker's ArrayMaker extension yet.
     
  13. Aman Iman

    Aman Iman

    Joined:
    Jul 18, 2014
    Posts:
    2
    Hello Baroni and thank you for this nice tool.
    I have one question: Is it possible to create a new path and waypoints during runtime? I think I must go deep inside the code.. but where to start?

    Best regards
    AmanIman
     
    Last edited: Jul 18, 2014
  14. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hi Amanlman,

    yes, paths are just gameobjects with multiple children as waypoints. Basically you create waypoints in the order you would like, keep them in an array and assign this array to a PathManager component (to the "waypoints" variable). It is also good practice to add the new path to the WaypointManager afterwards.
     
  15. Aman Iman

    Aman Iman

    Joined:
    Jul 18, 2014
    Posts:
    2
    Hello Baroni, many many thanks for this info... is it possible to get some example code? That would be awesome :)
     
  16. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Sure:

    Code (csharp):
    1. //create path object
    2. GameObject path = new GameObject("myPath");
    3. PathManager pathComponent = path.AddComponent<PathManager>();
    4.  
    5. //create waypoints
    6. int waypointCount = 10;
    7. Transform[] waypoints = new Transform[waypointCount];
    8. for(int i = 0; i < waypointCount; i++)
    9. {
    10.    waypoints[i] = new GameObject("Waypoint" + i).transform;
    11.    waypoints[i].parent = path.transform;
    12. }
    13.  
    14. //reposition waypoints
    15. waypoints[0].position = new Vector3(0, 10, 0);
    16. waypoints[1].position = new Vector3(0, 10, 5);
    17. ...
    18.  
    19. //assign waypoints to path component and WaypointManager
    20. pathComponent.waypoints = waypoints;
    21. WaypointManager.AddPath(path);
    You can then assign the new path to a movement component and start movement, as usual.
     
  17. KidSicarus

    KidSicarus

    Joined:
    Feb 3, 2014
    Posts:
    35
    Is there an easy way to align a long path to an uneven terrain?

    Thanks.
     
  18. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Not really, no. You could try the "Place to Ground" button on the PathManager, but this will only reposition waypoints on top of the terrain, it won't insert new waypoints to smooth things out. Tweens are not meant to be used on terrains as they will never follow them exactly - I recommend using navMove, if feasible.
     
  19. KidSicarus

    KidSicarus

    Joined:
    Feb 3, 2014
    Posts:
    35
    Thanks, Baroni.
     
  20. justkedin

    justkedin

    Joined:
    Sep 19, 2013
    Posts:
    9
    Hi again lol
    In my application, the user can plot waypoints during runtime to create a path for their object. Is there a way to see the line of the path while plotting these waypoints -- the same way as when we use the Waypoint Manager to create a path and we see the yellow line. Thank you!! :)
     
  21. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Is there a simple way to draw WayPoints using straight lines?

    My characters only move on either the X or Y axis only, at a time. So if they are moving on the X access, the Y should be locked when I create the next waypoint.

    Similar to how holding SHIFT in MS PAINT causes the line tool to become totally straight on the X or Y axis.

    It pains me to think I have to type in adjustments in the Inspector for every path I create.
     
  22. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    @justkedin
    In the editor, path lines are being drawn using Unity Gizmos and thus not visible at runtime. However the sample scenes demonstrate a component to make them visible, named "PathRenderer". Attach this script to your PathManager along with a LineRenderer and enable the onUpdate variable in its inspector.

    @CarterG81
    I am not aware of such a functionality in Unity and SWS does not implement this either, sorry.
     
  23. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Not a big problem, I just figured out an easy way to create the waypoints then move them around on just one axis. It takes a bit more time, but only a few extra seconds per :)

    Also, I implemented a autosnap editor script for the scene editor, which resolves a ton of issues I was having :D

    I do still have a few questions though...


    1) Is there a way to shrink the Gizmo size of waypoints? My game is a pixel game with tiny 14x14 people, so the gizmo's cover a huge portion of the screen. This isn't a deal-breaker, since I can zero the alpha for the gizmos and replace them with sprite objects, but it would be nice to be able to shirnk the gizmo size of each waypoint.


    Right now I (very easily) created a straight line path as I needed, and using the move script was able to get him moving almost instantly. Great! Now to figure out how to call a few event functions, and change a few animations- and I'm set!

    This is after trying uSequencer (fail), and Animator (took 10x longer to make my cut scenes than by using this, despite how I thought the timelines in those assets would speed up workflow. How wrong I was, lol. Keyframing takes much longer. A waypoint system with gameobject is soooooooo much faster!)
     
    Last edited: Aug 1, 2014
  24. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Question 2) Is there a way to call a method using the Message Settings, with more than just one parameter?

    I was hoping to be able to call Laser(Object target, int NumAttacks);
    That way using SWS, I can both shoot the target and decide how many times they should shoot their laser guns.

    The examples and inspector only appear to allow one parameter.
     
  25. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Waypoint sizes are defined in the PathManager script at line 44 and 49, you can adjust these how you like there.

    That's not possible no, but you could use one message to only declare the int variable and another one to set the target and let it shoot. Or only specify the target with a message and set the int variable in your script's inspector, if that's feasible.

    Great to hear you are enjoying working with SWS :) If you need more help regarding waypoint messages or animations, please let me know here or visit our support forum.
     
  26. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Thank you :)

    One look at the message example scene, and I understood it. Just to clarify, if I have 2 messages, the first message (top message in inspector) will ALWAYS be called before the second message, correct? If so, I was thinking of just setting any parameters first, and then just calling the function.

    Message 1) SetLaserColor(BlueColor)
    Message 2) SetLaserTarget(EnemyObject)
    Message 3) ShootLaser().

    Something like that.

    edit: Oh yea, what you suggested is a good idea. In most cases I can simply declare the public variables in the inspector. Usually when shooting a laser, it will either be red or blue. In any scene where they change colors, I can simply call a function SetLaserColor(int).

    Thank you again!
     
  27. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    edit: I changed those two lines, but that does not get rid of that more solid yellow gizmo when selecting the Path gameobject in the Hierarchy.

    gizmo.png
     
    Last edited: Aug 1, 2014
  28. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Yes, exactly. Messages are invoked in a loop, in the order specified in the inspector.

    Argh... changing public variables via code won't change their values on existing scripts, as these values are being overwritten by the inspector anyway (which aren't visible there due to the custom editor). Should have tried that out first. Are you sure that by sphere gizmo you mean the wire sphere for waypoints, not their handles? The handles won't be visible after deseleting the path.

    Edit: If you want to change the handle too, that would be at line 337 in PathEditor.cs.
     
    CarterG81 likes this.
  29. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Thanks :)

    It was the handles that I was after. Got it!
     
  30. g8minhquan

    g8minhquan

    Joined:
    Jun 18, 2014
    Posts:
    38
    Hi Baroni, I've got this bug recently with SWS: when creating paths, there's nothing happening when pressing "P". It doesn't create any waypoint.
    The bug doesn't happen all the times, but when it does, I have to restart Unity to make it work again. Do you think of any possible reason causing this?
     
  31. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hmm that's weird. Which operating system and version of Unity are you running? Also, are you trying to place waypoints in 2D mode or 3D, and if 3D, do you always have a collider as background object?
     
  32. g8minhquan

    g8minhquan

    Joined:
    Jun 18, 2014
    Posts:
    38
    I'm using Unity 4.5.1 Free on Windows 7. I'm creating waypoints in 2D mode and SWS correctly recognizes the 2D mode.
     
  33. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    If you figure out some repro steps, or a sample project that replicates this, please let me know.
     
  34. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    I am trying to figure out how my character can arrive at a waypoint, change animation, delay, change animation again, delay again, and THEN continue onwards to the next waypoint. I'd prefer to do this with messages.

    Right now, I just have messages like this, using the SWS movement script "Spline Move":

    1) Method: Animate, Text: "S_Idle"
    2) Method: Idle, Numeric: 0.8
    3) Method: Animate, Text: "N_Idle"
    4) Method: Idle, Numeric: 0.8
    5) Method: Animate, Text: "S_Idle"


    However, my Idle function does nothing currently because I don't know what method to use to pause the SWS messages. I'd prefer to do this in SWS's Spline Move and my script, not by changing my animation clips.

    Code (csharp):
    1.  
    2.   //Don't Move or Change Animation
    3.    void Idle(float time)
    4.    {
    5.  
    6.    }
    7.  
     
  35. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Message invocation in SWS can't be paused, but if your animation/idle/animation behavior is following a recurring pattern you could either write a single method that handles all of it or write a hacky add & execution method (something like that, pseude code and not tested):

    Code (csharp):
    1. public class MessageData
    2. {
    3.    public string methodName;
    4.    public string methodObj;
    5. }
    6.  
    7. List<MessageData> data = new List<MessageData>();
    8.  
    9. public void AddAnimation(string anim)
    10. {
    11.    MessageData d = new MessageData();
    12.    d.methodName = "Animate";
    13.    d.methodObj = anim;
    14.    data.Add(d);
    15. }
    16.  
    17. public void AddIdle(string time)
    18. {
    19.    MessageData d = new MessageData();
    20.    d.methodName = "Idle";
    21.    d.methodObj = time;
    22.    data.Add(d);
    23. }
    24.  
    25. public IEnumerator Execute()
    26. {
    27.    for(int i = 0; i < data.Count; i++)
    28.    {
    29.       yield return StartCoroutine(data[i].methodName, data[i].methodObj);
    30.    }
    31.  
    32.    data.Clear();
    33. }
    34.  
    35. IEnumerator Idle(string time)
    36. {
    37.    yield return new WaitForSeconds(float.Parse(time));
    38. }
    39.  
    40. IEnumerator Animate(string clip)
    41. {
    42.    ...
    43. }
    1) Method: AddAnimation, Text: "S_Idle"
    2) Method: AddIdle, Text: 0.8
    3) Method: AddAnimation, Text: "N_Idle"
    4) Method: AddIdle, Text: 0.8
    5) Method: AddAnimation, Text: "S_Idle"
    6) Method: Execute

    First you're adding methods to a list, and after all methods have been added you call Execute(). This method will loop over the list and call the assigned method. yield return StartCoroutine(...) makes sure that the current coroutine is done before the next one gets started. Hope this makes sense so far.
     
    CarterG81 likes this.
  36. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    It does, thank you very much! :)

    I will post the results if I get it working.
     
  37. CarterG81

    CarterG81

    Joined:
    Jul 25, 2013
    Posts:
    1,773
    Success! It was a bit tricky, because I discovered you have to make sure the Delay on that waypoint adds up to the total idle time. I kept having my character run off before the Coroutine was finished.

    Here is my working script:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public class CharacterActions : MonoBehaviour
    7. {
    8.    List<MessageData> data = new List<MessageData>();
    9.  
    10.    public void AddAnimation(string anim)
    11.    {
    12.      MessageData d = new MessageData();
    13.      d.methodName = "Animate";
    14.      d.methodObj = anim;
    15.      data.Add(d);
    16.    }
    17.  
    18.    public void AddIdle(string time)
    19.    {
    20.      MessageData d = new MessageData();
    21.      d.methodName = "Idle";
    22.      d.methodObj = time;
    23.      data.Add(d);
    24.    }
    25.  
    26.    public IEnumerator Execute()
    27.    {
    28.      for(int i = 0; i < data.Count; i++)
    29.      {
    30.        Debug.Log ("i = " + i);
    31.        yield return StartCoroutine(data[i].methodName, data[i].methodObj);
    32.      }
    33.  
    34.      data.Clear();
    35.    }
    36.  
    37.    IEnumerator Idle(string time)
    38.    {
    39.      Debug.Log ("Waiting for seconds: " + time);
    40.      yield return new WaitForSeconds(float.Parse(time));
    41.      Debug.Log ("Waiting done!");
    42.    }
    43.  
    44.    IEnumerator Animate(string clip)
    45.    {
    46.      Debug.Log ("Playing animation: " + clip);
    47.      Animator animator = this.GetComponent<Animator>();
    48.      animator.Play(clip);
    49.     Debug.Log ("Animation playing!");
    50.  
    51.      yield return null;
    52.    }
    53.  
    54.  
    55. }
    56.  
    57.  
    58. public class MessageData
    59. {
    60.    public string methodName;
    61.    public string methodObj;
    62.  
    63. }
    64.  
    65.  
    Steps to do this correctly:

    STEP 1 ) Add the messages.

    Example,
    1) Method: AddAnimation, Text: S_Idle
    2) Method: AddIdle, Text: 0.8
    3) Method: AddAnimation, Text: N_Idle
    4) Method: AddIdle, Text: 1.2
    5) Method: AddAnimation, Text: S_Idle
    6) Method: AddIdle, Text: 1.0
    7) Method: Execute

    STEP 2) Add up the Idle time, (ex. 0.8 + 1.2 + 1.0) and set that as the delay for the waypoint (ex. 3). This is required for your character to idle at the waypoint while doing his animations, or else he will simply idle between animations while also moving to the next waypoint.

    STEP 3) Don't forget that anytime you change the Idle time length in the messages, you need to recalculate the sum for the DELAY!

    sumDelay.png
     
    Last edited: Aug 3, 2014
  38. zKici

    zKici

    Joined:
    Feb 12, 2014
    Posts:
    438
    This has been the most useful assets out there !

    Extremely well, sufficient and cheap wow!

    On top of that I needed another option to add random delays and was willing to pay for it, however the developer agreed that it could be a handy upgrade for the asset itself and will make it free of charger.

    Simply amazing, one of the best out there, there is no need for any complex systems when this does it all and is very flexible.

    Thank you for such a great asset !
     
  39. Andreas12345

    Andreas12345

    Joined:
    Oct 17, 2013
    Posts:
    526
    Hi,
    i have a problem with speed between waypoints.
    I use input script edited from Baroni, to work with my Software/Hardware.
    But sometimes i have a stock between waypoints, was there a solution for always the same speed between waypoints?
    Some waypoints are far from each other, some waypoints are near to each other.
    I thought there was something?
     
  40. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hi Andreas,

    version 4.x includes a new movement script for user input (see our webplayer, scene 6). Version 4 has been released many months ago and replaces some old scripts, that's why I can't remember what exactly I modified in your script, but I recommend trying out the updated version (link to announcement here).
     
  41. Andreas12345

    Andreas12345

    Joined:
    Oct 17, 2013
    Posts:
    526
    hmmm... i check this out, but have really faith to kill my project. :)

    now you remember :)
     
  42. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    This looks a lot more polished than your prototype with cubes back then, good work on that one :) Backup your project before importing our 'new' version though, some scripts aren't backwards compatible.

    Out of office note: we're not available until August 18, support inquiries will be answered shortly afterwards.
     
    Last edited: Aug 8, 2014
  43. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,548
    I noticed, you support mecanim in v4, but the locomotion does not. You are still moving it by tween. Is it a technical limitation or am I missing something?
     
  44. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    What do you mean by locomotion? Tweens deliver input for Mecanim, which then transitions between different animation states based on speed and direction. The underlying movement scripts are still tweens.

    Out of office note: we're not available until August 18, replies will take a little bit longer.
     
  45. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,548
    Locomotion means the animation moves the character forward instead of code. It avoids foot skating. Since I see you are able to support mecanim, it should be able to support locomotion quite easily
     
  46. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    HOTween drives characters along their path, there's no option to reverse this behavior. If you would like to let animations control the speed and direction (locomotion) of characters, it doesn't make much sense to use tweens. Basically it's one or the other, but animation and object acceleration/speed can be fine tuned to make foot sliding less visible.

    Out of office note: we're not available until August 18, replies will take a little bit longer.
     
  47. FlarePoint

    FlarePoint

    Joined:
    Jun 18, 2014
    Posts:
    6
    Hello, i'm having trouble with something. Whenever I move in front of one of my walkers in game, it seems to rubber band back a few meters and then continue its path, I have removed the colliders off it and it still seems to do it, this issue sort of breaks my game in a way, and i'm wondering if there is a fix or if i'm doing something wrong.

    Thanks.
     
  48. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,548
    Some movements like slow walking zombie needs locomotion to avoid foot skate. So you are saying, if I remove the tween, then it will work?
     
  49. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hi FlarePoint,
    do you mean that you are trying to move to walkers or their path at runtime? If so, you should check out the 'local' sample in example scene 4. There's a checkbox named local on the movement script that allows you to do this. If this is not what you want, could you send me a repro project or some repro steps so I can investigate it further once I'm back in the office?

    Locomotion / root motion can't be used with a tweening engine, you will have to write your own movement script for that, yes.
     
  50. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,548
    That's what I mean. The locomotion already moves the character in the animation , so SWS should to support it , if it just doesn't need to tween.