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,261
    Hi @Kruko, "moveToPath" creates a tween with the same base settings defined on your movement script in the inspector, it's actually the exact same method being called as for the "regular" tween. Could you describe steps for me to reproduce this is one of the example scenes?
     
  2. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    Hope you don't mind if i do it like this

    Here's the ship using SWS (blue square for position) and waypoint 0 is the lower purple square. Path is Bezier, i'm using Playmaker to set path.



    Here's the spline move script setting



    Path setting



    All the waypoint transforms are also on Z:1



    Also, if it's worth knowing, i haven't updated to latest version.

    I'm unable to provide the gif at the moment, but it takes 4,1 seconds to reach waypoint 0, and about two seconds from waypoint 0 to waypoint 1.
     
  3. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    I can only take a guess here, since that's not what I'm seeing in the example scenes (and also not in any previous version of SWS). Could you switch the "Time Value" dropdown from 'Speed' to 'Time', and have a look at the "Ease Type" dropdown that shows up, verifying that its value is set to 'Linear'? - This has changed in a later version, where the ease type dropdown is always visible, since it affects both speed and time tweens.
     
  4. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    Oh i played around with it, some ease was probably set, left that way and returned to linear. I'll check it out and let you know!
     
  5. jingray

    jingray

    Joined:
    Feb 6, 2015
    Posts:
    53

    How to fix spike ?! Thanks
     
  6. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    This looks like a method from DOTween. Are you calling something specific in SWS at that point?
     
  7. jingray

    jingray

    Joined:
    Feb 6, 2015
    Posts:
    53
    I use pooling. While game object active a random position on screen, I called again CalcalatePath() function for BezierPathManager. The last, I called SetPath() function.
     
  8. jingray

    jingray

    Joined:
    Feb 6, 2015
    Posts:
    53
    If Path long, CatmullRomDecoder.SetTimeToLenghtTables(), CatmullRomDecoder.SetWaypointsLenghts() create more GC Alloc and Time ms high (>16 ms).
     
  9. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    @vudong CatmullRomDecoder is a class from DOTween as well. If this is troubling to you, I would suggest posting this in the official DOTween thread instead, or contacting its developer directly.

    Both CalculatePath() and SetPath() methods in SWS do calculations which are used for initialization and therefore need more resources once in the beginning, but nearly zero afterwards. CalculatePath is a performance heavy operation (this is stated in the scripting reference already) because it allows for recalculating and updating the whole path at runtime. SetPath on the other hand is responsible for initializing the tween you are using for movement on the path, which needs some CPU time for that too.
     
  10. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    SplineMove could really use first point and last point reached UnityEvents that are always available, even if a path hasn't been assigned. Currently, I have to redo events if the assigned path or points change. And, I can't assign a finished event in-editor when the path is set procedurally. Always visible first and last point events would solve both of those problems.
     
    Last edited: Oct 31, 2017
  11. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Thanks, it's on my to do list. Not sure about whether it's going to be a delegate or UnityEvent yet.
     
  12. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    Not much reason to avoid UnityEvents for it. They significantly improve usability and can be accessed through code just as easily.
     
  13. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    Instead of setting the SplineMove's moveToPath boolean to false on waypoint reached, a private bool should be used to temporary store the value on StartMove, with the temporary variable being the one to be set to false OnWaypointReached.

    What you're doing right now is treating a config variable like a state variable. Here's an example to illustrate why that's a problem:

    I'm using SWS to make a bat fly around in a looped path while disturbed. After the final waypoint, if the player hasn't been seen for a while, I use its UnityEvent to call the SplineMove's stop and then use another script to make the bat fly back to where it was originally perched. Up to that point, everything's fine. But, when I call the SplineMove's StartMove again (when the bat is disturbed again), it immediately snaps to the first waypoint instead of smoothly moving to it, because moveToPath (what should be a config variable) is being set on waypoint reached as if it were a state variable.

    Also, because there isn't a function or property to set moveToPath, it's impossible to reset this from a UnityEvent. For future reference, all public variables should instead be serialized private variables with a public property. This makes them accessible from UnityEvents, among other benefits. Example:
    Code (CSharp):
    1. // Config field, accessible from UnityEvents
    2. [SerializeField]
    3. [UnityEngine.Serialization.FormerlySerializedAs("moveToPath")]
    4. private bool _moveToPathOnStart;
    5. public bool MoveToPathOnStart {
    6.     get { return _moveToPathOnStart; }
    7.     set { _moveToPathOnStart = value; }
    8. }
    9.  
    10. // State field
    11. private bool _movingToPath;
     
  14. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    @Baroni

    Hello, i was updating Unity to 2017 so i didn't find time to check upon the problem i was having, but i do have another question. Can i use a json file to apply transform of waypoints and bezier handles to the waypoint objects?
     
  15. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    It's really just necessary to set moveToPath to true via code before calling StartMove in your script - not everything can be handled with UnityEvents (and SWS is not going that route).

    If you mean a json formatted list of three dimensional points to be applied on path waypoints, like a "Simple Waypoint System JSON importer", then no, you would need to write an editor script that does this and converts your data. Let me know if you need any help, I wrote some JSON converters in other areas before. You could also send me your json file via email, for example.
     
  16. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    That's just poor, lazy systems design. I added a single line function to set the value, and it works fine from Unity Events.
     
  17. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    @OhiraKyou moveToPath is not meant to be set via UnityEvents. It is a config variable to be set at the point you are calling StartMove. I could add a parameter to the StartMove method though, so you can call that via a UnityEvent and pass it in directly.
     
  18. OhiraKyou

    OhiraKyou

    Joined:
    Mar 27, 2012
    Posts:
    259
    If it were a config variable, it wouldn't need to be set every time you start moving. You really should be using a separate bool for current state that copies the config bool's value on move start.
     
  19. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362

    No, i had something else in mind, i'll send you an e-mail.
     
  20. giraffe1

    giraffe1

    Joined:
    Nov 1, 2014
    Posts:
    302
    I want my npc's to each have there own patrol paths.

    I use a spawner to spawn npc's.

    What is the best way to assign different NPC's different paths? Is there any built-in methods or can you recommend an elegant way to do this?

    Thanks.
     
  21. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    SetPath (PathManager). The Runtime example scene has a sample for this.
     
  22. Little_Master

    Little_Master

    Joined:
    Sep 14, 2017
    Posts:
    3
    hello i am using sws version 5.1.1 . my game object is moving using spline move adn loop type is loop but when my gameobject near to at end point it slow down . i want constant speed . Any Solution .
     
  23. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hello @Little_Master, check that your Time Value is set to "Speed" in the inspector. Also consider updating, your version is very old.
     
  24. applicattura

    applicattura

    Joined:
    Mar 28, 2017
    Posts:
    16
    I have just tested the asset and would like to ask about easing functions in the Example10. When I change from linear to any of the ease functions the objects behave badly, sudden position/rotation changes. Is it a problem with the asset or I made something wrong?
     
  25. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    @applicattura You didn't do anything wrong - the Waypoint Rotation feature is still experimental (as indicated) while gathering more feedback and actual use cases. As such, it doesn't support ease types other than linear yet since that interferes with the current rotation calculation code.
     
  26. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    Hello @Baroni

    i've yet to do that JSON example for waypoints to send to you, but i've got some more basic things setting up now.

    I have all my sprites that use paths in the game facing left, so when i move the objects by splinemove, they are facing the opposite way. Any elegant way of solving this since i am using the same prefabs for movement that doesn't involve using paths and it's quite unconvenient for me to change all the sprites now or flip the scale or sprite for the reasons of using some more movement methods then just tweening.

    They should basically move like in your example



    I'm also having a problem with children (enemy ship jets), they don't seem to inherit the rotation of the parent. I'm using catmull rom sidescroller 2d mode. I can solve this by getting the parent rotation and setting it to child every frame, but i'm looking for something less expensive.
     
  27. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    I may have an idea, since the stuff that's on a waypoint has a different parent than the rest, i may try changing the x scale to -1 if the parent is different, i'll see if it works.
     
    Last edited: Nov 21, 2017
  28. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hey @Kruko,

    Since SWS expects the sprite direction to face right = forward, the only way would be to flip the sprite graphic in your graphic application, or make the sprite a child of an empty parent game object (with the movement script attached on the parent) and rotate the child/sprite 180 degrees - or scale it to -1.

    Not sure about your exact setup on this - movement scripts overwrite the position and rotation of parent objects. Could you elaborate?
     
  29. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    I've set the scale of parent when it spawnes parented to waypoint enemies spawner to -1 and it works fine. As for the child/parent question, here's an image:



    Now, i figured out the problem is the jet is spawned before activating the splinemove component so it doesn't inherit the rotation and scale of the ship. But, when it activate it with splinemove active, i get this



    Scale is inherited, so that's ok, it is flipped the right way, but the Z rotation is not good. It is also inherited, only when i set it to 0 it is ok, BUT, only when they're moving from right to left, when they're moving from left to right, the scale is inherited, and i set the rotation to 0, but then i get the jet reversed.



    Any advice on how to construct it properly, i want to kick myself in the head right now. I now it's probably beyond the scope of sws, but i just need this with the child following the scale and rotation.

     
    Last edited: Nov 22, 2017
  30. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    As I wrote above, it's usually done the other way around:

    Parent (movement script, scale/rotation 0,0,0)
    -- Child (ship sprite, scale/rotation -1)

    This way you can modify the local child (ship) scale or rotation as you wish, without it being affected by the movement script. If you can't get it working properly, could you send me a minimal sample or your sprite via email, so I can play around with it?
     
  31. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    @Baroni

    I'm a bit confused about the order here, is it:

    spawn parent (ship), activate movement script, spawn child (jet), set child scale/rotation

    or

    spawn parent (ship), spawn child (jet), activate movement script, set child scale/rotation?

    Putting a ship into another empty object is a bit complicated since i use parent name for some other stuff, ship is usually parented under a spawner which defines behavior and other stuff.
     
    Last edited: Nov 22, 2017
  32. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    This one, although I don't know your exact setup here.
     
  33. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    I have to check it out, my timing with activation of the movement script is probably bad.
     
  34. JDrem1

    JDrem1

    Joined:
    Jun 24, 2017
    Posts:
    199
    Hi.
    This may be absurdly obvious.
    Please forgive if it is.

    I have no problem, getting the pathing working. Brilliant plug-in, absolutely awesome.

    But I cannot find where I access loop, and ping pong.
    I have a couple of sailing ships... well "sailing" :D around an island. But I cant seem to see where at the end of the path, I assign them to either turn round and go the other way, and keep doing that.

    Or just continue around and around.

    Any help really appreciated. :)
     
  35. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hi @Dayn1, please have a look at the "Loop Type" variable. If you don't find something you're looking for, you can always search on our scripting documentation.
     
  36. JDrem1

    JDrem1

    Joined:
    Jun 24, 2017
    Posts:
    199
    Hi and thank you for the reply.

    Where is the "loop type variable" please. That is what I was looking for. I have looked in the manager, and the Unity "windows tab entry." and in the project tab.
    I cant see any reference to "loop" or "ping-pong." I searched online, and watched what videos I could fine, and also looked on your home page.

    The only place I can find it is a quick reference to it on the official page (quote.)
    "MOVEMENT
    At game start or through code
    Based on speed or time
    Looptypes (loop, pingpong, random)"

    But with no further explanation as to how it works.

    I appreciate any help with this.

    Thank you.
    Andy. :)
     
  37. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    @Dayn1 It is a setting on the movement script. The link I posted to our scripting reference shows the splineMove component, if you scroll to the top. You can set the loop type separately for each movement script, so a global setting on the WaypointManager or any project settings would not make much sense.

    splineMove.png
     
  38. JDrem1

    JDrem1

    Joined:
    Jun 24, 2017
    Posts:
    199
    Hello Baroni.

    Huge help.
    Really appreciate it. :D

    Best Regards.

    Andy.
     
    Last edited: Nov 30, 2017
  39. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    @Baroni

    Appropriate spawning sequence and script activation sorted things out (along with scale and rotation adjustments depending on location and some other settings). It was kinda tough because i'm making a universal system for objects using their own translate movement, parents translate movement when in a squadron or sws, but in the end i nailed it with your help. I can't imagine what hell would it be in 3D.

    Thanks for the help once again, i will e-mail you for assistance with json when the time comes, cheers.
     
    Baroni likes this.
  40. JDrem1

    JDrem1

    Joined:
    Jun 24, 2017
    Posts:
    199
    Hi Baroni.

    Loving this amazing plug-in.

    But I have come across (I am sure what is a basic lack of knowledge on my part.)
    I'm trying to set up some bunny's running around on a hilly type environment, and down onto a flatter area. I have gone through the waypoints making sure they are on the ground.
    (I know it has snap to surface) but some were floating, and some sunken, its quite a undulating terrain.

    I have then experimented with Navemesh agent, and navmesh move script settings, in align with and without Spline move.
    I have added rigid bodies, and colliders, but no matter what I do, the little bouncy tykes keep either running through mid air, in parts of the random loop setup. Or else underground.
    Even though the waypoints are as near as darn-it on the floor.

    I realise Its most probably me doing something wrong. But any help, or info in the right direction will be greatly appreciated.

    Thanks. :)
     
    Last edited: Nov 30, 2017
  41. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hi @Dayn1, the splineMove component is obviously not an ideal movement type on terrain, since you would need a lot of waypoints to model the terrain shape, or else your object would float above the terrain when moving from waypoint to waypoint.

    navMove with Unity's navigation system is better, as it allows you to bake the navigation shape closely to the terrain. Rigidbodies could interfere with the NavMeshAgent component, so I would recommend turning that off (at least the gravity on it). If your object still moves through air or underground, please check the navigation settings when baking the NavMesh - SWS has no control over that, and basically just tells the NavMeshAgent to move from position to position on it.
     
    JDrem1 likes this.
  42. JDrem1

    JDrem1

    Joined:
    Jun 24, 2017
    Posts:
    199
    Thanks Baroni.

    I will get started on giving this a go.

    I really appreciate your help, and feedback.

    Andy. :)
     
    Baroni likes this.
  43. JDrem1

    JDrem1

    Joined:
    Jun 24, 2017
    Posts:
    199
    Hi Baroni.

    This is such a brilliant plug-in. But I cannot find any instructions on the individual actions.
    Anyway sorry for the questions. I always do searches before asking.

    I now have two seemingly easy to do/fix issues. I cannot find how to do them.
    I have tried all the logical steps I could think of. But I know I'm missing something in my "doings" :confused:

    First.
    I am trying to have a creature fly through the air.(no problem) But then do different animations on waypoints, glide, land etc.
    - I have tried attaching the mecanim animations to the creature, on the events tabs.
    - And I have tried attaching both the animations directly. And creating an empty object, and then child the anims to the game object, and then pop that on the individual, specified waypoints, where I want the animation to happen.

    None of it works. Can you point me in the right direction please. :)

    Second.

    When the creature moving along the path, the waypoint has set him on an angle so his legs aren't flat facing the ground.
    To change his angle I have tried rotating both the waypoint, and the creature. But nothing seems to change his angle in flight.
    Again any help really appreciated.

    Oh and is there a manual, explaining the steps to achieve the various settings / options / and abilities of Simple Waypoint please.

    Id much rather read, than keep bothering you.
    Thank you for a brilliant plug-in. and any help. :D
     
    Last edited: Dec 4, 2017
  44. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    @Dayn1 Hey Andy,

    Actions? Do you mean waypoint events, or movement settings in the inspector?

    Which method did you use when attaching animations in the events tab? You can't just assign them or the animator there, you have to write a public method, with one string parameter, that calls Animator.Play on your object's Animator component. If you then drag this method into an event, you can enter the name of the animation to play. Also check that you don't have the MoveAnimator component on your object as that could overwrite your manual animation calls.

    The rotation of the waypoint is applied on the object if you are using the waypoint rotation feature (see the example scene for that). Otherwise, you can try locking the rotation - by setting "Lock Rotation" to "X". Your object will then not be affected by rotation around the X axis.

    Did you see the documentation pdf included in the package? It should explain the basics very well. If you would like to read more details about the various variables on all scripts, I've added comments to all public variables and methods so you can look the up in our scripting reference (e.g. for splineMove). Also, nearly every line in the demo scripts of the example scenes are documented, if you would like to look through them.
     
  45. JDrem1

    JDrem1

    Joined:
    Jun 24, 2017
    Posts:
    199
    Hi Baroni.

    I will go through all you have said, and answer by pm rather than tying up the thread any-more.
    Thank you for another brilliant detailed answer. :)
     
    Last edited: Dec 6, 2017
  46. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    Hi @Baroni,

    another day, another question! I'm regularly checking enemy ships if they're in the camera frustum, when they're not - they get despawned. However, i noticed a strange behaviour when they move along the path. They don't react to leaving the frustum. Any ideas?

     
  47. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Impossible for me to know @Kruko, since I don't know how you are checking or despawning them or what they should "react" to?
     
    Oshigawa likes this.
  48. Oshigawa

    Oshigawa

    Joined:
    Jan 26, 2016
    Posts:
    362
    Hello @Baroni,

    simple isvisible check with camera frustum planes taken into account.

    Code (csharp):
    1. Plane[] planes = GeometryUtility.CalculateFrustumPlanes (camera);
    2. return GeometryUtility.TestPlanesAABB (planes, renderer.bounds);
    I just tried it out, end waypoints needed to be a bit further out of the frustum, everything's fine, cheers.
     
    Baroni likes this.
  49. robdeja

    robdeja

    Joined:
    Mar 18, 2016
    Posts:
    7
    Hello @Baroni,

    I'm running Unity 2017.3 with SWS 5.4.1, but I'm having a problem with GoToWaypoint (int index) - using the waypoint index number does not go to that position. I have 16 waypoints in my path but whatever number I use, it seems to go somewhere close to the start of the path, if I use high numbers (eg. 150) then I can get it to a position further along the path, but unreliably.
    I have multiple paths in my scene (the other objects with paths are loaded additively in a separate scene) - maybe the issue is here?
    In this thread somewhere I noticed that you mentioned that stopping the path and restarting it with a new start position has proven reliable, but I get the same problem with this too.

    Am I using this incorrectly, or are there any known problems with 2017.3, or is there anything else I can try?
    Code (CSharp):
    1. myObject.GetComponent<splineMove>().GoToWaypoint(8);
    Code (CSharp):
    1.  
    2. public void GoToPathPoint(int waypoint)
    3. {
    4.         myObject.GetComponent<splineMove>().Stop();
    5.         myObject.GetComponent<splineMove>().startPoint = waypoint;
    6.         myObject.GetComponent<splineMove>().StartMove();
    7. {
    8.  
    Cheers,
    Rob

    Edit: I just debugged the length of the waypoint array (myObject.GetComponent<splineMove>().waypoints.Length) and it returned 183 - I'm guessing that it's collecting all waypoints from every path in my scene (including the scene loaded additively), not just on the path my object is attached to (I have many objects each travelling their own paths). Am I meant to specify the path somewhere in code before calling GoToWaypoint() (other than it already being specified in the Path Container of the splineMove component)?
     
    Last edited: Jan 9, 2018
  50. Baroni

    Baroni

    Joined:
    Aug 20, 2010
    Posts:
    3,261
    Hi @robdeja,

    I guess you are using a bezier path? Bezier paths count all points on the path (yellow dots), not just waypoints. So if you call GoToWaypoint() on the movement script (in which case you don't need your own code to stop and set the startPoint for this manually if the tween is running already), then you have to pass in the point number - not waypoint number - your object should go to. If your bezier path has 183 waypoints, that would actually be 1830 bezier points with a default segment detail of 10.