I am trying to figure out how to add name tags above the player in multiplayer in Godot 4

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By AzoraHusky

Hello, been trying to figure out how to add name tags to players in multiplayer. I setup the 3D Label and set a “player_name” variable. But I can’t figure out how to apply the name from the client connecting to the server.

I have tried a dictionary and making it a global variable. But no matter what I do, it makes the name “31” instead of the name I gave it. I tried RPC and such, but no luck.

The way the name is set is at the main menu, you type the IP and type the name, and then it is supposed to set the name when you join, but instead it gives a 31. I probably don’t fully understand how RPC and such works, trying to get myself accustomed to Godot, and I was half tempted to go back to Unreal due to how frustrating it was and how little information I found on the topic.

The main menu for the game

World.gd

extends Node

@onready var MainMenu = $CanvasLayer
@onready var IPAddressEntry = $CanvasLayer/MainMenu/MarginContainer/VBoxContainer/IPAddressEntry

const Player = preload("res://Prefabs/Player.tscn")
const PORT = 4433
var enet_peer = ENetMultiplayerPeer.new()
var name_tag : String

func _ready():
	var id = ResourceLoader.get_resource_uid(Player.resource_path)

func _unhandled_input(event):
	if Input.is_action_just_pressed("quit"):
		get_tree().quit()


func _on_play_btn_pressed():
	MainMenu.hide()
	name_tag = $CanvasLayer/MainMenu/MarginContainer/VBoxContainer/NameEntry.text
	
	enet_peer.create_server(PORT)
	multiplayer.multiplayer_peer = enet_peer
	multiplayer.peer_connected.connect(add_player)
	multiplayer.peer_disconnected.connect(remove_player)
	
	add_player(multiplayer.get_unique_id())
	
	upnp_setup()


func _on_connect_btn_pressed():
	MainMenu.hide()
	rpc("set_peer_name_tag", $CanvasLayer/MainMenu/MarginContainer/VBoxContainer/NameEntry.text)
	
	enet_peer.create_client(IPAddressEntry.text, PORT)
	multiplayer.multiplayer_peer = enet_peer

func add_player(peer_id):
	var player = Player.instantiate()
	player.name = str(peer_id)
	GameManager.NameTagsDict[str(peer_id)] = name_tag
	print("Server ID %s Name %s" % [peer_id, name_tag])
	add_child(player)

func remove_player(peer_id):
	var player = get_node_or_null(str(peer_id))
	if player:
		player.queue_free()

@rpc("any_peer")
func set_peer_name_tag(new_name_tag):
	name_tag = new_name_tag

@rpc("call_remote")
func get_name_tag(id) -> String:
	return str(GameManager.NameTagsDict[id])

func upnp_setup():
	var upnp = UPNP.new()
	
	var discover_result = upnp.discover()
	assert(discover_result == UPNP.UPNP_RESULT_SUCCESS, "UPNP Discover Failed! Error %s" % discover_result)
	
	assert(upnp.get_gateway() and upnp.get_gateway().is_valid_gateway(), "UPNP Invalid Gateway!")
	
	var map_result = upnp.add_port_mapping(PORT)
	assert(map_result == UPNP.UPNP_RESULT_SUCCESS, "UPNP Port Mapping Failed! Error %s" % map_result)
	
	print("Success! Join Address: %s" %upnp.query_external_address())

Player.gd

extends CharacterBody3D


var SPEED = 5.0
const JUMP_VELOCITY = 4.5
var SENSITIVITY = 5.0

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
@onready var CamPivot = $CamPivot
@onready var PlayerCam = $CamPivot/PlayerCam

@export var player_name = "Player"

func _enter_tree():
	set_multiplayer_authority(str(name).to_int())

func _ready():
	if not is_multiplayer_authority(): return
	
	if name != "1":
		player_name = str(rpc("get_name_tag", name))
	else:
		player_name = GameManager.NameTagsDict[name]
	
	print("Player ID %s Name %s" % [name, player_name])
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	PlayerCam.current = true

func _unhandled_input(event):
	if not is_multiplayer_authority(): return
	if event is InputEventMouseButton:
		Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	elif event.is_action_pressed("ui_cancel"):
		Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
	if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
		if event is InputEventMouseMotion:
			rotation.y -= event.relative.x * SENSITIVITY * 0.001
			PlayerCam.rotation.x = clamp(PlayerCam.rotation.x - event.relative.y * SENSITIVITY * 0.001, deg_to_rad(-90), deg_to_rad(90))

func _physics_process(delta):
	if not is_multiplayer_authority(): return
	
	# Add the gravity.
	if not is_on_floor():
		velocity.y -= gravity * delta

	# Handle Jump.
	if Input.is_action_just_pressed("jump") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir = Input.get_vector("left", "right", "forward", "back")
	var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
	if direction:
		velocity.x = direction.x * SPEED
		velocity.z = direction.z * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		velocity.z = move_toward(velocity.z, 0, SPEED)

	move_and_slide()

func _process(delta):
	get_node("NameTag").text = str(player_name)

Sorry for the mess, been trying to debug this code for several hours now, and been trying mutliple methods and just trying to get it to work, any help would be appreciated.