♪♪♪
Zak Parrish: Hey folks, this is Zak from Epic Games.
If you didn't already know, Unreal Engine 4.7 is out.
If you don't have it, you should get it because there are several new features.
One of those features is the ability to create Blueprintable Components.
In this video, we want to give you a really quick idea of what Blueprintable Components are
and an overview of some ways you can use them.
It is really cool, so let me show you.
Here is a project we put together.
It is a little spaceship shooter.
It is pretty simple.
This is all done in Paper 2D.
We have a ship that flies around and shoots lasers.
There are power ups that make his lasers more powerful.
You will notice it is missing enemies.
We will make an enemy for the game using our in-editor asset creation workflow along with
some Blueprintable custom components I have put together.
If there is time, I will make one from scratch to show you how that workflow goes.
Let's start by dragging in an Empty Pawn.
It is a Pawn that does nothing.
In Location, make sure Y is set to 0.
The game plane exists on the Y axis.
Again, this is a 2D game; 0 and Y is where the game is actually going.
Let's click +Add Component to add a new component.
We are going to add a Sphere Component.
In the Details panel, type "sphere" and select Sphere Collision.
We will leave the name as Sphere.
This can be very informal and simple.
In the Sprites folder I created, I have several random sprites.
I am going to drag MagneticMineVector_Sprite on top of the Sphere.
This is just to give us something to render in our viewport.
Now you can see our sprite.
He has a little bit of depth.
He responds to lighting, but he is 2D.
It is just a clever use of a Normal Map. It is nothing fancy.
That is what we have.
We have broken up every other piece of functionality into a series of components.
We have a 2DShooterMovement Component, ExplodeOnDeathComponent, HurtsToTouch, etc.
All of these were written entirely within Blueprint.
We can drag-and-drop these onto this Pawn to define behavior.
Let's start by dragging the 2DShooterMovement Component onto the Sphere.
This component was designed in a way that it defines
how this object can move through space.
I will open the 2DShooterMovement Component real quick.
We won't get into this too much. I will open the 2DShooterMovement.
You can see what we are doing on Event Begin Play.
As soon as this component comes to life, we are getting a reference to its owner,
and we are casting that out to a Pawn. Then I am storing that information, so I can use it later.
Then on every tick, we are making sure the Pawn is still valid.
We are grabbing Movement Input Vector.
All we are doing is using that to add a local offset to the object.
You may not already know the Movement Input Vector is what would come in
from any sort of input like a gamepad.
The Movement Input Vector can also come from an AI Controller.
We are checking here to see if there is an AI Controller on this object.
If there is an AI Controller, go ahead and move the object around.
If there is not an AI Controller, that means the is probably being driven by a player.
We have some screen limiting math.
I will double-click to open ScreenLimiting_2.
It looks really scary, but it is just several Boolean operations
to see what side of the screen we are on.
The screen limiting math multiplies the Movement Input Vector by 0.
The easy way to look at this is it locks us so we can't move
outside a certain range on the screen.
That is the only thing that would be important to us in this example.
That is our 2DShooterMovement Component.
The cool thing is this the exact same Movement Component that is used to
move our hero spaceship you saw me flying around and shooting lasers.
Now, this object we have created has the ability to move around.
Having the ability, is not the same as having the will or the drive.
For that drive, we need an AI Component.
I have a custom Blueprint Component called AISelectorComponent.
I can drag-and-drop AISelectorComponent onto the 2DShooterMovement Component.
This provides the user with a drop down for the different types of AI Controller we have
created in this project.
We can tell the object to move down the screen or to do all different kinds of behaviors.
Let's select ChaseThePlayer.
I have only added two (2) components: 2DShooterMovement and AISelector, which is set to ChaseThePlayer.
With that, I will click Play.
It is not going to do anything while we are invincible.
You are invincible for the first four (4) seconds of the game.
All of a sudden he starts chasing us around the screen, which is pretty special.
Nothing else happens. I can't shoot it or interact with it.
Let's fix that.
Let's say we want to shoot this and have it blow up.
We have a TakesDamageComponent.
I will double-click to open it up again really quickly.
You can see on Event Begin Play, we are getting the owner.
We are binding a Custom Event to whenever the owner takes damage.
Whenever the owner of the component takes damage, we want to do some things.
Here is what we want to do.
We want to subtract the damage from their existing Health and then reset that value
to the new Health.
We also have a Check for Death function, which is doing a very quick comparison
to see if Health is less than 0.
If your Health is less than 0, you probably ought to be destroyed.
There is a special case for the hero ship because he has a death and respawn action.
We are not going to get caught up in that.
Let's close a lot of these tabs.
Let's go all the way back to our level.
Drag-and-drop the TakesDamageComponent onto the AIController.
Set a value for Health and press Play.
Now, I can shoot the Pawn and it goes away.
What happened was I shot the Pawn, and it ceased to exist.
That was kind of boring.
I am going to stop opening up the components.
They are all very simple. We have an ExplodeOnDeathComponent.
I can drag-and-drop the ExplodeOnDeathComponent onto the AIController.
Let's press Play again.
We can shoot and now the Pawn explodes when we hit the it.
Again, this is a tiny piece of scripted behavior that is
completely enclosed inside of that component.
By adding the behavior, we start to further define what this Pawn can do.
Let's do a few other things.
Let's say we want the Pawn to hurt us if it touches us.
The Pawn is chasing us, right?
If the Pawn ever hits us, it would be cool if it hurt us.
Drag-and-drop a HurtsToTouch Component on top of the AIController.
It has a Collision Damage set to 500.
We will select the checkbox to Damage Itself.
I said I wouldn't open another component,
but I will open HurtsToTouch to give you some insight.
You can see each component is a tiny snippet of Blueprint script.
They are all very small.
In a lot of cases, they are just binding to an existing event that is already on the Pawn.
Now, let's test this. Click Play.
We have to be vulnerable for the behavior to work. He chases us.
As soon as he hits us, we both explode.
That is awesome.
Now, let's add another component.
We have a ScoreComponent, which gives us the ability to assign a score.
I will set Score to 3184.
That is just a random number.
When I shoot him, my score is in the upper left corner: 3184. I don't know how well you can see it.
The Score Component is working.
You can see how this component based workflow allows me to take all of the important parts
of the game behavior, break them into each of these components,
and then I can drag-and-drop the ones I need.
Where do you go from here?
I have this Pawn that has been defined and is doing what I want it to do.
I can convert the Pawn to a Blueprint by clicking Blueprint / Add Script.
Let's do that. Right-click and select New Folder.
I will call this MySpecialEnemies.
Inside this folder, we will call this Blueprint MySpecialEnemy.
I will click Create Blueprint to create that.
This Pawn has been replaced with a Blueprint.
We can open the Blueprint inside the Blueprint Editor.
We can add more script to it.
We can start giving it brand new behavior if we wanted.
It doesn't stop here.
Technically, it only starts here.
We have only begun the process.
If we are happy, that is cool.
We could grab this Spawn Volume.
This is something in my level that is a custom Blueprint object.
I will open it up so you can see it.
Really all it is doing is spawning enemies from somewhere within its volume.
It has a property for what type of Enemy Class it is spawning.
I can set the Enemy Class to MySpecialEnemy that we just created.
I will play the game.
As soon as we can be killed, the enemies are going to start spawning onto the screen.
Here they come. They are all chasing me and they are all very scary.
We can start blowing them up.
Boom.
Awesome.
What if decide we want more functionality later?
We have converted this to a Blueprint.
It is real easy to fall into the trap of thinking you are done once you have done that.
You are really not done.
Let's create a new component of our own to add a new piece of behavior.
I am going to right-click in the Content Browser and select Blueprint Class.
Here are your new features for this Blueprint Class.
You have Actor Component and Scene Component.
A Scene Component is a component that has its own relative location.
The location is relative to where the Actor is. You can move the Scene Component around.
Think of it like how an Arrow Component already works inside of Blueprint.
You can position the Arrow Component anywhere relative within the Blueprint.
The same is true for a Scene Component.
An Actor Component has no key location and can be placed anywhere.
We are going to use an Actor Component.
Let's call this FireAtPlayer.
This behavior is designed to allow our enemy to start shooting at the player.
We will double-click to open FireAtPlayer.
We have two (2) events here, which are very important.
We have Event Begin Play and Event Tick.
Event Begin Play is what happens when this component is added to an Actor.
The moment this component is born, all of the attached script will be executed.
Event Tick is something that will happen on every tick of the game.
Be very careful with Event Tick because heavy tick operations tend to add up
and lead to performance problems. It doesn't mean you should
avoid Tick events, you should be careful with how you use them.
I am going to create a Custom Event.
Let's give this a name.
Let's call this Fire.
That is easy to remember.
When we fire, we are going to Get Player Pawn.
We are going to make sure the Player Pawn is actually the hero ship.
We will drag off a wire and Cast To HeroShipPawn.
We will connect the nodes.
Here is a fun thing.
The Damage Component we applied to the enemy ship also exists on our hero.
We will get that Damage Component.
Again, we are just reusing the same components over and over again.
Get Damage Component.
The Damage Component has its own custom property for invulnerability.
We will get whether or not the player is invulnerable.
You can't kill the player during the first 3-4 seconds of gameplay.
If you don't have the invulnerability in place, the game is actually very hard to play.
Let's drag a wire off Invulnerable and create a Branch.
We are creating this Branch just so that we don't do anything if the player is invulnerable.
As soon as the player is no longer invulnerable and this tests to False,
we want to Spawn Actor from Class.
We want to spawn a class we created called EnemyShot.
This is a basic Projectile Class.
All it does is fire forward and applies damage when it hits something.
It is pretty basic.
Now that we have this, we need to know the direction we are going to be shooting.
Let's do a little bit of very basic vector math.
Let's Get Player Pawn.
We will also get our owner's location.
Get Owner.
We need to get the location in space for the owner and the Player Pawn.
Drag out a wire and say "Get Actor Location".
I will copy and paste both of them.
We know where both of these objects live in the world at this particular moment.
We are going to subtract the location of the owner
away from the location of the Player Pawn.
We are going to get the XVector Rotation.
Type in "XVector" and select Rotation from XVector.
This makes a rotator starting from the X axis of the vector.
I am going to right-click on the Spawn Transform.
If you didn't know you could do this, this is awesome.
Select Split Struct Pin.
We will drive Spawn Transform Rotation with our new calculation.
Where are we going to shoot from?
That will be the owner's location.
Drag a wire to Spawn Transform Location.
With that, we should be ready to shoot.
We just have a little bit more work to do because this is just a Custom Event.
Nothing is firing this Custom Event right now.
Off the Event Begin Play, we will set a timer.
This timer is going to call the Fire function.
We need to set up the interval at which it is going to call this function.
I am going to do something a little fancy because
I want this to be very easy for a user to utilize.
Let's create a new variable by clicking +Variable.
We will call this "FireFrequencyRange".
We will set its Variable Type to Vector2D.
For its Default Value, we will give this a range of 1 to 3 seconds.
If I drag FireFrequencyRange into the graph,
I can immediately right-click on its pin and select Split Struct Pin.
Now, I have FireFrequencyRange X and I have FireFrequencyRange Y.
Check this out.
We can drag off the first pin and do a Random Float in Range.
We can use those two (2) numbers to drive Max and Min.
The Return Value becomes my Time.
I will make the new FireFrequencyRange variable editable by clicking the eye icon.
When I compile this means if I drop this component onto any object in my scene, I will be able
to see a max and min time where it should be shooting.
Let's test this out.
If I go under MySpecialEnemies, MySpecialEnemy is now a Blueprint.
If I want to add more components, I need to do that within the Blueprint Editor.
Double-click to open MySpecialEnemy.
Here is his Components panel. There are all those components I added.
Let's add one more by clicking +Add Component. We will add the new FireAtPlayer Component.
When we select FireAtPlayer, you see it has Fire Frequency Range.
The default time of 1-3 seconds is fine, but we can change that if we want.
Now, let's play the game.
Nothing happens while we are invulnerable, which is good.
As soon as we are vulnerable, the enemies are blowing themselves up when they get shot.
That is not very useful.
There is a fix for that.
We will laugh at that one.
Enemy Shot is a special custom class that needs to know
if it is being fired from an enemy.
Because I didn't check Fire From Enemy,
all of the shots are colliding with the enemy as soon as they shoot them
so they are blowing themselves up.
This makes the game a little too easy.
We will check Fired From Enemy.
We will click Play one more time.
We need fanfare.
I need music for this game.
Now the enemies are all shooting at me and chasing me.
They will explode if they touch me.
You see how easy that was for me to create this entirely new behavior.
Of course, there was some work to do on the back end.
There were different scripts.
I created different AI Controllers we could switch between.
There was the one that chases the enemy, and there were a few others I didn't show.
The actual scripting of each component didn't take place in this video.
The point is that with this component driven workflow, you don't have to just make a game.
You can make a framework which makes building your games easier as you move forward.
People on my team whose job was to create asteroids, space debris, boss characters, etc.
can simply drag-and-drop the components they need.
Or, we can create new components as we decide we need more behavior.
That wraps it up for this video.
I just wanted to show you all this new workflow in Unreal Engine 4.7.
Please go get Unreal Engine 4.
If you are interested in what you've seen and want to try it out,
go get Unreal Engine 4.7 right now.
I can't wait to see what you have made.
I will talk to you later.
♪♪♪