parent
a55e64b73f
commit
94704798a5
13 changed files with 180 additions and 54 deletions
@ -0,0 +1,9 @@ |
||||
public partial class Game : Node |
||||
{ |
||||
[Export] public Player LocalPlayer { get; set; } |
||||
|
||||
public MultiplayerManager MultiplayerManager { get; private set; } |
||||
|
||||
public override void _EnterTree() |
||||
=> MultiplayerManager = GetNode<MultiplayerManager>("MultiplayerManager"); |
||||
} |
@ -0,0 +1,12 @@ |
||||
public partial class Synchronizer : MultiplayerSynchronizer |
||||
{ |
||||
// Required because `Velocity` can't be synchronized automatically. |
||||
[Export] public Vector3 PlayerVelocity { |
||||
get => _player.Velocity; |
||||
set => _player.Velocity = value; |
||||
} |
||||
|
||||
Player _player; |
||||
public override void _Ready() |
||||
=> _player = GetParent<Player>(); |
||||
} |
@ -0,0 +1,81 @@ |
||||
public partial class MultiplayerManager : Node |
||||
{ |
||||
[Export] public Player LocalPlayer { get; set; } |
||||
[Export] public Node3D Players { get; set; } |
||||
[Export] public PackedScene PlayerScene { get; set; } |
||||
|
||||
public event Action<Player> PlayerJoined; |
||||
public event Action<Player> PlayerLeft; |
||||
|
||||
public override void _Ready() |
||||
{ |
||||
Multiplayer.ConnectedToServer += OnMultiplayerReady; |
||||
Multiplayer.ServerDisconnected += OnMultiplayerDisconnected; |
||||
Multiplayer.PeerConnected += OnPeerConnected; |
||||
Multiplayer.PeerDisconnected += OnPeerDisconnected; |
||||
} |
||||
|
||||
|
||||
public void Connect(string address, ushort port) |
||||
{ |
||||
var peer = new ENetMultiplayerPeer(); |
||||
peer.CreateClient(address, port); |
||||
Multiplayer.MultiplayerPeer = peer; |
||||
} |
||||
|
||||
public bool CreateServer(ushort port) |
||||
{ |
||||
var peer = new ENetMultiplayerPeer(); |
||||
if (peer.CreateServer(port) == Error.Ok) { |
||||
Multiplayer.MultiplayerPeer = peer; |
||||
OnMultiplayerReady(); |
||||
return true; |
||||
} else |
||||
return false; |
||||
} |
||||
|
||||
public void Disconnect() |
||||
=> OnMultiplayerDisconnected(); |
||||
|
||||
|
||||
void OnMultiplayerReady() |
||||
{ |
||||
var localId = Multiplayer.GetUniqueId(); |
||||
LocalPlayer.Name = localId.ToString(); |
||||
LocalPlayer.SetMultiplayerAuthority(localId); |
||||
|
||||
if (!Multiplayer.IsServer()) |
||||
// Spawn players for all the other peers. This excludes the server, |
||||
// since `OnPeerConnected` will already be called for it on connecting. |
||||
foreach (var peerId in Multiplayer.GetPeers()) |
||||
if (peerId != 1) OnPeerConnected(peerId); |
||||
} |
||||
|
||||
void OnMultiplayerDisconnected() |
||||
{ |
||||
LocalPlayer.Name = "Local"; |
||||
foreach (var player in Players.GetChildren().Cast<Player>()) |
||||
OnPeerDisconnected(player.PeerId); |
||||
Multiplayer.MultiplayerPeer.Close(); |
||||
Multiplayer.MultiplayerPeer = null; |
||||
} |
||||
|
||||
|
||||
void OnPeerConnected(long peerId) |
||||
{ |
||||
var player = PlayerScene.Instantiate<Player>(); |
||||
player.SetMultiplayerAuthority((int)peerId); |
||||
player.Name = peerId.ToString(); |
||||
player.IsLocal = false; |
||||
player.PeerId = (int)peerId; |
||||
Players.AddChild(player); |
||||
PlayerJoined?.Invoke(player); |
||||
} |
||||
|
||||
void OnPeerDisconnected(long peerId) |
||||
{ |
||||
var player = Players.GetNode<Player>(peerId.ToString()); |
||||
PlayerLeft?.Invoke(player); |
||||
player.QueueFree(); |
||||
} |
||||
} |
Loading…
Reference in new issue