So i have been learning godot and now i want to implement random spawn locations in the game, right now i can only spawn on one side and i want 4 at least.
extends Path3D
var timer = 0
var spawntime = 2
var enemy = preload("res://whitecube.tscn")
func _process(delta):
timer += delta
if (timer > spawntime)
var newenemy = enemy.instantiate()
add_child(newenemy)
timer = 0
this is the code i have in my path3D to spawn them in each 2 seconds extends PathFollow3D
@export var movespeed = 6
func _process(delta):
set_progress(get_progress() + movespeed * delta)
and this is the path they folow and speed
i tried to create 1 markers3d and drag the path/pathfollow3d scene inside,then copy and paste it 4 times but the paths are all connected so if i move the path1, the path 2 moves too and i dont know why.Anyways After creating that i thought about creating a node3d which would be used as a spawn location and a random number generator from 1 to 4, inside the "if (timer > spawntime)" i would do one if for each location and set the spawnlocation = marker1 ,2 ,3 or 4 depending on the random number.
i have been learning this language for about 2 months only. So if what i am saying is stupid i deeply apologize and ask you for your help. Thank you.
In the following code
pathis a reference to thePath3D. Since you are writing in an script attached to thePath3D, you do not needpath. So instead of - for example -path.curve.get_baked_length()you can writeself.curve.get_baked_length()or simplycurve.get_baked_length(). However I'll keep writingpathfor generality.Furthermore, if you need to pick between multiple
Path3Dyou could have references to them in anArray, pick one at random from the array (for example withpick_random), and that will be yourpath.Picking a position at random on the
Path3DNow, the task is getting a position at random from a
Path3D, correct?I'll start by getting the length of the
Path3D:Now we can pick a distance along the
Path3Dlike this:Then we sample the
Path3Don that distance:Assuming we are going to add a new instance as child of a different node, let us convert that to global coordinates:
In the following code
node_parentis the reference to theNode3Dunder which you will add the new instance as child. Again, if you are writing the code on an script attached to thatNode3Dyou do not need to writenode_parent.The next task is to instantiate a new child at that position, right?
So let us go from global coordinates to local coordinates of the
node_parent:Note: If
node_parentandpathare the same node, you don't need these global an local conversions at all. You can work with theresult_path_positionwe had above.New let us instantiate, set position, and add the instance as child:
Following a
Path3DIf you want to do this with
PathFollow3Dthen each instance needs to be a child of a differentPathFollow3D. ThePathFollow3Dmust be added as children of thePath3D. And you can control the position along the path with eitherprogressorprogress_ratio.For example, if you want the instances to advance along the path at a given speed, you would - of course - start by setting the
progressto0.0, and then each frame you increaseprogressbyspeed * delta.Of course, you don't need
PathFollow3D. You could have a reference to thePath3DYou also need the speed you want to advance at, and keep track of your position on the track:
And advance yourself:
You could, instead of keeping track of progress, find the closest position to the path:
Here I'm placing the instance at the start of the path in
_ready(). It is also an example of handling an emptyPath3D(if thePath3Dhas no points, I place the instance at the position of thePath3Ditself).You can also imagine that you could find out where is the closest offset, and compare it with the current position, so we can write code to return to the path (for example if something can push the instance off track):
This would not have been possible with
PathFollow3D.Handling if the instance reached the end of the
Path3Dis possible by taking the length of thePath3D(as shown in the case of picking a position at random) and comparing the offset with that. I'll leave that to you.It is also possible to use
sample_baked_with_rotationwhich gives you aTransform3D, so the instance can follow the rotation of thePath3D, the code would need to be adjusted to work withTransform3Dinstead of justVector3. For that you will need to get the position of theTransform3Dby reading itsoriginproperty. And, of course, you would setgloba_transforminstead ofglobal_position.However, I would suggest to rotate according to the direction the instance is moving (i.e. the direction between
global_positionanddest) which would also work when the instance is returning to the path.If you don't need to interpolate the rotation, using
look_atto look atdestwould suffice, which reminds me, you can query the up vector from the path withsample_baked_up_vector.Note that in these codes I'm writing
global_position. If you are moving aCharacterBody3Dyou might want to usemove_and_slideinstead...Again, I hope you can adapt this code to your needs.