Timeline not working

Hello, I have been working on making a game as part of my university course and have run into a dead end. The game is similar to the concept of whack-a-mole. The aim of the game is to collect pugs (that pop out of various locations before returning to their hiding place) by clicking on them.

What I have been able to do is create an array so the pugs are able to spawn at various target locations but when I try to make them jump up and down they just carry on going up in space!

I just cannot figure it out, I was using a timeline in order for actor to rise into the air and when the timeline finishes the actor would destroy itself. I thought that perhaps the actor was being destroyed before being able to return but that did not fix the problem. It just meant more pugs were flying up into the air forever.

Can someone please help, here is the code I have got so far.


1 Like

Hi,

I think the problem is that you start your timeline every tick. It only needs to be executed once, and it will play your animation. Now it is basically executing the first frame over and over again, so you might want to hook it up to BeginPlay or something similar.

I hope this helps you.

2 Likes

One more issue that I see is that based on your posted screenshots, the actors would never move down. What will happen once you hook it up to OnBeginPlay is that a 1 second long timeline will play, and while it is playing, you will add +20 to your actor location on the Z axis, and wouldn’t be actually doing anything with the ‘Bobbing’ value. That is the value that you animate in your timeline (you change it from 0 to 0.5 in one second), which I don’t really see the reasons for.

What I would try is go into your scene and check the World Z location of your spawning point, and the heighest point that your pugs will move to. Then in your timeline, set the ‘Length’ value to decide the length of your animation. Make two keyframes, one at the start, and one at the end of your animation, and set the ‘Value’ of them to the ‘Spawning World Z location’ of your pugs. Then make a third keyframe in the middle, and set its value to the ‘Heighest World Z location’ of your pugs. By right clicking on your third keyframe you can smooth out the curve. The last step is to get the ‘SetActorLocation’ node (instead of the ‘AddWolrdLocalOffset’) and plug ‘Update’ into it, and use the returned float value (Bobbing) as the new Z location. After the animation finished, you can destroy the pugs.

I hope this will clear it up for you.

Hey!

Kontur is right in his assumption. You basicly fire the timeline every frame. As far as I understand you, your pugs are being spawned and then destroyed again. If this is the case, just hook up your timeline play with an “Event begin” node. This will only fire once, after it was spawned. The second problem is that your AddActorWorldOffset is constantly being updated to the same exact position you specified from frame one (in your case Z = 20). To get the thing you want, I made a replica with the modifications:

To get the three green delta locations, I right clicked on the vector node and then:

You probably need to change your “Z-value” in the timeline to something higher to make the object move faster.

Hope I could be of help :).

EDIT: If you want them to retract, then you just have to change your timeline from 1 to 2 seconds and add a -0.5 value at the end:

Hi,

Based on the post, I made the assumption that OP wants the pugs to move back to their original location before destroying them and his current setup is only for troubleshooting. If this is the case, your solution works as well, actually better, but OP still has to make at least 3 keyframes on the timeline to animate the local Z offset up and down.

Thanks for the quick replies. What I did was change the length of the timeline to 0.7 seconds as I am randomly spawning in pugs in random locations at random times between 0.8-1s. At 0.35s I gave it a positive value to a desired height and at 0.7 seconds a negative value. This means that the actor rises for the first 0.35 seconds and falls for the remaining time. When the timeline completes the actor is then destroyed. So I was able to get the actor to jump up and down and I was able to prevent another actor spawning on top of another actor by using a delay in the spawn.

What I am now trying to figure out how to spawn more pugs around the map. You see if I reduce the time for a pug to be randomly spawned to say 0.2-1s then there is the chance that an actor will spawn on top of another actor. Do you know how to add a delay to my code. I am using an array of target spawn points. The code counts how many spawn points there are present and randomly picks a number between a set range. I do not know how to tell it to not choose a specific number for a set time

140fa45479c910aa468220d2a47b0f1c87ca0777.jpeg

Okay, I hope this helps, make an Editable/Exposed on spawned variable and plug your currently used target point in it when you spawn your pug. When the pug dies, make sure to remove that target point from the ‘TakenTargets’ array.

I followed your blueprints but now the pugs are not spawning at all. I am not sure why as I do not really understand your blueprints as I am still new to unreal.

Forgive me, I was a little bit tired and forgot to provide some explanations.

If your pugs not spawninig with this, could you please post a screenshot of your setup, so I can have a look?

You said that you don’t want your pugs to spawn on top of each other, so the setup above should generate a ‘FreeTargets’ array every time you spawn a pug, making sure that the pug is choosing a random location from one of the available ones.

The idea behind it is that you create 2 arrays (TargetPoint type) one called ‘FreeArrays’ and the other called ‘TakenArrays’. Every time a pug is about to spawn, you check your original target point array (the one that you made using the MakeArray node and contains all the possible spawn points) against the ‘TakenArray’ and you generate a new ‘FreeTargets’ array. You do this with the ‘ForEachLoop’, which takes an array as an input and it executes the ‘LoopBody’ for each element of the array. Here is some further info about it:https://www.youtube.com/watch?v=F-Ab8oS6YDU. What you basically do in the ‘ForEachLoop’ is that you check every element of your original array and you add the elements that are NOT contained in the ‘TakenArray’ to your ‘FreeArray’.

When the loop completed you want to get a random element of the ‘FreeTargets’ array to use it as a spawn location (the same way as you originally did) and the last step is making sure that you added this newly chosen spawn location to the ‘TakenArray’ so no pug will spawn there until another pug is occupying the location. This is why you need to remove the target point from your ‘TakenTargets’ array when a pug dies, so the location becomes free again.

The first clear array node is just clears the ‘FreeTargets’ array before the spawn, so it will generate a fresh one every time.

Here’s the screenshot.


FreeArray.pngTakenArray.png

Yea, I am not surprised, connect your Spawn Pug event to the clear array not the spawn node and it should work.

But! You also need to remove the target point from the array after the pug died otherwise the location would never free up, and you could only use it once in the whole game, which is not what you want.

Go to your Pug blueprint and create a Target Point actor (not array this time) and name it ‘OccupiedTarget’ and check the ‘Editable’ and ‘Expose on Spawn’ checkboxes. This variable will hold the occupied target of your pug, so you will know this way which target point location to free up when the pug dies. The ‘Editable’ and ‘Expose on Spawn’ checkboxes make that variable exposed, so when you spaw your pug, you will see an input option called ‘OccupiedTarget’ in the ‘SpawnActorFromClass’ node. You want to plug the array element you get from the ‘FreeTargets’ array (the same blue wire that you used for the ‘GetActorTransform’) to that input.

Only now I noticed that you created this spawner in the Level Blueprint, which is not so optimal, because communicating between class blueprints and the level blueprint is not obvious (you need to use Event Dispatchers in order to talk to the Level Blueprint from a class blueprint, which is a whole new topic), so what I would suggest you to do is grab and copy this whole ‘spawning setup’ and move it form the Level Blueprint to a blueprint class (just create a new Actor Bluerpint Class, name it spawner and place it into your level from the content browser by drag and dropping it).

To move this from the level blueprint is important because you want to tell your spawner from a class blueprint(pug) to remove a certain element from one of its arrays, so you need a reference, but it is not that simple with level blueprints. Once you moved it to a class blueprint, create another ‘Editable’/‘Exposed on Spawn’ variable on your pug blueprint named ‘SpawnerReference’ and the type is whatever name you gave to your new ActorBlueprint (so if you named it ‘PugSpawner’ you would chose a ‘PugSpawner Reference’ variable type). Make sure to plug a ‘Self’ reference of your PugSpawner in that input when you spawn your pug.

The last step, is to go to your Pug blueprint again, and create a function called ‘KillPug’. You want to call this function when the movement timeline finishes (so not the Destroy Actor). In this function you need to grab your ‘PugSpawner’ reference variable from the left tab (the one that you exposed and filled up with the PugSpawner reference) and you want to ‘get’ it. Grab a wire from it and start to type in ‘TakenTargets’ and you should see an option to choose ‘Get TakenTargets’ (you might need to switch off context sensitivity). Now grab your ‘OccupiedTarget’ reference, ‘get’ it and remove that element from the ‘TakenTargets’ using the ‘Remove’ node. After this, you can call ‘DestroyActor’ and now the space should be free again fo other pugs to spawn.

I hope it helps, if you still struggle I will try and illustrate it with a few screenshots.

Okay a minor issue you might encounter is that in a class blueprint you can’t get a reference to your target points the way you did in the level blueprint. So delete those 6 references and the make array node and use this setup instead at the beginning:

What the ‘GetAllActorsOfClass’ node does is that it collects all instances of a selected class in the level and shoves them into an array, so you want to select TargetPoints.

The attatchement isn’t working

Let me try this one.

Alright I have made the adjustments for spawn pug. However you’re previous comments I managed to do few things however got stuck with linking up Occupied Targets with the array and creating the funtion KillPug.
I’ll link with the screenshots showing what I have done so far:


You are really close, you only have to give ‘OccupiedTarget’ a single target point reference (the one that is used by the newly spawned pug), not the whole array. So in this case it means that you have to plug that element of the ‘FreeTargets’ array into the ‘OccupiedTarget’ input that you chose randomly (it is coming out from the ‘Get’ node, basically it is the same wire that you use to plug into ‘GetActorTransform’).

Another thing I see is that you probably forgot to check ‘ExposeOnSpawn’ for the SpawnReference, because I don’t see that as an input option in the ‘SpawnActorFromClass’ node. Make sure it is checked, and for that, use a ‘Self’ input (right click->get a reference to self).

Your Kill Pug function is almost finished as well, just get a ‘RemoveItem’ node and plug your ‘TakenTargets’ array and the ‘OccupiedTarget’ reference into it and make sure the execution pin is connected (coming from the ‘KillPug’ node). After that, simply call the ‘DestroyActor’ function (that you used originally).

I think it should work if you do these, let me know if you have any problems.

Okay I have done everything you said however the pugs still don’t spawn when I press play.

Do you have an instance of your Spawner class in your game world? (simply drag and drop it anywhere in your scene)

EDIT:

Put a print string node after the ‘SpawnPugs’ event to check if the event itself is executed.

Yeah I have dragged the spawner into the game world. It seems the event doesnt execute. In the little tab to the left where it shows you how many actors there in the game it changes from 30 to 42. So I assume something is spawning.

Also, do you call your ‘SpawnPugs’ event at EventBeginPlay?

If you do not execute it at least once, that loop that you have set up with the delay will never start.

Make sure that in the EventBeginPlay of your spawner class you call ‘SpawnPugs’!