We can now have two players in our game, but they look the same. Wouldn’t it be nice if each player could customize their look a bit?
We will add that feature in the following lessons.
First, we need something to customize. We added some hands to the player characters and put several hand textures in the project.
There are two parts to character customization:
In this lesson, we’ll be working on the first part: adding a
hand_texture
property to our PlayerSettings
resource and updating the hands in-game when the texture changes in the
resource.
In the following lesson, we will connect the resource to a menu and make it so changing menu options updates the character in the obstacle course.
This will teach you how to react to changes in a resource’s data and synchronize changes in separate game screens.
For now, let’s focus on making the character’s hands customizable.
We need to:
hand_texture
property to the
PlayerSettings
resource.hand_texture
changes.hand_texture
property.Let’s get started.
Open the PlayerSettings.gd
script where we add a new
exported variable.
Notice how we set the type of the hand_texture
variable
to Texture
. When we use the Quick Load feature in
the Inspector later, Godot will only list image textures.
export var hand_texture: Texture = null setget set_hand_texture
func set_hand_texture(new_hand_texture: Texture) -> void:
= new_hand_texture
hand_texture # This Resource function is equivalent to calling emit_signal("changed").
emit_changed()
There are two ways to react to changes in a resource:
Resource
class has a signal named
"changed"
. Every node that needs to react to a change in a
resource can connect to it.We’ll use both in this series.
We’ll need the setter function to give each character the correct look at the start of the game, and the signal will synchronize changes between the menu and the level.
Open the PlayerCharacter.gd
script.
We need to add a function that updates the hands’ textures. We
already defined onready
variables for each hand sprite.
onready var hand_sprite_left := $HandsPivot/LeftHand
onready var hand_sprite_right := $HandsPivot/RightHand
We define a new function to update the sprites’ textures from the
PlayerSettings
resource stored in the settings
property.
func update_skin() -> void:
# We need to update the hands according to the settings' hands_texture
# property.
= settings.hand_texture
hand_sprite_left.texture = settings.hand_texture hand_sprite_right.texture
We need to call that function in two cases:
PlayerSettings
resource
to the character."changed"
signal.
Otherwise, changes in the menu will not synchronize with the characters
in the game level when we put everything together.We can do both by adding a setter function to the
settings
property. When we assign a new
PlayerSettings
, the setter will trigger.
Update the line where we defined the settings
variable
like so.
var settings: PlayerSettings setget set_settings
We then write the setter function where we connect to the settings’
"changed"
signal.
We also call update_skin()
to update the hands the first
time we load the settings.
func set_settings(new_settings: PlayerSettings) -> void:
if new_settings == settings:
return
= new_settings
settings # We need to connect to this signal to synchronize changes to the character
# between the menu and the game level.
connect("changed", self, "update_skin")
new_settings.update_skin()
Changing a setting through the character like
player.settings.hand_texture = ...
will trigger a call to
set_settings()
every time. That’s why the first two lines
check if the settings resource didn’t change.
In that case, we’ll have already connected the changed signal, and we would get an error if we tried to do that again.
At this stage, we can test that the hand textures get applied from the resource in the TwoPlayers scene we used previously.
First, we need to assign different hand textures to our two
PlayerSettings
resource files,
player_1_settings.tres
, and
player_2_settings.tres
.
Open each file and assign them one of the hands textures you’ll find
in the assets/
directory.
Open the scene TwoPlayers.tscn
once again and run it.
You should see the hands display the textures you put in the
resources.
Open the TwoPlayers.gd
script and add a line of code to
replace the hands in one of the settings resources.
func _ready() -> void:
# ...
= preload("../assets/hand_red_open.png") player_1.settings.hand_texture
Changing the hand_texture
property should reflect on the
character if our resource code works.
Rerun the scene, and you should see the players’ hands change according to this last line of code.
You now have the foundations of character customization. All we need is a menu in which the player can choose hand options.
We’ll work on that in the next lesson.
Open the practice Inventory items.
In this practice, you will create a couple of resource files and give them to an inventory to display.