Hello, this is Kim Hyun-Jin, and I'm in charge of Unreal Engine Basics for Immersive Contents
Today, we will learn about how to spawn an actor after a certain amount of time passes
To decide whether that time has passed, we will be learning about
How to use Set Time Node and Delay Node
Spawning Actor After A Certain Time
Let's learn about spawning an actor after a certain time
First, let's create a new Blueprint class
Go to Content Browser
Right click
Choose 'Blueprint Class'
Let's choose 'Actor'
Let's name it
BP_AIActorManager
Double click to open it
For this actor
Let's make it spawn an AI Actor
After a certain amount of time passes
In order to realize this
We need to start with the concept of Delta Seconds
Delta Seconds mean the amount of time needed
Whenever we call an Event Tick Node
Say, we clicked on 'Play' just now
Then this will call our Tick events several times, right?
This Tick event is called once
And the second Tick
Let's say this took 0.1 second
And it is called again
And this is also another 0.1 second
The same 0.1 here
Then, at this point, for this Tick event
How much time has passed since the start?
0.1 second, and three times, right?
Meaning, 0.3 seconds, correct?
So, when we spawn an actor after a certain time
This accumulates these Delta Seconds
And once it hits the set number
Than this spawns an actor
For example, let's say that after every 0.5 second
We will spawn one AI Actor
So when we press 'Start'
Tick Event goes, once, twice, three times, four, five, six times
The spawning happens whenever this is called
Why is that?
It's because every 0.1 second is
One, two, three, four, five
In total, 0.5 second has accumulated
So this will spawn an AI Actor, once
And then
After five times of this
This will again spawn an AI Actor
For a movement, we say vt, and this value t
This means we multiply it by Delta Seconds, right?
Let me explain why we multiply this
Let's say we have a great computer
This computer, whenever it processes something
Let's say it can process something four times in a second
Now we have a bad computer
This bad computer, in the same duration of a second
Let's say it can process something twice
And let's say that we're processing a movement
And when this processes it once
This code will make a character move by a meter
Then, this great computer will call this movement by a meter four times, right?
Then how far has the character moved?
Four meters in total
And this bad computer, since it runs the same code
It makes the character move a meter whenever it processes the code once
Same one meter
Then what happens?
After a second, this character moves two meters
Then here, whether it is a great or a bad computer, with the same program
With a great computer, the character moves more
In the same duration of time
And for the bad computer, it moves less
Then this program is a very unfair one
Therefore, despite differences in capability
All characters should move a certain amount if given the same amount of time
Which means, let's try this
We said a great computer processes this four times in a second
This means that processing it once takes 0.25 seconds
0.25 seconds
While this bad computer takes 0.5 second each
So to this distance being traveled
Let's multiply it by this time that each process takes
And then let's try adding all the values
Then, for a great computer
You will get 0.25 for each
And once you add them all up
The final result is 1
Let's do the same for our bad computer
Then this becomes 0.5 and 0.5, when summed it's also 1
This will make sure that both move a meter
It's the same now, see?
What of this procedure made them the same?
It's when we multiplied the time duration for each process
So what is this time duration in other words?
It is Delta Seconds
So, when we move an AI Actor
We multiply it by Delta Seconds
In order to make the movement exactly same for all computers
Same thing, for Player, we want to make it move the same for all computers
That's why we multiplied by Delta Seconds here as well
So, let's use Delta Seconds to check for our time duration
And then spawn an Actor
First, let's create two variables
At VARIABLES, click on the plus button
And its name, let's say
'CreateTime'
Data type is 'Float'
And then, VARIABLES, plus button again
Let's name this 'CurrentTime'
Data type, same thing, let's say 'Float'
Compile, and let's choose our CreateTime
And set its default value as 1
This CreateTime variable
Does its job at a certain time
And this means that an Actor will be spawned once in every second
At Event Tick Node, we will accumulate the time
Let's drag Delta Seconds, and plus
Drag in CurrentTime at our left
And bring it here using 'get'
Now, let's add this value
Next, again, drag in CurrentTime
This time, use 'set' to bring it
Then, this value, which is a sum of Delta Seconds and CurrentTime
This value goes into CurrentTime again
Now it runs this
Let's say that the value for Delta Seconds is 0.5
CurrentTime starts with 0, correct?
Add the two, and what do we have?
We have 0.5
And this 0.5 goes where?
It goes back to CurrentTime
Then, when the Tick Event is called again
CurrentTime now is not 0, what is it?
It becomes 0.5
So when wee add it to Delta Seconds, it becomes 1
So, again, CurrentTime becomes
This value 1
And when another Event Tick runs
CurrentTime, because it's now 1, not 0.5,
It will add 1 with 0.5
Which makes CurrentTime 1.5 again
So this keeps accumulating Delta Seconds to count time
Let's try and print this as well
Right click, 'Print String'
And connect to the Execution Pin
And CurrentTime, with the value it has, add Instring, compile
Moving back to Action Level
Let's drag in our BP_AIActorManager
And place it at the Viewport
Make sure this Output Log window
Is visible over here
When we press 'Play'
1
2
3
4
5
It looks as if it is going in real time
The value matches the flow of time in reality
So, what does this part do?
It allows time to pass
And then, this CurrentTime value
It determines if this is bigger than 1
Meaning, if it is bigger than this CreateTime value
What does that mean?
It means that a second has passed
Drag in this CurrentTime
And add a sign to ask if the left is bigger, select 'Greater'
And then drag in CreateTime variable in our left by using 'get'
So this compares the values of CurrentTime and CreateTime
And then we ask
If CurrentTime value is
Bigger than that of CreateTime
Then this becomes True
If it is less, it returns False
So we ask this, with what?
With an if statement
So, right click and search for 'if' and you will get a node called 'Branch'
Add this node
And this compared value goes to this Condition
Then, with these two values, we arrive at either True or False
Let's have this Branch run
What does this mean?
It means, if
If a second has passed
Which is this, right?
And here
I said 'a second' because the default value for CreateTime is 1
If it is 2, that means 'if two seconds have passed'
When this is True, right?
If this is True, what do we do?
We create an Actor
If False, we don't do anything
This time, let's right click and
Add a node called 'Spawn Actor from Class'
Let's connect it so that it runs when True
We have this first class Item here
Click on 'Select Class'
And this will show us all the Blueprint classes we created, as well as the default classes at Unreal
So what class are we trying to create?
It is BP_AIActor
So let's search for BP_AIActor and we have it here
Select BP_AIActor
Second, 'Spawn Tranform'
It asks, when creating this Actor
What location, rotation value, and scale value it will have
So now, let's spawn it at where AI Actor Manager is
And for size and rotation, let's keep it default
For BP_AIManager, size and rotation are set as default
Only the location changes, since we place it at the Actor Level
So all we need is its location value
So right click on this 'Spawn Transform' pin
And select the menu 'Split Struct Pin'
Like so here, Location, Rotation, and Scale
We can put in values for each of them
Here, we just need to set Location for that of our AI Manager
So, right click
Add 'Get Actor Location' node
And then, this value will be connected to our Spawn Transform, or the location part
What does this mean?
It means, let's spawn
BP_AIActor
And where?
At BP_AIActor
At Manager
At Location
Let's compile
Let's move to our Actual Level
Let's remove this BP_AIActor now
Let's try and play now
When we play, it keeps adding itself, right?
It is spawning, but not once every second, it keeps coming
This is happening because
We've accumulated CreateTime
Let's say it is now at 1.2 seconds mark
Then, since it's greater than CreateTime
This statement becomes True, and it spawns an Actor
And it goes back here
And what is CreateTime at this point?
It is 1.2 seconds
Now, let's say we added more Delta Seconds
And that it is now bigger than 1.2, which is 1.3 seconds
Then, now, it is greater than CreateTime again
So it is being spawned again
Instead of waiting for another second, it just spawns again
It only waits for the initial second
And then it keeps spawning without waiting
What do we do for this?
After spawning BP_AIActor
We need to reset CurrentTime that has counted time back to 0
Now, bring in CurrentTime at our left
By using 'set'
And then we just put in the value 0 for CurrentTime
So that it runs this
'Accumulated Time'
'Reset'
Compile, and at the Actual Level
Let's play it
Then, just like so
One
Two
Three
One is spawned every second, see?
We are seeing error here because
When AI Actor and Player collide, both are destroyed
And whenever an AI Actor is spawned, its node looks for Player
And since there is no Player left, we are seeing an error
For our test purpose
Let's make our Player not be destroyed
So double click on BP_Player to open
And for our on Components Begin Overlap Node
Let's remove the part where it destroys itself
Next, save and compile
Back at the Actual Level, play again and
Now we see AI Actor spawning and approaching as I move
And what happens when we collide?
It gets destroyed
Using SetTimer Node
Now, let's use a SetTimer Node
So that it implements the same thing we just talked about
Back at our BeginPlay Node, right click
And add a node named 'SetTimer by Function Name'
With this node, for every 'time'
It calls a same function to 'Function Name'
And here
We will make this node that spawns BP_AIActor into a function
So that it calls that function right away
To our left, at FUNCTIONS, click on the plus button to create a function
Let's call it 'CreateAIActor'
At its Event Graph window
Let's copy SpawnActor BP_AIActor Node and Get Actor Location Node
And paste it at CreateAIActor Node
And connect the Execution Node
Back to Event Graph
Click on the function name at SetTime by Function Name
And write the function name, 'CreateAIActor'
For 'time', bring 'Create Time' using 'get'
And connect
Now, since this action needs to repeat itself
Let's tick the box that says 'Looping'
And connect Begin Play to SetTimer by Function Name
This will spawn at Timer
And also spawn at where we measure the time
So let's disconnect the Exec Pin at Event Tick
And compile, back to Actual Level, let's play it
And we see the same spawning every other second
Using Delay Node
Next, let's use Delay Node to spawn actors
In order to prevent duplicate spawns
Disconnect the Execution Pin that starts at Begin Play
And back to Event Tick
At the bottom, right click and search for 'Delay'
And we get a Delay Node at the bottom
Let's add that
And connect the Execution Pin from the Event Tick so that it comes over here
And this duration, or CreateTime, bring it in using 'get' and connect it
Next, let's use our CreateAIActor function and connect it here so that it runs
And now, compile, and back to our Actual Level and play
Like this, we see how it spawns one AI Actor per every second
And what is the difference here?
In order to repeat a behavior
SetTime Node has the 'looping' option checked
as True, and it only runs once at Begin Play
While this one, it does not run the next one before our duration passes
Meaning, even if it repeats, it won't continue until a duration passes
After this duration passes
Then it runs this and checks again
You can use whatever is more convenient for you
But in the beginning, I recommend that
You use the first method where we make the time pass ourselves
And use an if statement in order for our desired action
Let's now apply all the things we have learned
And spawn and actor that moves upward from this Player position
And let's make it a bit fast
At Content Browser, right click
'Blueprint Class' and choose 'Actor'
Let's name it BP_Bullet
Double click to open
For this bullet, we will just code it so that it moves upward
At Event Graph
Right click
Search for 'Get Actor Location' and add it
And right click again to add 'Get Actor Forward Vector'
Now, let's create a variable
At VARIABLES, click on the plus button and create our Speed variable
Data type is 'Float'
Compile, and let's set its default value as 600
Forward Vector, multiply
And let's bring in Speed using 'get' and multiply it
And then multiply it again by the result we have
And multiply it by this Delta Time
Next, add another Plus node here
Add it with the current location
Right click to add 'Set Actor Location Node'
Put it into New Location
And connect Exec Pin from Event Tick to Select Location
Now, let's go to Viewport and touch up its appearance
Click on Add, choose 'Static Mesh'
At the Details window to the right, go to 'Static Mesh' and choose 'None'
And choose 'Capsule'
See this 'Shape Narrow Capsule'?
Choose this capsule
Compile, and choose any color you like for this material
And let's tilt it a bit to this side
So this green, this green part of Location at Transform
Make it 90 and it rotates the other way, see?
-90 will rotate it this way around
It may be a bit too big
So let's go back to Actual Level and see by adding our BP_Bullet
Oh, it's not too big
If it is too big for you
You can go back and reduce the Scale values of our BP_Bullet
I will leave this as it is now
Compile, back to Actual Level
Add BP_Bullet here and play
Now we see that it is moving upward
And we will keep it at our Player location
And make it spawn every certain amount of time
Then what happens?
It spawns, it moves up, another spawns, it moves up
That's what we will see
Let's remove this BP_Bullet here
Back to BP_Player
Let's create a variable
FUNCTIONS, click on the plus button
Let's name it CreateBullet
Right click, add 'Spawn Actor From Class' node
Click on this area where we choose the class
And set our BP_Bullet here
Next, right click here
Let's now bring in 'Get Actor Transform'
And put it right into Spawn Transform
What does this do?
It sets the location, rotation and scale values
Of our Player at once
Let's not connect our Exec Pin
Back to our Event Graph
At Begin Play, let's use our Timer node
To spawn our Bullet Actor
Right click and select 'Set Timer by Function Name'
For function name
Bring in our CreateBullet
And tick for Looping
Let's set the time value as 0.5
And then
Connect it with the Exec Pin from our 'Add Mapping Context'
Compile, back to Actual Level, play
Like so, every 0.5 second
This spawns an Actor called Bullet
And here
When a bullet and an AI Actor collide
Then our bullet actor should disappear
So at Edit, go to 'Project Settings'
At 'Engine', go to 'Collision' tab
Let's use New Object channel to create a channel called Bullet
And for default response, I will set it as 'ignore'
And then click on 'Accept'
Back to BP_Bullet
Choose 'Static Mesh' and at Details, move to Collision tab
And for this Collision preset, go to its dropdown menu and choose 'Custom'
And change 'Collision Enabled' to 'Query Only'
And 'Object Type', let's set it to Bullet that we made
Other than that, keep everything as 'Ignore'
Let's just go to this AI part for Object Response
And set it as 'Overlap'
And now, scroll down
When 'On Component Begin Overlap'
We will remove the both
So let's click on this button to add a node
And here, at 'Other Actor', drag the cursor
And search for 'destroy' to get 'Destroy Actor'
Add this node
And then right click again
And add another 'Destroy Actor'
And also connect the Exec Pin
This means, when we collide, it removes you and me
Let's compile
At BP_Player, choose this Box Component
At 'Collision'
You should make sure that Bullet is ignoring any collision
Or, this will happen
Let's say we set it as Overlap
Then every time a bullet spawns, it will disappear, right?
It cannot do that when colliding with Player
So make sure to set it as Ignore
Now, at BP_AIActor
Choose 'Sphere' component
And move to Collision tab
And expand on this Collision preset
Here, Bullet should be set as 'Overlap'
So that Bullet and AIActor collide with each other
So compile, at Actual Level, let's try playing it
Like so, whenever Bullet Actor and AI Actor collide
They disappear
See how whenever BP_Bullet and BP_AIActor meet, they disappear
And let's add a sound effect for that
Let's disconnect the Exec Pin connected to this actor destroying node
And let's add a sound effect for explosion here
Right click, search for 'Play Sound'
And we have 'Play Sound 2D'
Add this node
And we get a list of sounds we can choose from
Go to 'Select Asset'
And we see that list of sounds we can use
Now, search for 'explo...' and we get 'Explosion01'
Choose this file
And connect the Exec Pin
It's a very simple way to play a sound
Compile, back to Actual Level, play
And we now hear the sound effect for every collision
When you study Unreal on your own
I recommend that you also work on adding sound effects
Whenever we spawn a BP_Bullet as well
Now, after certain time passes
It keeps adding BP_AIActor or BP_Bullet
And there is a problem with this
When we play it
See the bullets that are going upward
And the BP_AIActors that are going downward past Player?
Let's pause here and check out our Outliner window to the right
We have a ton of BP_AIActor and BP_Bullet here
These actors that are here
They do not get destroyed; they remain so until the end
This AI Actor just moves this way forever
And with this happening
If we run this content for long enough
There will be a myriad of un-destroyed actors
That will slow down the program
And in a worst case scenario
The program may shut itself down
So we need to make sure that whenever BP_AIActor or BP_Bullet goes beyond this screen
That they get destroyed as well
And you already know how to implement this
Which is, first create an Actor
And this Actor will
Destroy any actor that
Collide into it
So let's create this actor
Right click
Blueprint Class, choose 'Actor'
Let's name it 'DestroyZone'
Double click to open
Click on 'Add' to add a Static Mesh
And at Details, at Static Mesh menu, search for 'Cube'
And add it here
This DestroyZone Actor,
It won't be visible in our play screen
Meaning, we do not need any particular material for this
And at Edit, go to 'Project Settings'
At Engine, go to 'Collision' tab
And let's create one more Object Channel
Choose 'New Object Channel'
And let's name it DestroyZone
Let's set 'Default Response' as 'Ignore'
Now, click on 'Accept' and close the window
Compile once again
At DestroyZone, choose 'Static Mesh'
Scroll down the Details, at Collision tab
At the dropdown menu of 'Collision' preset
Choose 'Custom'
And for 'Collision Enabled', choose 'QueryOnly'
And for 'Collision Process', choose ignore, and for everything else as well
So that only Bullet and AI, these two will overlap, or collide
And then scroll down at 'Event' tab
For On Component Begin Overlap, click on the plus button to add a node
At Other Actor Pin, drag the ouse out
And add 'Destroy Actor Node'
Meaning, for this DestroyZone
Only Bullet and AI actors can collide with this
So this collision event
It is only called when these two actors collide
And it will destroy that actor that collides with this
Compile
And let's go to BP_Bullet and check one thing
Choose 'Static Mesh', and at 'Collision' tab
Let's change the setting to say that it will 'Overlap' or collide into DestroyZone
Again, at Content Drawer
At Actual Practice, double click on BP_AIActor to open it
Here, go to our Sphere Collision Component
At 'Collision' tab, expand on Collision Presets
And for DestroyZone, tick for 'Overlap'
And back to Actual Level
We will add this DestroyZone at our level
Change the size with our Scale Tool
Drag on this green to make it longer
We need to set it so that it is not visible in our play screen
This cannot show us whether these actors are
Being destroyed or not
So press F8 to zoom out a little
And let's force this Player to move a bit
It will collide into it, but it will not be destroyed
Let's pause there
At DestroyZone, we should change this Object Type at Collision
As of now, this Object Type is set as WorldDynamic
That's why the collision with AI Actor and Bullet Actor had been ignored
Let's go to the dropdown menu of World to set it as DestroyZone
Compile again and play
Let's zoom out and move our Player
See these two actors; they are destroyed when they bump into this
This means, if we make this big wall of DestroyZone here
All actors that try to move out of the area will get destroyed
Let's summarize what we have learned today
The equation of 'Duration of time = Current time Time required to call the Tick Function'
Has helped us measure the amount of time having passed
And we also learned how to spawn an actor after a certain time
We also learned about how to use SetTimer Node and Delay Node
Spawn Actor after a Certain Time Accumulate Delta Seconds and spawn an actor when it reaches a number
Multiply by Delta Seconds to make the movement the same for all environments
Using SetTimer Node SetTimer by Function Name
Every 'time', call the same function as Function Name; to repeat this, tick on 'Looping'
Using Delay Node Search for Delay at Event Tick Duration: Runs itself again after a certain time Add sound effect for when the actor gets destroyed with collision