Table of Contents
In this post we'll be covering how Godot uses it's core concept of
Scene composition using
Nodes in the
SceneTree for both large and small scenes. With scenes at the core of Godot, you can break your game into smaller reusable components.
These components then become the building blocks for your game. This is at the heart of Object Oriented Programming and once you have your mind wrapped around how it works, the sky is the limit.
You can watch the video covering this topic, or go at your own pace following this post.
We'll be composing a Tank Scene in this example. Let's first start by creating a new Scene by clicking the new tab icon on the 2D Main Screen or right click in our FileSystem dock under the
res:// folder and selecting New > Scene...
Next let's create a Root Node by selecting the + icon in our Scene Dock. We will search and select
CharacterBody2D . This node is a type of
Node2D that inherits from
PhysicsBody2D and also includes behaviour for handling movement and collisions with other objects.
Let's rename our
Tank as it better describes the scene we are building.
When using any extension of the
CollisionObject2D node, it will warn you if you don't include a Collision Shape (
CollisionPolygon2D). We can go ahead and add a
CollisionShape2D child node to our Tank, we'll define it's
shape property as a
RectangleShape2D for now and once we've imported and set our sprite texture we can adjust it's shape to better match our needs.
Let's take a moment to organize our project a bit further and save our current Tank scene. This will help us stay organized and is a good practice to do early on in a project.
At the root of our project
res:// lets create a folder called
assets and another called
scenes. We'll create a subfolder in assets called
sprites and this is where we will store our sprite assets.
scenes folder is where we will save our Scene
.tscn resources and their corresponding
.gd script resources. Now save our current Tank scene into the
scenes folder as
We may later decide to create further layers of organization in our folder structure to better represent our project as it grows.
Next we will either download the assets from our project's Github repo or create your own
tank_weapon.png. These images will imported as
Texture resources to be used as our tanks main body sprite as well as the weapon which we may want to control separately in the future.
Select our root node on our Tank scene and create a new
Sprite2D child node and name it
BodySprite. We'll also create our weapon by first adding
Node2D as a child of our Tank name it
Weapon and then add a child
WeaponSprite to our Weapon.
BodySprite node selected we should see in the Inspector Dock the texture property. Let's set this texture to our tank's body sprite we've imported into the assets/sprites folder. You can do this by selecting the dropdown and loading, or drag and drop from our FileSystem dock into the sprites texture field in the Inspector. Repeat this process for the
You'll likely need to move your
WeaponSprite to be aligned with the
BodySprite. For our example we'll also set the pivot point to middle of our weapons attachment area. Select the pivot icon on the 2D Screen's toolbar and click the location on the image that your weapon would rotate around.
Note that if you're using the provided project's tank body sprite, it is a texture atlas and requires that on your
Sprite2D node you also define the Animation's hframe property to
2 to match the number of animation frames we have in our sprite sheet.
With this we can also add an
AnimationPlayer to our Tank root node. With this
AnimationPlayer selected, you can select on the Bottom dock's
Animation tab and we'll create 2 Animations:
move. To create a new Animation select the
Animation button and select
New and name it
BodySprite node and on the Inspector you'll notice a key icon on our properties. This allows us to add a keyframe to our Animation Track. Let's add a keyframe for the Sprite's current frame property. Ensure the beginning of the track is selected and then press the key icon for the frame property. Confirm that we want to create a track for the frame property and leave the RESET track option selected. This tells our Animation player what to do with the frame property when the animation resets.
We should now see the
BodySprite's frame property being tracked on the timeline track for our animation. We'll repeat this process by creating a new animation called
move and adding a keyframe for the frame property again, but this time we will click the key icon a second time and Godot will automatically increment the frame value and insert another keyframe on our timeline in the next step.
The step is defined next to the
Animation button and is defaulted to
.1. We can adjust the the length of our animation by modifying the value next to the stopwatch icon on the right side, this is defaulted to
1. Next to that is our looping option, where looping is off by default. If we click the loop icon once it'll enable looping, a 2nd click will enable ping ponging, and a 3rd time cycles back to off. For our
move animation we'd like it to be looping, with a duration of
.2 and the default step size of
Next we'll cover extracting a branch of our scene and moving it into it's own scene. Our
Weapon node is a great candidate for this, as we may have different behavior and children such as our
Weapon node and right click and select
Save Branch as Scene and name it
weapon.tscn. This will pull our nodes into their own scene, which you'll note the Scene icon on our
Weapon node. Click the Scene icon to open our new Scene tab and our
SceneTree will only contain the root
Weapon node as well as the
WeaponSprite node child.
We'll do more with our Weapon later on, but for now understand that the process of extracting nodes into their own scene is great for decoupling features when it makes sense and prevents a scene from becoming too large in scope.
Now that we've got our Tank sprites visible in our editor, we can modify the
CollisionShape2D's sizing to better fit our tank. Select the CollisionShape2D and drag the scale handles to adjust the size to our liking.
We will handle collision logic later on, but for now we will just setup the sizing and ensure it matches our sprite's artwork.
This is a good start to learning the basics of creating and managing a Nodes in Scene for an object in our game and how those Nodes compose into the SceneTree. We've also learned setting properties in the Inspector and how we can keyframe those properties within an Animation.
Join us next as we add some life into our tank by introducing
GDScript and write some initial code to move our tank around in our world.