I'm trying to make an ordinary multiplayer FPS. I use a second Camera3D and a SubViewport to avoid player's gun clipping into the wall: enter image description here
Both cameras' cull masks set up the way that everything works fine until the other player hasn't connected.
As another player connects to a host, every player get an extra gun rendered on their screen: enter image description here Apparently it's happening because every new connection instantiates a new player, hence there's another viewport in the world which adds up everything it has to render to players' screens. Also if I remove the whole SubViewportContainer, guns don't render in the wrong places anymore, only in other players' hands, but now they're clipping into the walls.
Here's my world script that handles connections:
extends Node
@onready var main_menu = $CanvasLayer/Menu
@onready var address_entry = $CanvasLayer/Menu/MarginContainer/VBoxContainer/AddressEntry
const Player = preload("res://scenes/Player.tscn")
const PORT = 8899
var enet_peer = ENetMultiplayerPeer.new()
func _unhandled_input(event):
if Input.is_action_just_pressed("exit"):
get_tree().quit()
func _on_host_pressed():
main_menu.hide()
enet_peer.create_server(PORT)
multiplayer.multiplayer_peer = enet_peer
multiplayer.peer_connected.connect(add_player)
add_player(multiplayer.get_unique_id())
func _on_join_pressed():
main_menu.hide()
enet_peer.create_client(address_entry.text, PORT)
multiplayer.multiplayer_peer = enet_peer
func add_player(peer_id):
var player = Player.instantiate()
player.name = str(peer_id)
add_child(player)
This seems like a common task but still I couldn't manage to find any Godot 4 solution on the Internet.
I have tried to change pistol's model meshes' VisualInstance3D layer while instantiating a new player on a new connection, but this doesn't really make any sense as every players' guns VisualInstance3D layers are the same anyway. And since the model isn't made very well and has many meshes it just hurts to see the code:
func add_player(peer_id):
var player = Player.instantiate()
var glock_body = player.get_node("Camera/Camera3D/toy_glock_lowpoly_w_bevel/glock_body")
var glock_slide = player.get_node("Camera/Camera3D/toy_glock_lowpoly_w_bevel/glock_slide")
var glock_barrel = player.get_node("Camera/Camera3D/toy_glock_lowpoly_w_bevel/glock_barrel")
var glock_trigger = player.get_node("Camera/Camera3D/toy_glock_lowpoly_w_bevel/glock_trigger")
var glock_magazine = player.get_node("Camera/Camera3D/toy_glock_lowpoly_w_bevel/glock_magazine")
var glock_ammo_shell = player.get_node("Camera/Camera3D/toy_glock_lowpoly_w_bevel/glock_ammo_shell")
glock_body.set_layer_mask(3)
glock_slide.set_layer_mask(3)
glock_barrel.set_layer_mask(3)
glock_trigger.set_layer_mask(3)
glock_magazine.set_layer_mask(3)
glock_ammo_shell.set_layer_mask(3)
player.name = str(peer_id)
add_child(player)