removed dissonance integration
parent
260cd891db
commit
96e3e762eb
|
|
@ -11,6 +11,7 @@ namespace VelNet
|
||||||
{
|
{
|
||||||
[Header("NetworkObject properties")]
|
[Header("NetworkObject properties")]
|
||||||
public VelNetPlayer owner;
|
public VelNetPlayer owner;
|
||||||
|
[Tooltip("Whether this object's ownership is transferrable. Should be true for player objects.")]
|
||||||
public bool ownershipLocked;
|
public bool ownershipLocked;
|
||||||
public bool IsMine => owner != null && owner.isLocal;
|
public bool IsMine => owner != null && owner.isLocal;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,8 +46,7 @@ namespace VelNet
|
||||||
public List<string> deletedSceneObjects = new List<string>();
|
public List<string> deletedSceneObjects = new List<string>();
|
||||||
public readonly Dictionary<string, NetworkObject> objects = new Dictionary<string, NetworkObject>(); //maintains a list of all known objects on the server (ones that have ids)
|
public readonly Dictionary<string, NetworkObject> objects = new Dictionary<string, NetworkObject>(); //maintains a list of all known objects on the server (ones that have ids)
|
||||||
private VelNetPlayer masterPlayer;
|
private VelNetPlayer masterPlayer;
|
||||||
public static VelNetPlayer LocalPlayer => instance.players.Where(p => p.Value.isLocal).Select(p=>p.Value).FirstOrDefault();
|
public static VelNetPlayer LocalPlayer => instance.players.Where(p => p.Value.isLocal).Select(p => p.Value).FirstOrDefault();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Use this for initialization
|
// Use this for initialization
|
||||||
|
|
@ -156,7 +155,7 @@ namespace VelNet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this may check for ownership in the future. We don't need ownership here
|
// TODO this may check for ownership in the future. We don't need ownership here
|
||||||
deleteObjects.ForEach(DeleteNetworkObject);
|
deleteObjects.ForEach(DeleteNetworkObject);
|
||||||
|
|
||||||
|
|
@ -436,24 +435,24 @@ namespace VelNet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SendUdpMessage(string message)
|
private static void SendUdpMessage(string message)
|
||||||
{
|
{
|
||||||
if (udpSocket == null || !udpConnected)
|
if (instance.udpSocket == null || !instance.udpConnected)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] data = Encoding.UTF8.GetBytes(message);
|
byte[] data = Encoding.UTF8.GetBytes(message);
|
||||||
//Debug.Log("Attempting to send: " + message);
|
//Debug.Log("Attempting to send: " + message);
|
||||||
udpSocket.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint);
|
instance.udpSocket.SendTo(data, data.Length, SocketFlags.None, instance.RemoteEndPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send message to server using socket connection.
|
/// Send message to server using socket connection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void SendNetworkMessage(string clientMessage)
|
private static void SendNetworkMessage(string clientMessage)
|
||||||
{
|
{
|
||||||
if (socketConnection == null)
|
if (instance.socketConnection == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -461,7 +460,7 @@ namespace VelNet
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Get a stream object for writing.
|
// Get a stream object for writing.
|
||||||
NetworkStream stream = socketConnection.GetStream();
|
NetworkStream stream = instance.socketConnection.GetStream();
|
||||||
if (stream.CanWrite)
|
if (stream.CanWrite)
|
||||||
{
|
{
|
||||||
// Convert string message to byte array.
|
// Convert string message to byte array.
|
||||||
|
|
@ -477,22 +476,22 @@ namespace VelNet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Login(string username, string password)
|
public static void Login(string username, string password)
|
||||||
{
|
{
|
||||||
SendNetworkMessage("0:" + username + ":" + password);
|
SendNetworkMessage("0:" + username + ":" + password);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Join(string roomname)
|
public static void Join(string roomname)
|
||||||
{
|
{
|
||||||
SendNetworkMessage("2:" + roomname);
|
SendNetworkMessage("2:" + roomname);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Leave()
|
public static void Leave()
|
||||||
{
|
{
|
||||||
SendNetworkMessage("2:-1");
|
SendNetworkMessage("2:-1");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendTo(MessageType type, string message, bool reliable = true)
|
public static void SendTo(MessageType type, string message, bool reliable = true)
|
||||||
{
|
{
|
||||||
if (reliable)
|
if (reliable)
|
||||||
{
|
{
|
||||||
|
|
@ -500,11 +499,11 @@ namespace VelNet
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SendUdpMessage(userid + ":3:" + (int)type + ":" + message);
|
SendUdpMessage(instance.userid + ":3:" + (int)type + ":" + message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendToGroup(string group, string message, bool reliable = true)
|
public static void SendToGroup(string group, string message, bool reliable = true)
|
||||||
{
|
{
|
||||||
if (reliable)
|
if (reliable)
|
||||||
{
|
{
|
||||||
|
|
@ -512,19 +511,19 @@ namespace VelNet
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SendUdpMessage(userid + ":4:" + group + ":" + message);
|
SendUdpMessage(instance.userid + ":4:" + group + ":" + message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// changes the designated group that sendto(4) will go to
|
/// changes the designated group that sendto(4) will go to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetupMessageGroup(string groupName, IEnumerable<int> userIds)
|
public static void SetupMessageGroup(string groupName, IEnumerable<int> userIds)
|
||||||
{
|
{
|
||||||
SendNetworkMessage($"5:{groupName}:{string.Join(":", userIds)}");
|
SendNetworkMessage($"5:{groupName}:{string.Join(":", userIds)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void InstantiateNetworkObject(string prefabName)
|
public static void InstantiateNetworkObject(string prefabName)
|
||||||
{
|
{
|
||||||
VelNetPlayer localPlayer = LocalPlayer;
|
VelNetPlayer localPlayer = LocalPlayer;
|
||||||
|
|
@ -534,14 +533,15 @@ namespace VelNet
|
||||||
Debug.LogError("Couldn't find a prefab with that name: " + prefabName);
|
Debug.LogError("Couldn't find a prefab with that name: " + prefabName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkObject newObject = Instantiate(prefab);
|
NetworkObject newObject = Instantiate(prefab);
|
||||||
newObject.networkId = localPlayer.userid + "-" + localPlayer.lastObjectId++;;
|
newObject.networkId = localPlayer.userid + "-" + localPlayer.lastObjectId++;
|
||||||
newObject.prefabName = prefabName;
|
newObject.prefabName = prefabName;
|
||||||
newObject.owner = localPlayer;
|
newObject.owner = localPlayer;
|
||||||
instance.objects.Add(newObject.networkId, newObject);
|
instance.objects.Add(newObject.networkId, newObject);
|
||||||
|
|
||||||
// only sent to others, as I already instantiated this. Nice that it happens immediately.
|
// only sent to others, as I already instantiated this. Nice that it happens immediately.
|
||||||
instance.SendTo(MessageType.OTHERS, "7," + newObject.networkId + "," + prefabName);
|
SendTo(MessageType.OTHERS, "7," + newObject.networkId + "," + prefabName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SomebodyInstantiatedNetworkObject(string networkId, string prefabName, VelNetPlayer owner)
|
public static void SomebodyInstantiatedNetworkObject(string networkId, string prefabName, VelNetPlayer owner)
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ namespace VelNet
|
||||||
{
|
{
|
||||||
if (kvp.Value.owner == this && kvp.Value.prefabName != "")
|
if (kvp.Value.owner == this && kvp.Value.prefabName != "")
|
||||||
{
|
{
|
||||||
manager.SendTo(VelNetManager.MessageType.OTHERS, "7," + kvp.Value.networkId + "," + kvp.Value.prefabName);
|
VelNetManager.SendTo(VelNetManager.MessageType.OTHERS, "7," + kvp.Value.networkId + "," + kvp.Value.prefabName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,12 +138,12 @@ namespace VelNet
|
||||||
|
|
||||||
public void SendGroupMessage(NetworkObject obj, string group, string identifier, byte[] data, bool reliable = true)
|
public void SendGroupMessage(NetworkObject obj, string group, string identifier, byte[] data, bool reliable = true)
|
||||||
{
|
{
|
||||||
manager.SendToGroup(group, "5," + obj.networkId + "," + identifier + "," + Convert.ToBase64String(data), reliable);
|
VelNetManager.SendToGroup(group, "5," + obj.networkId + "," + identifier + "," + Convert.ToBase64String(data), reliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendMessage(NetworkObject obj, string identifier, byte[] data, bool reliable = true)
|
public void SendMessage(NetworkObject obj, string identifier, byte[] data, bool reliable = true)
|
||||||
{
|
{
|
||||||
manager.SendTo(VelNetManager.MessageType.OTHERS, "5," + obj.networkId + "," + identifier + "," + Convert.ToBase64String(data), reliable);
|
VelNetManager.SendTo(VelNetManager.MessageType.OTHERS, "5," + obj.networkId + "," + identifier + "," + Convert.ToBase64String(data), reliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -155,7 +155,7 @@ namespace VelNet
|
||||||
if (!manager.objects.ContainsKey(networkId) || manager.objects[networkId].owner != this || !isLocal) return;
|
if (!manager.objects.ContainsKey(networkId) || manager.objects[networkId].owner != this || !isLocal) return;
|
||||||
|
|
||||||
// send to all, which will make me delete as well
|
// send to all, which will make me delete as well
|
||||||
manager.SendTo(VelNetManager.MessageType.ALL_ORDERED, "8," + networkId);
|
VelNetManager.SendTo(VelNetManager.MessageType.ALL_ORDERED, "8," + networkId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -174,14 +174,14 @@ namespace VelNet
|
||||||
manager.objects[networkId].owner = this;
|
manager.objects[networkId].owner = this;
|
||||||
|
|
||||||
// must be ordered, so that ownership transfers are not confused. Also sent to all players, so that multiple simultaneous requests will result in the same outcome.
|
// must be ordered, so that ownership transfers are not confused. Also sent to all players, so that multiple simultaneous requests will result in the same outcome.
|
||||||
manager.SendTo(VelNetManager.MessageType.ALL_ORDERED, "6," + networkId);
|
VelNetManager.SendTo(VelNetManager.MessageType.ALL_ORDERED, "6," + networkId);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendSceneUpdate()
|
public void SendSceneUpdate()
|
||||||
{
|
{
|
||||||
manager.SendTo(VelNetManager.MessageType.OTHERS, "9," + string.Join(",", manager.deletedSceneObjects));
|
VelNetManager.SendTo(VelNetManager.MessageType.OTHERS, "9," + string.Join(",", manager.deletedSceneObjects));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
%YAML 1.1
|
|
||||||
%TAG !u! tag:unity3d.com,2011:
|
|
||||||
--- !u!244 &-1719467165466355418
|
|
||||||
AudioMixerEffectController:
|
|
||||||
m_ObjectHideFlags: 3
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name:
|
|
||||||
m_EffectID: 6362d3ceb713f4c3fa42448a3e29217e
|
|
||||||
m_EffectName: Dissonance Echo Cancellation
|
|
||||||
m_MixLevel: a240a2d1f057e4cf9bbc59f6cfbec367
|
|
||||||
m_Parameters: []
|
|
||||||
m_SendTarget: {fileID: 0}
|
|
||||||
m_EnableWetMix: 0
|
|
||||||
m_Bypass: 0
|
|
||||||
--- !u!241 &24100000
|
|
||||||
AudioMixerController:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: VelAudioMixer
|
|
||||||
m_OutputGroup: {fileID: 0}
|
|
||||||
m_MasterGroup: {fileID: 24300002}
|
|
||||||
m_Snapshots:
|
|
||||||
- {fileID: 24500006}
|
|
||||||
m_StartSnapshot: {fileID: 24500006}
|
|
||||||
m_SuspendThreshold: -80
|
|
||||||
m_EnableSuspend: 1
|
|
||||||
m_UpdateMode: 1
|
|
||||||
m_ExposedParameters: []
|
|
||||||
m_AudioMixerGroupViews:
|
|
||||||
- guids:
|
|
||||||
- b8e40716c8c1442ab9ef14e149b2423c
|
|
||||||
name: View
|
|
||||||
m_CurrentViewIndex: 0
|
|
||||||
m_TargetSnapshot: {fileID: 24500006}
|
|
||||||
--- !u!243 &24300002
|
|
||||||
AudioMixerGroupController:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: Master
|
|
||||||
m_AudioMixer: {fileID: 24100000}
|
|
||||||
m_GroupID: b8e40716c8c1442ab9ef14e149b2423c
|
|
||||||
m_Children: []
|
|
||||||
m_Volume: 3d9590ea0314643bd94e1616b88508ef
|
|
||||||
m_Pitch: 31f1ddadf3a5d47caab0e64b81ced2ae
|
|
||||||
m_Send: 00000000000000000000000000000000
|
|
||||||
m_Effects:
|
|
||||||
- {fileID: 24400004}
|
|
||||||
- {fileID: -1719467165466355418}
|
|
||||||
m_UserColorIndex: 0
|
|
||||||
m_Mute: 0
|
|
||||||
m_Solo: 0
|
|
||||||
m_BypassEffects: 0
|
|
||||||
--- !u!244 &24400004
|
|
||||||
AudioMixerEffectController:
|
|
||||||
m_ObjectHideFlags: 3
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name:
|
|
||||||
m_EffectID: f79719d1f394d4b4783ede937d403602
|
|
||||||
m_EffectName: Attenuation
|
|
||||||
m_MixLevel: 8d97d9fd1e8d446eb9244b5dead78e90
|
|
||||||
m_Parameters: []
|
|
||||||
m_SendTarget: {fileID: 0}
|
|
||||||
m_EnableWetMix: 0
|
|
||||||
m_Bypass: 0
|
|
||||||
--- !u!245 &24500006
|
|
||||||
AudioMixerSnapshotController:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_Name: Snapshot
|
|
||||||
m_AudioMixer: {fileID: 24100000}
|
|
||||||
m_SnapshotID: 86ea5b9fedb76448594a5ab2119e34a1
|
|
||||||
m_FloatValues: {}
|
|
||||||
m_TransitionOverrides: {}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: fa1da19d935e241119cdd522ceae772c
|
|
||||||
NativeFormatImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
mainObjectFileID: 24100000
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
||||||
using System;
|
|
||||||
using Dissonance;
|
|
||||||
using Dissonance.Networking;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Serialization;
|
|
||||||
|
|
||||||
|
|
||||||
namespace VelNet
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Added to the same object as DissonanceComms component. Only one in the scene.
|
|
||||||
/// </summary>
|
|
||||||
[RequireComponent(typeof(DissonanceComms))]
|
|
||||||
[AddComponentMenu("VelNet/Dissonance/VelNet Comms Network")]
|
|
||||||
public class VelCommsNetwork : MonoBehaviour, ICommsNetwork
|
|
||||||
{
|
|
||||||
public ConnectionStatus Status => manager.connected ? ConnectionStatus.Connected : ConnectionStatus.Disconnected;
|
|
||||||
public NetworkMode Mode => NetworkMode.Client;
|
|
||||||
|
|
||||||
public event Action<NetworkMode> ModeChanged;
|
|
||||||
public event Action<string, CodecSettings> PlayerJoined;
|
|
||||||
public event Action<string> PlayerLeft;
|
|
||||||
public event Action<VoicePacket> VoicePacketReceived;
|
|
||||||
public event Action<TextMessage> TextPacketReceived;
|
|
||||||
public event Action<string> PlayerStartedSpeaking;
|
|
||||||
public event Action<string> PlayerStoppedSpeaking;
|
|
||||||
public event Action<RoomEvent> PlayerEnteredRoom;
|
|
||||||
public event Action<RoomEvent> PlayerExitedRoom;
|
|
||||||
|
|
||||||
private ConnectionStatus _status = ConnectionStatus.Disconnected;
|
|
||||||
private CodecSettings initSettings;
|
|
||||||
public string dissonanceId;
|
|
||||||
[HideInInspector] public DissonanceComms dissonanceComms;
|
|
||||||
private VelNetManager manager;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// listen to this if you want to send voice
|
|
||||||
/// </summary>
|
|
||||||
public Action<ArraySegment<byte>> VoiceQueued;
|
|
||||||
|
|
||||||
|
|
||||||
// Start is called before the first frame update
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
_status = ConnectionStatus.Connected;
|
|
||||||
dissonanceComms = GetComponent<DissonanceComms>();
|
|
||||||
manager = VelNetManager.instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialize(string playerName, Rooms rooms, PlayerChannels playerChannels, RoomChannels roomChannels, CodecSettings codecSettings)
|
|
||||||
{
|
|
||||||
dissonanceId = playerName;
|
|
||||||
initSettings = codecSettings;
|
|
||||||
dissonanceComms.ResetMicrophoneCapture();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void VoiceReceived(string sender, byte[] data)
|
|
||||||
{
|
|
||||||
uint sequenceNumber = BitConverter.ToUInt32(data, 0);
|
|
||||||
VoicePacket vp = new VoicePacket(sender, ChannelPriority.Default, 1, true, new ArraySegment<byte>(data, 4, data.Length - 4), sequenceNumber);
|
|
||||||
VoicePacketReceived?.Invoke(vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendText(string data, ChannelType recipientType, string recipientId)
|
|
||||||
{
|
|
||||||
Debug.Log("sending text");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendVoice(ArraySegment<byte> data)
|
|
||||||
{
|
|
||||||
VoiceQueued?.Invoke(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetPlayerJoined(string id)
|
|
||||||
{
|
|
||||||
Debug.Log("Dissonance player joined");
|
|
||||||
PlayerJoined?.Invoke(id, initSettings);
|
|
||||||
RoomEvent re = new RoomEvent
|
|
||||||
{
|
|
||||||
Joined = true,
|
|
||||||
Room = "Global",
|
|
||||||
PlayerName = id
|
|
||||||
};
|
|
||||||
PlayerEnteredRoom?.Invoke(re);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetPlayerLeft(string id)
|
|
||||||
{
|
|
||||||
RoomEvent re = new RoomEvent
|
|
||||||
{
|
|
||||||
Joined = false,
|
|
||||||
Room = "Global",
|
|
||||||
PlayerName = id
|
|
||||||
};
|
|
||||||
PlayerExitedRoom?.Invoke(re);
|
|
||||||
// only send this event for non-local players
|
|
||||||
if (id != dissonanceId) PlayerLeft?.Invoke(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetPlayerStartedSpeaking(string id)
|
|
||||||
{
|
|
||||||
PlayerStartedSpeaking?.Invoke(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetPlayerStoppedSpeaking(string id)
|
|
||||||
{
|
|
||||||
PlayerStoppedSpeaking?.Invoke(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: 5d2009d8e264649749c0315d48765749
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
|
|
@ -1,251 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Dissonance;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace VelNet
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This should be added to your player object
|
|
||||||
/// </summary>
|
|
||||||
[AddComponentMenu("VelNet/Dissonance/VelNet Dissonance Player")]
|
|
||||||
public class VelNetDissonancePlayer : NetworkComponent, IDissonancePlayer
|
|
||||||
{
|
|
||||||
private VelCommsNetwork comms;
|
|
||||||
private bool isSpeaking;
|
|
||||||
private uint lastAudioId;
|
|
||||||
|
|
||||||
[Header("VelNet Dissonance Player Properties")]
|
|
||||||
public string dissonanceID = "";
|
|
||||||
|
|
||||||
//required by dissonance for spatial audio
|
|
||||||
public string PlayerId => dissonanceID;
|
|
||||||
public Vector3 Position => transform.position;
|
|
||||||
public Quaternion Rotation => transform.rotation;
|
|
||||||
public NetworkPlayerType Type => IsMine ? NetworkPlayerType.Local : NetworkPlayerType.Remote;
|
|
||||||
public bool IsTracking => true;
|
|
||||||
|
|
||||||
private static readonly List<VelNetDissonancePlayer> allPlayers = new List<VelNetDissonancePlayer>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only sends voice data to players in this list
|
|
||||||
/// </summary>
|
|
||||||
public List<int> closePlayers = new List<int>();
|
|
||||||
|
|
||||||
[Tooltip("Maximum distance to transmit voice data. 0 to always send voice to all players.")]
|
|
||||||
public float maxDistance;
|
|
||||||
|
|
||||||
private enum MessageType : byte
|
|
||||||
{
|
|
||||||
AudioData,
|
|
||||||
DissonanceId,
|
|
||||||
SpeakingState
|
|
||||||
}
|
|
||||||
|
|
||||||
// This object should not be in the scene at the start.
|
|
||||||
private void Awake()
|
|
||||||
{
|
|
||||||
comms = FindObjectOfType<VelCommsNetwork>();
|
|
||||||
if (comms == null)
|
|
||||||
{
|
|
||||||
Debug.LogError("No VelCommsNetwork found. Make sure there is one in your scene.", this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEnable()
|
|
||||||
{
|
|
||||||
// add ourselves to the global list of all players in the scene
|
|
||||||
if (!allPlayers.Contains(this))
|
|
||||||
{
|
|
||||||
allPlayers.Add(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogError("We're already in the player list 🐭", this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDisable()
|
|
||||||
{
|
|
||||||
// remove ourselves from the global list of all players in the scene
|
|
||||||
allPlayers.Remove(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Start()
|
|
||||||
{
|
|
||||||
if (IsMine)
|
|
||||||
{
|
|
||||||
SetDissonanceID(comms.dissonanceId);
|
|
||||||
comms.VoiceQueued += SendVoiceData;
|
|
||||||
|
|
||||||
//we also need to know when other players join, so we can send the dissonance ID again
|
|
||||||
|
|
||||||
VelNetManager.instance.OnPlayerJoined += (player) =>
|
|
||||||
{
|
|
||||||
using MemoryStream mem = new MemoryStream();
|
|
||||||
using BinaryWriter writer = new BinaryWriter(mem);
|
|
||||||
writer.Write((byte)MessageType.DissonanceId);
|
|
||||||
writer.Write(dissonanceID);
|
|
||||||
SendBytes(mem.ToArray());
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SendVoiceData(ArraySegment<byte> data)
|
|
||||||
{
|
|
||||||
// need to send it
|
|
||||||
if (!IsMine) return;
|
|
||||||
|
|
||||||
using MemoryStream mem = new MemoryStream();
|
|
||||||
using BinaryWriter writer = new BinaryWriter(mem);
|
|
||||||
writer.Write((byte)MessageType.AudioData);
|
|
||||||
writer.Write(lastAudioId++);
|
|
||||||
writer.Write(data.ToArray());
|
|
||||||
// send voice data unreliably
|
|
||||||
// SendBytes(mem.ToArray(), false);
|
|
||||||
SendBytesToGroup("voice", mem.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This sort of all initializes dissonance
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">Dissonance ID</param>
|
|
||||||
public void SetDissonanceID(string id)
|
|
||||||
{
|
|
||||||
dissonanceID = id;
|
|
||||||
|
|
||||||
using MemoryStream mem = new MemoryStream();
|
|
||||||
using BinaryWriter writer = new BinaryWriter(mem);
|
|
||||||
writer.Write((byte)MessageType.DissonanceId);
|
|
||||||
writer.Write(dissonanceID);
|
|
||||||
SendBytes(mem.ToArray());
|
|
||||||
comms.dissonanceComms.TrackPlayerPosition(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void VoiceInitialized(string id)
|
|
||||||
{
|
|
||||||
dissonanceID = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy()
|
|
||||||
{
|
|
||||||
comms.SetPlayerLeft(dissonanceID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Update is called once per frame
|
|
||||||
private void Update()
|
|
||||||
{
|
|
||||||
if (!IsMine) return;
|
|
||||||
|
|
||||||
// handle nearness cutoff
|
|
||||||
if (maxDistance > 0)
|
|
||||||
{
|
|
||||||
bool closePlayerListChanged = false;
|
|
||||||
foreach (VelNetDissonancePlayer p in allPlayers)
|
|
||||||
{
|
|
||||||
if (p == this)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
float dist = Vector3.Distance(p.transform.position, transform.position);
|
|
||||||
if (dist < maxDistance && !closePlayers.Contains(p.Owner.userid))
|
|
||||||
{
|
|
||||||
closePlayers.Add(p.Owner.userid);
|
|
||||||
closePlayerListChanged = true;
|
|
||||||
}
|
|
||||||
else if (dist >= maxDistance && closePlayers.Contains(p.Owner.userid))
|
|
||||||
{
|
|
||||||
closePlayers.Remove(p.Owner.userid);
|
|
||||||
closePlayerListChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (closePlayerListChanged)
|
|
||||||
{
|
|
||||||
VelNetManager.instance.SetupMessageGroup("voice", closePlayers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int lastLength = closePlayers.Count;
|
|
||||||
closePlayers = allPlayers.Where(p => p != this).Select(p => p.Owner.userid).ToList();
|
|
||||||
if (closePlayers.Count != lastLength)
|
|
||||||
{
|
|
||||||
VelNetManager.instance.SetupMessageGroup("voice", closePlayers);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// handle dissonance comms
|
|
||||||
|
|
||||||
//if we're not speaking, and the comms say we are, send a speaking event, which will be received on other network players and sent to their comms accordingly
|
|
||||||
if (comms.dissonanceComms.FindPlayer(dissonanceID)?.IsSpeaking != isSpeaking) //unfortunately, there does not seem to be an event for this
|
|
||||||
{
|
|
||||||
isSpeaking = !isSpeaking;
|
|
||||||
|
|
||||||
using MemoryStream mem = new MemoryStream();
|
|
||||||
using BinaryWriter writer = new BinaryWriter(mem);
|
|
||||||
writer.Write((byte)MessageType.SpeakingState);
|
|
||||||
writer.Write(isSpeaking ? (byte)1 : (byte)0);
|
|
||||||
SendBytes(mem.ToArray());
|
|
||||||
|
|
||||||
if (!isSpeaking)
|
|
||||||
{
|
|
||||||
lastAudioId = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ReceiveBytes(byte[] message)
|
|
||||||
{
|
|
||||||
using MemoryStream mem = new MemoryStream(message);
|
|
||||||
using BinaryReader reader = new BinaryReader(mem);
|
|
||||||
|
|
||||||
byte identifier = reader.ReadByte();
|
|
||||||
switch (identifier)
|
|
||||||
{
|
|
||||||
case 0: //audio data
|
|
||||||
{
|
|
||||||
if (isSpeaking)
|
|
||||||
{
|
|
||||||
comms.VoiceReceived(dissonanceID, message.Skip(1).ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1: //dissonance id (player joined)
|
|
||||||
{
|
|
||||||
if (dissonanceID == "") // I don't have this yet
|
|
||||||
{
|
|
||||||
dissonanceID = reader.ReadString();
|
|
||||||
|
|
||||||
// tell the comms network that this player joined the channel
|
|
||||||
comms.SetPlayerJoined(dissonanceID); // tell dissonance
|
|
||||||
comms.dissonanceComms.TrackPlayerPosition(this); // tell dissonance to track the remote player
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: // speaking state
|
|
||||||
{
|
|
||||||
if (message[1] == 0)
|
|
||||||
{
|
|
||||||
comms.SetPlayerStoppedSpeaking(dissonanceID);
|
|
||||||
isSpeaking = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
comms.SetPlayerStartedSpeaking(dissonanceID);
|
|
||||||
isSpeaking = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
fileFormatVersion: 2
|
|
||||||
guid: c773e094326d413bb1bca7f91cbf7f8c
|
|
||||||
timeCreated: 1641506874
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Dissonance;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.Serialization;
|
using UnityEngine.Serialization;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
@ -14,13 +15,13 @@ namespace VelNet
|
||||||
public Text messages;
|
public Text messages;
|
||||||
public List<string> messageBuffer;
|
public List<string> messageBuffer;
|
||||||
public Dropdown microphones;
|
public Dropdown microphones;
|
||||||
Dissonance.DissonanceComms comms;
|
DissonanceComms comms;
|
||||||
|
|
||||||
public void HandleSend()
|
public void HandleSend()
|
||||||
{
|
{
|
||||||
if (sendInput.text != "")
|
if (sendInput.text != "")
|
||||||
{
|
{
|
||||||
velNetManager.SendTo(VelNetManager.MessageType.OTHERS, sendInput.text);
|
VelNetManager.SendTo(VelNetManager.MessageType.OTHERS, sendInput.text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,7 +29,7 @@ namespace VelNet
|
||||||
{
|
{
|
||||||
if (userInput.text != "")
|
if (userInput.text != "")
|
||||||
{
|
{
|
||||||
velNetManager.Login(userInput.text, "nopass");
|
VelNetManager.Login(userInput.text, "nopass");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,14 +37,14 @@ namespace VelNet
|
||||||
{
|
{
|
||||||
if (roomInput.text != "")
|
if (roomInput.text != "")
|
||||||
{
|
{
|
||||||
velNetManager.Join(roomInput.text);
|
VelNetManager.Join(roomInput.text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start is called before the first frame update
|
// Start is called before the first frame update
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
comms = FindObjectOfType<Dissonance.DissonanceComms>();
|
comms = FindObjectOfType<DissonanceComms>();
|
||||||
microphones.AddOptions(new List<string>(Microphone.devices));
|
microphones.AddOptions(new List<string>(Microphone.devices));
|
||||||
velNetManager.MessageReceived += (m) =>
|
velNetManager.MessageReceived += (m) =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,6 @@
|
||||||
"url": "https://vel.engr.uga.edu"
|
"url": "https://vel.engr.uga.edu"
|
||||||
},
|
},
|
||||||
"samples": [
|
"samples": [
|
||||||
{
|
|
||||||
"displayName": "Dissonance Integration",
|
|
||||||
"description": "Includes support for Dissonance Voice, available separately from the Unity Asset Store.",
|
|
||||||
"path": "Samples~/DissonanceIntegration"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"displayName": "Example",
|
"displayName": "Example",
|
||||||
"description": "Example Scene",
|
"description": "Example Scene",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue