Feature Request: Spawn Multiple Instances along Path



  • Hello,

    This is a Feature Request.

    I don't believe there is the ability to spawn multiple prefabs along a path. Would this be a difficult feature to add?

    I believe it would be a useful feature for your product.

    Here is my scenario:

    (Imagine a marching line of ants along a path)

    I have a spline path that has multiple 90 degree turns. Each Waypoint is position in exact units.(No Float Positions)
    I would like to instantiate multiple objects along the path(Even between Waypoints) both at exact distances from each other and random distances from each other.

    For objects between Waypoints it would be nice to have a bool such as "Move to NEXT Waypoint" similar to  Move To Path but with the ability to figure out the Next Waypoint to move towards on its own.

    I would also be a nice feature to spawn randomly from a set of instances. This would allow different instances along the path and not just the same one repeated.

    There is an asset called "Road Crossing Game Template" by Puppeteer that can almost do the above features but only on a straight path between two Waypoints. It does not have the capability of changing directions or having more than two Waypoints.

    I have created the above scenario using SWS by manually placing objects along a spline path and using SplineMove.cs "Move To Path" and assigning them a "Start Point" but it is tedious work because I am using this Idea throughout my game.

    Great Asset regardless of my request.

    Thanks,
    r_chevallier



  • Hi and thanks for sharing your ideas. In reply to them one by one:

    I don't believe there is the ability to spawn multiple prefabs along a path. Would this be a difficult feature to add?

    Instantiating prefabs on a path in the editor (not at runtime) is a difficult feature indeed. That's because the path does not actually exist in the editor - at editor time, it is calculated only for drawing the path line gizmos. Then at runtime, DOTween does the actual path calculations. So while it would be possible to instantiate your game objects at runtime, after the path is created by DOTween, this would add a slight delay to your game which you would probably want to avoid.

    *For objects between Waypoints it would be nice to have a bool such as "Move to NEXT Waypoint" similar to  Move To Path but with the ability to figure out the Next Waypoint to move towards on its own.

    [...]

    I have created the above scenario using SWS by manually placing objects along a spline path and using SplineMove.cs "Move To Path" and assigning them a "Start Point" but it is tedious work because I am using this Idea throughout my game.*

    Before calling StartMove() on the movement script, you could loop over the path's waypoints and do a Vector3.Distance check to find the closest one, then assign the "Start Point" accordingly - that would automate the need for assigning the startPoint variable manually.

    I would also be a nice feature to spawn randomly from a set of instances. This would allow different instances along the path and not just the same one repeated.

    Could you please elaborate: what do you mean by "spawn randomly from a set of instances"? Do you mean objects moving on the path, so that objects chosing their path randomly at start? If that's the case, then you can already do that - just instantiate your objects and call SetPath() on them with the path of your choice, selected by your script randomly (e.g. of an array of available PathManager components).



  • Thanks for the reply.

    I realize this is probably a tall order but I personally think it would add a lot of value to your already solid product.

    In reply to your responses:
    Instantiating prefabs on a path in the editor (not at runtime) is a difficult feature indeed. That's because the path does not actually exist in the editor - at editor time, it is calculated only for drawing the path line gizmos. Then at runtime, DOTween does the actual path calculations. So while it would be possible to instantiate your game objects at runtime, after the path is created by DOTween, this would add a slight delay to your game which you would probably want to avoid.

    Instantiating multiple prefabs along a path at RUNTIME was the idea I had in mind(Not in the Editor). For me personally, I would not be spawning more than a max of probably 10 to 15 Instances at a time per path. In addition to this It would be great to set the spacing of the spawned objects at either exact intervals or within a random range along the path. I suppose it would be a good to also have the option of spawning on Waypoints only along the path as well.

    Could you please elaborate: what do you mean by "spawn randomly from a set of instances"? Do you mean objects moving on the path, so that objects chosing their path randomly at start? If that's the case, then you can already do that - just instantiate your objects and call SetPath() on them with the path of your choice, selected by your script randomly (e.g. of an array of available PathManager components).

    By "spawn randomly from a set of instances" , it would be the same idea as spawning from a prefab pool. You would assign a specific prefab pool such as "Enemies" and withing that prefab pool you would have a list of different Enemy Prefabs that would spawn randomly along a specific path(not a random path).

    Thanks,
    r_chevallier



  • To be honest, I got a similar "spawner" request only once before, long time ago. Actually, currently I would like to further reduce the complexity of the examples in Simple Waypoint System, and focus more on its extensibility. This also means, in this case, not adding more variables or options to the movement scripts or paths, but adding public methods so you (and everyone else) is able to write something like this on your own. The "spawner" functionality (at runtime) you are describing is already possible without any additional methods though, which is why I just wrote it and would like to share it here, rather than shipping it with the product itself.

    Instructions:

    • create empty game object with a movement script and "PathSpawner" script (source code below)
    • assign the path you would like objects to spawn on to the movement script
    • assign prefabs to the "Objects" array on the PathSpawner script
    • if you would like to spawn objects on waypoints only, check "On Waypoints Only"
    • if you would like to spawn objects in a (random) distance, adjust the "Distance Min" & "Distance Max" ranges

    http://fs1.directupload.net/images/171217/3b4hpa53.png

    using UnityEngine;
    using SWS;
    
    using DG.Tweening;
    using DG.Tweening.Core;
    using DG.Tweening.Plugins.Core.PathCore;
    using DG.Tweening.Plugins.Options;
    
    public class PathSpawner : MonoBehaviour
    {
    	public bool onWaypointsOnly;
    	public GameObject[] objects;
    
    	[Range(0.1f, 100f)]
    	public float distanceMin = 1;
    	[Range(0.1f, 100f)]
    	public float distanceMax = 100;
    	public int maxSpawnCount = 0;
    
    	private splineMove move;
    
    
    	void Start()
    	{
    		distanceMin = Mathf.Clamp(distanceMin, distanceMin, distanceMax);
    
    		move = GetComponent<splineMove>();
    		move.StartMove();
    		move.tween.ForceInit();
    		move.Pause();
    
    		Spawn();
    
    		move.Stop();
    	}
    
    
    	void Spawn()
    	{
            int spawnCount = 0;
    
            if (onWaypointsOnly)
    		{
    			for(int i = 0; i < move.pathContainer.waypoints.Length; i++)
    			{
                    if (spawnCount == maxSpawnCount)
                        break;
    
                    GameObject obj = SpawnAtPos(move.pathContainer.waypoints[i].position);
                    splineMove objMove = obj.GetComponent<splineMove>();
                    if (objMove != null)
                    {
                        objMove.pathContainer = move.pathContainer;
                        objMove.startPoint = i;
                        objMove.StartMove();
                    }
    
                    spawnCount++;
                }
    
    			return;
    		}
    
    		TweenerCore<Vector3, Path, PathOptions> tweenPath = move.tween as TweenerCore<Vector3, Path, PathOptions>;
    		float totalLength = tweenPath.PathLength();
    		float currentDist = 0f;
    
    		while (currentDist <= totalLength && spawnCount < maxSpawnCount)
    		{
    			currentDist += Random.Range(distanceMin, distanceMax);
    			if (currentDist > totalLength) break;
    
    			float perc = currentDist / totalLength;
    			GameObject obj = SpawnAtPos(tweenPath.PathGetPoint(perc));
    			splineMove objMove = obj.GetComponent<splineMove>();
    			if(objMove != null)
    			{
    				objMove.pathContainer = move.pathContainer;
    
    				objMove.StartMove();
    				objMove.tween.ForceInit();
    				objMove.tween.fullPosition = objMove.tween.Duration() * perc;
    			}
    
    			spawnCount++;
    		}
    	}
    
    
    	GameObject SpawnAtPos(Vector3 pos)
    	{
    		return (GameObject)Instantiate(objects[Random.Range(0, objects.Length)], pos, Quaternion.identity);
    	}
    }
    


  • Thanks for the script,

    First I want to say the way you set this up is brilliant and definitely very useful to me and I can make use of it in my game.

    Now that being said, what I had in mind was exactly what you made but with the ability of the spawned objects to MOVE ALONG THE PATH TOO. (same speed of coarse)

    I liked what you did too, so  having the spawned objects move along the path should actually be an option and not absolute.

    I looked at the spawned objects and their path container is unassigned. I suppose you would also have to use moveToPath for the objects inbetween waypoints.

    Is this something that you feel would be good addition to your asset?

    If you feel this would be a good addition I hope to see it added to this script but I also respect your time and understand if you have a different opinion.

    Never the less, thanks for the spawning script you did create.

    r_chevallier



  • I have modified the script in my previous reply to also take spawned objects with a movement script on them into account.  ;)

    If the object prefab you assign in the PathSpawner has a splineMove script attached to it, the PathSpawner will not only spawn the object but also let it move on its path, starting from the position it has spawned it at.



  • Thanks for the modification. I know others will find this useful but I am coming up with odd behaviors with this script.

    The new version of the script seems to spawn all the instances on Waypoint 0, no matter what the minimum and maximum distance is set too. They do move though.

    Even the non spawned Original game object with the Path Spawner script goes to Waypoint 0 even if it has a different start point assigned.

    If I take out the below code the objects spawn at the correct positions.(but do not move of coarse)

    			objMove.pathContainer = move.pathContainer;
    
    			objMove.StartMove();
    			objMove.tween.ForceInit();
    			objMove.tween.fullPosition = objMove.tween.Duration() * perc;
    

    Do you get these behaviors on your part? The test scene I set up is very simple.

    Also,
    When the bool "On Waypoints Only" is checked the do spawn on the waypoints but do not move.

    Sorry for the hassle.

    Raymond



  • I've tested with a default path and it works as expected there. Could it be that you are using a bezier path?

    Even the non spawned Original game object with the Path Spawner script goes to Waypoint 0 even if it has a different start point assigned.

    Not sure what you mean here - the game object with the PathSpawner script only needs a movement script for reading out the path. You should not enable "OnStart" on it, or otherwise try to start movement, or assign a startPoint to it, as it is ignored anyway. The spawned objects can have a movement script, but they should not make use of "OnStart" or "startPoint" either, because the PathSpawner places them at the correct (random) position on the path.



  • For my test scene I am using a regular path(non bezier). But I was planning on using this on both non bezier and bezier paths in my game if possible.

    In regards to the below statement:
    Even the non spawned Original game object with the Path Spawner script goes to Waypoint 0 even if it has a different start point assigned.

    I meant that even the game object that has the move script and Path Spawner script goes to Waypoint 0, even if  has a start point of  Waypoint 3 for example.

    If I Disable the Path Spawner script it goes to the correct Start Point.

    My SWS asset is updated so I not sure why my path behavior is different than yours. I am using Unity version 2017.2.1f1 Personal (The latest Version).

    I could export my scene an send it to you, but not sure what email to send it to? administrator@rebound-games.com or info@rebound-games.com

    Thanks again,
    Raymond



  • *I meant that even the game object that has the move script and Path Spawner script goes to Waypoint 0, even if  has a start point of  Waypoint 3 for example.

    If I Disable the Path Spawner script it goes to the correct Start Point.*

    This doesn't matter - as I said above, the PathSpawner script only initializes the path positions at runtime. It is not designed to go anywhere, so leave all settings on its movement script at the defaults. You should only have one PathSpawner script per path. In fact, you could even attach it to the PathManager game object.

    The objects you spawn can have a movement script, but this should be left at the defaults too (except speed, ease type or other position unrelated things).

    Both email addresses work, but info@ is the main support email.



    • updated PathSpawner script above to correctly move prefabs spawned with "On Waypoints Only" on the path too.

    Note that when spawning an object with a movement script on the last waypoint, it immediately jumps to the first waypoint (if "close loop" is disabled), so it looks like two objects are spawning at the first waypoint. You can limit this by setting the "Max Spawn Count" on the PathSpawner to the waypoint count - 1. I do not prevent this behavior, since it could be desired when using a closed loop (where the object at the last waypoint would move to the first).



  • Awesome Work. This makes my project so much more developer friendly. It has allowed me to delete several game objects in the Unity Editor because now I can just spawn them along the path.

    Thanks for the great effort.

    Raymond



    • updated so that "On Waypoints Only" takes "Max Spawn Count" into account too (removed the prior notice about it not supporting that)


  • Hello Baroni,
    is it possible to orient the instances along path?
    Thank you,

    Manuel



  • Hello Manuel,

    of course - in the script, after it says "SpawnAtPos(tweenPath.PathGetPoint(perc));", you would just get a position further along the path e.g. using tweenPath.PathGetPoint(perc + 0.01f) and orient the object to that position.


Log in to reply