Godot Version
Godot Engine v4.3.stable.official.77dcf97d8
Question
Hi, I need some help with my simple multiplayer game. I want to change the color of the players’ bodies (MeshInstance3D) in runtime after they join the server. I’m trying to separate the players into two teams.
I wrote the set_team(team_id: int) function in my player script to change the players’ team and call it from the parent script. In the _ready() function of the player script, I set the color of the player’s body based on the team.
I’ve tried debugging using breakpoints and printing, and it seems that the team was set correctly and the color changed, but the color that I can see is still blue instead of green or red.
this is how I set the color and the team in player.gd :
@onready var body: MeshInstance3D = $Body/Body
var team: int = 0
...
func _ready() -> void:
camera.current = true
camera.top_level = true
if team == 1:
body.mesh.material.albedo_color = Color(1, 0, 0, 1)
print(body.mesh.material.albedo_color)
elif team == 2:
body.mesh.material.albedo_color = Color(0, 1, 0, 1)
print(body.mesh.material.albedo_color)
...
func set_team(team_id: int) -> void:
team = team_id
and the output after player click on join button :
(1, 0, 0, 1)
if you change the abledo_color yourself in the inspector does it change the color?
I’m guessing you can’t see what the server looks like?
lets say the server is fine and showing the right colors.
how do you replicate team
to the clients?
Does it happen in a custom spawn from a MultiplayerSpawner?
Is it a MultiplayerSyncrhonizer with on spawn enabled for team?
RPC’d?
Yes, when I change the “albedo_color” in the inspector, it changes the color of the player’s body.
I have commented out two lines that hide the world and players when the host button is pressed. Now, I can see players on the server side, and their color changes there, but on the client side, they still stay blue.
Additionally, I have encountered another problem:
when the first player joins, its color is red, which is correct. However, when the second player joins, the color of both players turns green which is incorrect. it must be the first one red and the second one green.
let me explain the code flow of the project that I wrote.
I have a game scene which is the main one and has two spawners, one for players and one for the server, and a simple panel with three buttons “host”, “join”, and, “exit”. on the first instance, I click on “host” It spawns a server scene and hides the world and players (normally. it is commented out now) after that on the other two instances I click on “join” which spawns a player scene and a player_control scene which is a simple label and kick button to show on the server panel. there is one synchronizer in the total project which is in the player scene and used for syncing players’ positions and players’ rotations.
for teams, I define an integer variable in the player script that is set by a function, called from the main script and in _ready function of player script I set color, base on that variable.
it does not use the RPC functions at all. should I use them?
I hope it was clear. I think that I made it too complicated.
sorry for the long text.
Rpc-methods are a good way of handling that. The reason both players change color is probably because you change the color in standardmaterial which is a shared resource between the scenes. You would have to make it local_to_scene
1 Like
@herrspaten is correct
I think this happens because the material is being shared for efficiency reasons. The fix for this is easy. Like he says, You should be able to make the material resource unique in the inspector.
Now, I’m more I’m more interested in how you spawn the player. It isn’t clear in your explanation.
Do you use a MultiplayerSpawner? Or is it a reaction to the peer connection signal that the player spawns?
If you use a MultiplayerSpawner, but not the custom spawn function, the spawner node will not preserve state set by the host and the player will remain blue on the peer.
This could potentially be fixed with MultiplayerSynchronizer if you add team integer to the replication config with a Spawn sync enabled, but could just set it to watch for the sync or never if you don’t allow players to change side. (This may not fix it since it relies on data that may not have arrived yet. I have had issues with state initializing on spawn this way with synchronizers)
Another way is to use the custom spawn of the MultiplayerSpawner to build the player on the remote peer using parameters to build the player node. (Although it sounds like your control could make it tricky?)
Concerning your code, I feel like you should just change the colored when the set_team is called. I don’t see a reason to defer the change until _ready.
1 Like