netfishing/network/player_spawn_service.gd

103 lines
2.7 KiB
GDScript3
Raw Permalink Normal View History

class_name PlayerSpawnService
extends Node
const PlayerScene: PackedScene = preload("res://player/player.tscn")
signal avatar_spawned(peer_id: int, avatar: Player)
signal avatar_removed(peer_id: int)
var _players_root: Node3D
var _local_player: Player
var _spawn_transform: Transform3D
var _avatars: Dictionary[int, Player] = {}
var _local_peer_id: int = 1
func setup(
players_root: Node3D,
local_player: Player,
spawn_transform: Transform3D,
) -> void:
_players_root = players_root
_local_player = local_player
_spawn_transform = spawn_transform
func register_local_player(peer_id: int) -> void:
if _local_player == null:
return
for existing_id: int in _avatars.keys():
if _avatars[existing_id] == _local_player:
_avatars.erase(existing_id)
_local_peer_id = peer_id
_avatars[peer_id] = _local_player
_local_player.name = "Player_%d" % peer_id
_local_player.set_local_control(true)
_local_player.set_network_peer_id(peer_id)
func spawn_remote_player(
peer_id: int,
transform: Transform3D,
authoritative_simulation: bool = false,
) -> Player:
if peer_id <= 0 or peer_id == _local_peer_id:
return null
var existing: Player = _avatars.get(peer_id)
if existing != null and is_instance_valid(existing):
return existing
var avatar := PlayerScene.instantiate() as Player
avatar.name = "Player_%d" % peer_id
avatar.set_local_control(false)
avatar.set_network_peer_id(peer_id)
_players_root.add_child(avatar)
avatar.global_transform = transform
avatar.configure_network_remote(authoritative_simulation)
_avatars[peer_id] = avatar
avatar_spawned.emit(peer_id, avatar)
return avatar
func remove_peer(peer_id: int) -> void:
if peer_id == _local_peer_id:
return
var avatar: Player = _avatars.get(peer_id)
_avatars.erase(peer_id)
if avatar != null and is_instance_valid(avatar):
avatar.queue_free()
avatar_removed.emit(peer_id)
func clear_remote_players() -> void:
for peer_id: int in _avatars.keys():
if peer_id != _local_peer_id:
remove_peer(peer_id)
func get_avatar(peer_id: int) -> Player:
return _avatars.get(peer_id)
func set_peer_presentation_visible(peer_id: int, should_be_visible: bool) -> void:
2026-07-29 23:10:51 -04:00
var avatar: Player = _avatars.get(peer_id)
if avatar != null and is_instance_valid(avatar):
avatar.set_remote_presentation_visible(should_be_visible)
2026-07-29 23:10:51 -04:00
func get_peer_ids() -> Array[int]:
var result: Array[int] = []
for peer_id: int in _avatars:
result.append(peer_id)
result.sort()
return result
func get_spawn_transform_for_index(index: int) -> Transform3D:
if index <= 0:
return _spawn_transform
var angle: float = float(index) * 2.3999632297
var ring: float = 1.4 + floor(float(index - 1) / 8.0) * 1.2
var result: Transform3D = _spawn_transform
result.origin += Vector3(cos(angle) * ring, 0.0, sin(angle) * ring)
return result