您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
93 行
3.5 KiB
93 行
3.5 KiB
using System;
|
|
using Unity.Collections;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
|
|
namespace Unity.Multiplayer.Samples.BossRoom.Shared.Infrastructure
|
|
{
|
|
/// <summary>
|
|
/// This type of message channel allows the server to publish a message that will be sent to clients as well as
|
|
/// being published locally. Clients and the server both can subscribe to it. However, that subscription needs to be
|
|
/// done after the NetworkManager has initialized. On objects whose lifetime is bigger than a networked session,
|
|
/// subscribing will be required each time a new session starts.
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
public class NetworkedMessageChannel<T> : MessageChannel<T> where T : unmanaged, INetworkSerializeByMemcpy
|
|
{
|
|
string m_Name;
|
|
|
|
bool m_HasRegisteredHandler;
|
|
|
|
public NetworkedMessageChannel()
|
|
{
|
|
m_Name = $"{typeof(T).FullName}NetworkMessageChannel";
|
|
}
|
|
|
|
public override void Dispose()
|
|
{
|
|
if (!IsDisposed)
|
|
{
|
|
if (NetworkManager.Singleton != null && NetworkManager.Singleton.CustomMessagingManager != null && m_HasRegisteredHandler)
|
|
{
|
|
NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler(m_Name);
|
|
}
|
|
|
|
m_HasRegisteredHandler = false;
|
|
}
|
|
base.Dispose();
|
|
}
|
|
|
|
public override IDisposable Subscribe(Action<T> handler)
|
|
{
|
|
if (NetworkManager.Singleton != null && NetworkManager.Singleton.IsListening)
|
|
{
|
|
// Only register message handler on clients
|
|
if (!m_HasRegisteredHandler && !NetworkManager.Singleton.IsServer)
|
|
{
|
|
NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(m_Name, ReceiveMessageThroughNetwork);
|
|
m_HasRegisteredHandler = true;
|
|
NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnect;
|
|
}
|
|
|
|
return base.Subscribe(handler);
|
|
}
|
|
|
|
Debug.LogError("Cannot subscribe to NetworkedMessageChannel. NetworkManager is not initialized.");
|
|
return null;
|
|
}
|
|
|
|
void OnClientDisconnect(ulong clientId)
|
|
{
|
|
m_HasRegisteredHandler = false;
|
|
NetworkManager.Singleton.OnClientConnectedCallback -= OnClientDisconnect;
|
|
NetworkManager.Singleton.CustomMessagingManager.UnregisterNamedMessageHandler(m_Name);
|
|
}
|
|
|
|
public override void Publish(T message)
|
|
{
|
|
if (NetworkManager.Singleton.IsServer)
|
|
{
|
|
// send message to clients, then publish locally
|
|
SendMessageThroughNetwork(message);
|
|
base.Publish(message);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("Only a server can publish in a NetworkedMessageChannel");
|
|
}
|
|
}
|
|
|
|
void SendMessageThroughNetwork(T message)
|
|
{
|
|
var writer = new FastBufferWriter(FastBufferWriter.GetWriteSize<T>(), Allocator.Temp);
|
|
writer.WriteValueSafe(message);
|
|
NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(m_Name, writer);
|
|
}
|
|
|
|
void ReceiveMessageThroughNetwork(ulong clientID, FastBufferReader reader)
|
|
{
|
|
reader.ReadValueSafe(out T message);
|
|
base.Publish(message);
|
|
}
|
|
}
|
|
}
|