some more cleanup and documentation, split dissonance player into its own componenent for simple adding, added some binarywriter extensions
parent
55b405c5b8
commit
8861888ade
|
|
@ -8,6 +8,7 @@ using System.Net;
|
||||||
|
|
||||||
namespace VelNetUnity
|
namespace VelNetUnity
|
||||||
{
|
{
|
||||||
|
[AddComponentMenu("VelNetUnity/VelNet Network Manager")]
|
||||||
public class NetworkManager : MonoBehaviour
|
public class NetworkManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
public enum MessageType
|
public enum MessageType
|
||||||
|
|
@ -21,6 +22,8 @@ namespace VelNetUnity
|
||||||
public string host;
|
public string host;
|
||||||
public int port;
|
public int port;
|
||||||
|
|
||||||
|
public static NetworkManager instance;
|
||||||
|
|
||||||
#region private members
|
#region private members
|
||||||
|
|
||||||
private TcpClient socketConnection;
|
private TcpClient socketConnection;
|
||||||
|
|
@ -36,14 +39,14 @@ namespace VelNetUnity
|
||||||
public GameObject playerPrefab;
|
public GameObject playerPrefab;
|
||||||
public Dictionary<int, NetworkPlayer> players = new Dictionary<int, NetworkPlayer>();
|
public Dictionary<int, NetworkPlayer> players = new Dictionary<int, NetworkPlayer>();
|
||||||
|
|
||||||
public Action<NetworkPlayer> onJoinedRoom = delegate { };
|
public Action<NetworkPlayer> OnJoinedRoom;
|
||||||
public Action<NetworkPlayer> onPlayerJoined = delegate { };
|
public Action<NetworkPlayer> OnPlayerJoined;
|
||||||
public Action<NetworkPlayer> onPlayerLeft = delegate { };
|
public Action<NetworkPlayer> OnPlayerLeft;
|
||||||
|
|
||||||
public List<NetworkObject> prefabs = new List<NetworkObject>();
|
public List<NetworkObject> prefabs = new List<NetworkObject>();
|
||||||
public NetworkObject[] sceneObjects;
|
public NetworkObject[] sceneObjects;
|
||||||
public List<string> deletedSceneObjects = new List<string>();
|
public List<string> deletedSceneObjects = new List<string>();
|
||||||
public 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 NetworkPlayer masterPlayer;
|
private NetworkPlayer masterPlayer;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@ -58,6 +61,15 @@ namespace VelNetUnity
|
||||||
|
|
||||||
public readonly List<Message> receivedMessages = new List<Message>();
|
public readonly List<Message> receivedMessages = new List<Message>();
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (instance != null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Multiple NetworkManagers detected! Bad!", this);
|
||||||
|
}
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
ConnectToTcpServer();
|
ConnectToTcpServer();
|
||||||
|
|
@ -112,8 +124,7 @@ namespace VelNetUnity
|
||||||
player.userid = m.sender;
|
player.userid = m.sender;
|
||||||
players.Add(userid, player);
|
players.Add(userid, player);
|
||||||
player.room = m.text;
|
player.room = m.text;
|
||||||
player.manager = this;
|
OnJoinedRoom?.Invoke(player);
|
||||||
onJoinedRoom(player);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //not for me, a player is joining or leaving
|
else //not for me, a player is joining or leaving
|
||||||
|
|
@ -150,9 +161,8 @@ namespace VelNetUnity
|
||||||
player.isLocal = false;
|
player.isLocal = false;
|
||||||
player.room = m.text;
|
player.room = m.text;
|
||||||
player.userid = m.sender;
|
player.userid = m.sender;
|
||||||
player.manager = this;
|
|
||||||
players.Add(m.sender, player);
|
players.Add(m.sender, player);
|
||||||
onPlayerJoined(player);
|
OnPlayerJoined?.Invoke(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -498,10 +508,12 @@ namespace VelNetUnity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//changes the designated group that sendto(4) will go to
|
/// <summary>
|
||||||
public void SetupMessageGroup(string groupname, int[] userids)
|
/// changes the designated group that sendto(4) will go to
|
||||||
|
/// </summary>
|
||||||
|
public void SetupMessageGroup(string groupName, IEnumerable<int> userIds)
|
||||||
{
|
{
|
||||||
SendNetworkMessage("5:" + groupname + ":" + String.Join(":", userids));
|
SendNetworkMessage($"5:{groupName}:{string.Join(":", userIds)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteNetworkObject(string networkId)
|
public void DeleteNetworkObject(string networkId)
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,14 @@ namespace VelNetUnity
|
||||||
public abstract class NetworkObject : MonoBehaviour
|
public abstract class NetworkObject : MonoBehaviour
|
||||||
{
|
{
|
||||||
public NetworkPlayer owner;
|
public NetworkPlayer owner;
|
||||||
public string networkId; //this is forged from the combination of the creator's id (-1 in the case of a scene object) and an object id, so it's always unique for a room
|
/// <summary>
|
||||||
public string prefabName; //this may be empty if it's not a prefab (scene object)
|
/// This is forged from the combination of the creator's id (-1 in the case of a scene object) and an object id, so it's always unique for a room
|
||||||
|
/// </summary>
|
||||||
|
public string networkId;
|
||||||
|
/// <summary>
|
||||||
|
/// This may be empty if it's not a prefab (scene object)
|
||||||
|
/// </summary>
|
||||||
|
public string prefabName;
|
||||||
public bool isSceneObject;
|
public bool isSceneObject;
|
||||||
public abstract void HandleMessage(string identifier, byte[] message);
|
public abstract void HandleMessage(string identifier, byte[] message);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,28 +5,37 @@ using System;
|
||||||
|
|
||||||
namespace VelNetUnity
|
namespace VelNetUnity
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// One of these will be instantiated for each player that joins the "room".
|
||||||
|
/// </summary>
|
||||||
[RequireComponent(typeof(NetworkObject))]
|
[RequireComponent(typeof(NetworkObject))]
|
||||||
|
[AddComponentMenu("VelNetUnity/VelNet Network Player")]
|
||||||
public class NetworkPlayer : MonoBehaviour
|
public class NetworkPlayer : MonoBehaviour
|
||||||
{
|
{
|
||||||
public NetworkObject myObject;
|
private NetworkObject myObject;
|
||||||
public int userid;
|
public int userid;
|
||||||
public string username;
|
public string username;
|
||||||
|
|
||||||
public string room;
|
public string room;
|
||||||
public NetworkManager manager;
|
|
||||||
|
|
||||||
public bool isLocal;
|
public bool isLocal;
|
||||||
|
|
||||||
public int lastObjectId; //for instantiation
|
private NetworkManager manager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For instantiation
|
||||||
|
/// </summary>
|
||||||
|
public int lastObjectId;
|
||||||
|
|
||||||
|
|
||||||
private bool isMaster;
|
private bool isMaster;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
myObject = GetComponent<NetworkObject>();
|
||||||
myObject.owner = this;
|
myObject.owner = this;
|
||||||
manager = FindObjectOfType<NetworkManager>();
|
manager = NetworkManager.instance;
|
||||||
manager.onPlayerJoined += HandlePlayerJoined;
|
manager.OnPlayerJoined += HandlePlayerJoined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandlePlayerJoined(NetworkPlayer player)
|
public void HandlePlayerJoined(NetworkPlayer player)
|
||||||
|
|
@ -111,7 +120,7 @@ namespace VelNetUnity
|
||||||
NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName);
|
NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName);
|
||||||
if (temp != null)
|
if (temp != null)
|
||||||
{
|
{
|
||||||
NetworkObject instance = Instantiate<NetworkObject>(temp);
|
NetworkObject instance = Instantiate(temp);
|
||||||
instance.networkId = networkId;
|
instance.networkId = networkId;
|
||||||
instance.prefabName = prefabName;
|
instance.prefabName = prefabName;
|
||||||
instance.owner = this;
|
instance.owner = this;
|
||||||
|
|
@ -184,7 +193,7 @@ namespace VelNetUnity
|
||||||
NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName);
|
NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName);
|
||||||
if (temp != null)
|
if (temp != null)
|
||||||
{
|
{
|
||||||
NetworkObject instance = Instantiate<NetworkObject>(temp);
|
NetworkObject instance = Instantiate(temp);
|
||||||
instance.networkId = networkId;
|
instance.networkId = networkId;
|
||||||
instance.prefabName = prefabName;
|
instance.prefabName = prefabName;
|
||||||
instance.owner = this;
|
instance.owner = this;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
using System.IO;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace VelNetUnity
|
||||||
|
{
|
||||||
|
public static class BinaryWriterExtensions
|
||||||
|
{
|
||||||
|
public static void Write(this BinaryWriter writer, Vector3 v)
|
||||||
|
{
|
||||||
|
writer.Write(v.x);
|
||||||
|
writer.Write(v.y);
|
||||||
|
writer.Write(v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Write(this BinaryWriter writer, Quaternion q)
|
||||||
|
{
|
||||||
|
writer.Write(q.x);
|
||||||
|
writer.Write(q.y);
|
||||||
|
writer.Write(q.z);
|
||||||
|
writer.Write(q.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector3 ReadVector3(this BinaryReader reader)
|
||||||
|
{
|
||||||
|
return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Quaternion ReadQuaternion(this BinaryReader reader)
|
||||||
|
{
|
||||||
|
return new Quaternion(
|
||||||
|
reader.ReadSingle(),
|
||||||
|
reader.ReadSingle(),
|
||||||
|
reader.ReadSingle(),
|
||||||
|
reader.ReadSingle()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 239a48a05eea49c583384b4113cf4729
|
||||||
|
timeCreated: 1641508695
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using System;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.IO;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -8,6 +8,7 @@ namespace VelNetUnity
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A simple class that will sync the position and rotation of a network object
|
/// A simple class that will sync the position and rotation of a network object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[AddComponentMenu("VelNetUnity/VelNet Sync Transform")]
|
||||||
public class SyncTransform : NetworkObject
|
public class SyncTransform : NetworkObject
|
||||||
{
|
{
|
||||||
public Vector3 targetPosition;
|
public Vector3 targetPosition;
|
||||||
|
|
@ -16,18 +17,13 @@ namespace VelNetUnity
|
||||||
|
|
||||||
public byte[] GetSyncMessage()
|
public byte[] GetSyncMessage()
|
||||||
{
|
{
|
||||||
float[] data = new float[7];
|
using MemoryStream mem = new MemoryStream();
|
||||||
for (int i = 0; i < 3; i++)
|
using BinaryWriter writer = new BinaryWriter(mem);
|
||||||
{
|
|
||||||
data[i] = transform.position[i];
|
|
||||||
data[i + 3] = transform.rotation[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
data[6] = transform.rotation[3];
|
writer.Write(transform.position);
|
||||||
|
writer.Write(transform.rotation);
|
||||||
|
|
||||||
byte[] toReturn = new byte[sizeof(float) * data.Length];
|
return mem.ToArray();
|
||||||
Buffer.BlockCopy(data, 0, toReturn, 0, toReturn.Length);
|
|
||||||
return toReturn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void HandleMessage(string identifier, byte[] message)
|
public override void HandleMessage(string identifier, byte[] message)
|
||||||
|
|
@ -35,16 +31,15 @@ namespace VelNetUnity
|
||||||
switch (identifier)
|
switch (identifier)
|
||||||
{
|
{
|
||||||
case "s":
|
case "s":
|
||||||
float[] data = new float[7];
|
{
|
||||||
Buffer.BlockCopy(message, 0, data, 0, message.Length);
|
using MemoryStream mem = new MemoryStream(message);
|
||||||
for (int i = 0; i < 3; i++)
|
using BinaryReader reader = new BinaryReader(mem);
|
||||||
{
|
|
||||||
targetPosition[i] = data[i];
|
targetPosition = reader.ReadVector3();
|
||||||
targetRotation[i] = data[i + 3];
|
targetRotation = reader.ReadQuaternion();
|
||||||
}
|
|
||||||
|
|
||||||
targetRotation[3] = data[6];
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
using System;
|
||||||
|
using Dissonance;
|
||||||
|
using Dissonance.Networking;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
|
namespace VelNetUnity
|
||||||
|
{
|
||||||
|
[AddComponentMenu("VelNetUnity/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;
|
||||||
|
public DissonanceComms comms;
|
||||||
|
private NetworkManager 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;
|
||||||
|
comms = GetComponent<DissonanceComms>();
|
||||||
|
manager = NetworkManager.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize(string playerName, Rooms rooms, PlayerChannels playerChannels, RoomChannels roomChannels, CodecSettings codecSettings)
|
||||||
|
{
|
||||||
|
dissonanceId = playerName;
|
||||||
|
initSettings = codecSettings;
|
||||||
|
comms.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);
|
||||||
|
PlayerLeft?.Invoke(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPlayerStartedSpeaking(string id)
|
||||||
|
{
|
||||||
|
PlayerStartedSpeaking?.Invoke(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPlayerStoppedSpeaking(string id)
|
||||||
|
{
|
||||||
|
PlayerStoppedSpeaking?.Invoke(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,195 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Dissonance;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace VelNetUnity
|
||||||
|
{
|
||||||
|
[RequireComponent(typeof(VelCommsNetwork))]
|
||||||
|
[AddComponentMenu("VelNetUnity/Dissonance/VelNet Dissonance Player")]
|
||||||
|
public class VelNetDissonancePlayer : NetworkObject, IDissonancePlayer
|
||||||
|
{
|
||||||
|
private VelCommsNetwork comms;
|
||||||
|
private bool isSpeaking;
|
||||||
|
private uint lastAudioId;
|
||||||
|
|
||||||
|
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 => owner.isLocal ? NetworkPlayerType.Local : NetworkPlayerType.Remote;
|
||||||
|
public bool IsTracking => true;
|
||||||
|
|
||||||
|
public Vector3 targetPosition;
|
||||||
|
public Quaternion targetRotation;
|
||||||
|
|
||||||
|
public List<VelNetDissonancePlayer> allPlayers = new List<VelNetDissonancePlayer>();
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Start is called before the first frame update
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
comms = FindObjectOfType<VelCommsNetwork>();
|
||||||
|
|
||||||
|
if (!allPlayers.Contains(this))
|
||||||
|
{
|
||||||
|
allPlayers.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (owner.isLocal)
|
||||||
|
{
|
||||||
|
SetDissonanceID(comms.dissonanceId);
|
||||||
|
comms.VoiceQueued += SendVoiceData;
|
||||||
|
|
||||||
|
//we also need to know when other players join, so we can send the dissonance ID again
|
||||||
|
|
||||||
|
NetworkManager.instance.OnPlayerJoined += (player) =>
|
||||||
|
{
|
||||||
|
byte[] b = Encoding.UTF8.GetBytes(dissonanceID);
|
||||||
|
owner.SendMessage(this, "d", b);
|
||||||
|
};
|
||||||
|
NetworkManager.instance.SetupMessageGroup("close", closePlayers.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HandleMessage(string identifier, byte[] message)
|
||||||
|
{
|
||||||
|
switch (identifier)
|
||||||
|
{
|
||||||
|
case "a": //audio data
|
||||||
|
{
|
||||||
|
if (isSpeaking)
|
||||||
|
{
|
||||||
|
comms.VoiceReceived(dissonanceID, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "d": //dissonance id (player joined)
|
||||||
|
{
|
||||||
|
if (dissonanceID == "") // I don't have this yet
|
||||||
|
{
|
||||||
|
dissonanceID = Encoding.UTF8.GetString(message);
|
||||||
|
// tell the comms network that this player joined the channel
|
||||||
|
comms.SetPlayerJoined(dissonanceID); // tell dissonance
|
||||||
|
comms.comms.TrackPlayerPosition(this); // tell dissonance to track the remote player
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "x": // speaking state
|
||||||
|
{
|
||||||
|
if (message[0] == 0)
|
||||||
|
{
|
||||||
|
comms.SetPlayerStoppedSpeaking(dissonanceID);
|
||||||
|
isSpeaking = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
comms.SetPlayerStartedSpeaking(dissonanceID);
|
||||||
|
isSpeaking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SendVoiceData(ArraySegment<byte> data)
|
||||||
|
{
|
||||||
|
// need to send it
|
||||||
|
if (owner == null || !owner.isLocal) return;
|
||||||
|
|
||||||
|
using MemoryStream mem = new MemoryStream();
|
||||||
|
using BinaryWriter writer = new BinaryWriter(mem);
|
||||||
|
writer.Write(BitConverter.GetBytes(lastAudioId++));
|
||||||
|
writer.Write(data.ToArray());
|
||||||
|
// send voice data unreliably
|
||||||
|
owner.SendGroupMessage(this, "close", "a", mem.ToArray(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This sort of all initializes dissonance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Dissonance ID</param>
|
||||||
|
public void SetDissonanceID(string id)
|
||||||
|
{
|
||||||
|
dissonanceID = id;
|
||||||
|
byte[] b = Encoding.UTF8.GetBytes(dissonanceID);
|
||||||
|
owner.SendMessage(this, "d", b);
|
||||||
|
comms.comms.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 (owner == null) return;
|
||||||
|
if (!owner.isLocal) 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)
|
||||||
|
{
|
||||||
|
NetworkManager.instance.SetupMessageGroup("close", 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.comms.FindPlayer(dissonanceID)?.IsSpeaking != isSpeaking) //unfortunately, there does not seem to be an event for this
|
||||||
|
{
|
||||||
|
isSpeaking = !isSpeaking;
|
||||||
|
byte[] toSend = { isSpeaking ? (byte)1 : (byte)0 };
|
||||||
|
owner.SendMessage(this, "x", toSend);
|
||||||
|
|
||||||
|
if (!isSpeaking)
|
||||||
|
{
|
||||||
|
lastAudioId = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c773e094326d413bb1bca7f91cbf7f8c
|
||||||
|
timeCreated: 1641506874
|
||||||
|
|
@ -1,109 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Dissonance;
|
|
||||||
using Dissonance.Extensions;
|
|
||||||
using Dissonance.Networking;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
|
|
||||||
public class VelCommsNetwork : MonoBehaviour, ICommsNetwork
|
|
||||||
{
|
|
||||||
public ConnectionStatus Status
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return manager.connected?ConnectionStatus.Connected:ConnectionStatus.Disconnected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkMode Mode
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return 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;
|
|
||||||
|
|
||||||
ConnectionStatus _status = ConnectionStatus.Disconnected;
|
|
||||||
CodecSettings initSettings;
|
|
||||||
public string dissonanceId;
|
|
||||||
public DissonanceComms comms;
|
|
||||||
public NetworkManager manager;
|
|
||||||
|
|
||||||
public Action<ArraySegment<byte>> voiceQueued = delegate { }; //listen to this if you want to send voice
|
|
||||||
|
|
||||||
public void Initialize(string playerName, Rooms rooms, PlayerChannels playerChannels, RoomChannels roomChannels, CodecSettings codecSettings)
|
|
||||||
{
|
|
||||||
dissonanceId = playerName;
|
|
||||||
initSettings = codecSettings;
|
|
||||||
comms.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(vp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendText(string data, ChannelType recipientType, string recipientId)
|
|
||||||
{
|
|
||||||
Debug.Log("sending text");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendVoice(ArraySegment<byte> data)
|
|
||||||
{
|
|
||||||
voiceQueued(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start is called before the first frame update
|
|
||||||
void Start()
|
|
||||||
{
|
|
||||||
_status = ConnectionStatus.Connected;
|
|
||||||
comms = GetComponent<DissonanceComms>();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playerJoined(string id)
|
|
||||||
{
|
|
||||||
Debug.Log("dissonance player joined");
|
|
||||||
PlayerJoined(id, initSettings);
|
|
||||||
RoomEvent re = new RoomEvent();
|
|
||||||
re.Joined = true;
|
|
||||||
re.Room = "Global";
|
|
||||||
re.PlayerName = id;
|
|
||||||
PlayerEnteredRoom(re);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playerLeft(string id)
|
|
||||||
{
|
|
||||||
RoomEvent re = new RoomEvent();
|
|
||||||
re.Joined = false;
|
|
||||||
re.Room = "Global";
|
|
||||||
re.PlayerName = id;
|
|
||||||
PlayerExitedRoom(re);
|
|
||||||
PlayerLeft(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playerStartedSpeaking(string id)
|
|
||||||
{
|
|
||||||
PlayerStartedSpeaking(id);
|
|
||||||
}
|
|
||||||
public void playerStoppedSpeaking(string id)
|
|
||||||
{
|
|
||||||
PlayerStoppedSpeaking(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,73 +1,71 @@
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
public class NetworkGUI : MonoBehaviour
|
|
||||||
|
namespace VelNetUnity
|
||||||
{
|
{
|
||||||
public NetworkManager networkManager;
|
public class NetworkGUI : MonoBehaviour
|
||||||
public InputField userInput;
|
{
|
||||||
public InputField sendInput;
|
public NetworkManager networkManager;
|
||||||
public InputField roomInput;
|
public InputField userInput;
|
||||||
public Text messages;
|
public InputField sendInput;
|
||||||
public List<string> messageBuffer;
|
public InputField roomInput;
|
||||||
public Dropdown microphones;
|
public Text messages;
|
||||||
Dissonance.DissonanceComms comms;
|
public List<string> messageBuffer;
|
||||||
public void handleSend()
|
public Dropdown microphones;
|
||||||
{
|
Dissonance.DissonanceComms comms;
|
||||||
if(sendInput.text != "")
|
|
||||||
{
|
|
||||||
networkManager.sendTo(NetworkManager.MessageType.OTHERS,sendInput.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void handleLogin()
|
|
||||||
{
|
|
||||||
if(userInput.text != "")
|
|
||||||
{
|
|
||||||
networkManager.login(userInput.text, "nopass");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void handleJoin()
|
|
||||||
{
|
|
||||||
if(roomInput.text != "")
|
|
||||||
{
|
|
||||||
|
|
||||||
networkManager.join(roomInput.text);
|
public void HandleSend()
|
||||||
}
|
{
|
||||||
|
if (sendInput.text != "")
|
||||||
|
{
|
||||||
|
networkManager.SendTo(NetworkManager.MessageType.OTHERS, sendInput.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
public void HandleLogin()
|
||||||
|
{
|
||||||
|
if (userInput.text != "")
|
||||||
|
{
|
||||||
|
networkManager.Login(userInput.text, "nopass");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start is called before the first frame update
|
public void HandleJoin()
|
||||||
void Start()
|
{
|
||||||
{
|
if (roomInput.text != "")
|
||||||
comms = GameObject.FindObjectOfType<Dissonance.DissonanceComms>();
|
{
|
||||||
microphones.AddOptions(new List<string>(Microphone.devices));
|
networkManager.Join(roomInput.text);
|
||||||
networkManager.messageReceived += (m) => {
|
}
|
||||||
string s = m.type + ":" + m.sender +":" + m.text;
|
}
|
||||||
messageBuffer.Add(s);
|
|
||||||
messages.text = "";
|
// Start is called before the first frame update
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
comms = FindObjectOfType<Dissonance.DissonanceComms>();
|
||||||
|
microphones.AddOptions(new List<string>(Microphone.devices));
|
||||||
|
networkManager.MessageReceived += (m) =>
|
||||||
|
{
|
||||||
|
string s = m.type + ":" + m.sender + ":" + m.text;
|
||||||
|
messageBuffer.Add(s);
|
||||||
|
messages.text = "";
|
||||||
|
|
||||||
|
|
||||||
|
if (messageBuffer.Count > 10)
|
||||||
|
{
|
||||||
|
messageBuffer.RemoveAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string msg in messageBuffer)
|
||||||
|
{
|
||||||
|
messages.text = messages.text + msg + "\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if(messageBuffer.Count > 10)
|
public void handleMicrophoneSelection()
|
||||||
{
|
{
|
||||||
messageBuffer.RemoveAt(0);
|
comms.MicrophoneName = microphones.options[microphones.value].text;
|
||||||
}
|
}
|
||||||
for(int i = 0; i < messageBuffer.Count; i++)
|
}
|
||||||
{
|
|
||||||
messages.text = messages.text + messageBuffer[i] + "\n";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void handleMicrophoneSelection()
|
|
||||||
{
|
|
||||||
comms.MicrophoneName = microphones.options[microphones.value].text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update is called once per frame
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,244 +1,100 @@
|
||||||
using System;
|
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Dissonance;
|
|
||||||
using System.Text;
|
namespace VelNetUnity
|
||||||
public class PlayerController : NetworkObject, Dissonance.IDissonancePlayer
|
|
||||||
{
|
{
|
||||||
VelCommsNetwork comms;
|
public class PlayerController : NetworkObject
|
||||||
bool isSpeaking = false;
|
{
|
||||||
uint lastAudioId = 0;
|
public Vector3 targetPosition;
|
||||||
public string dissonanceID="";
|
public Quaternion targetRotation;
|
||||||
//required by dissonance for spatial audio
|
|
||||||
public string PlayerId => dissonanceID;
|
|
||||||
public Vector3 Position => transform.position;
|
|
||||||
public Quaternion Rotation => transform.rotation;
|
|
||||||
public NetworkPlayerType Type => this.owner.isLocal ? NetworkPlayerType.Local : NetworkPlayerType.Remote;
|
|
||||||
public bool IsTracking => true;
|
|
||||||
|
|
||||||
public Vector3 targetPosition;
|
public byte[] GetSyncMessage()
|
||||||
public Quaternion targetRotation;
|
{
|
||||||
|
using MemoryStream mem = new MemoryStream();
|
||||||
|
using BinaryWriter writer = new BinaryWriter(mem);
|
||||||
|
|
||||||
public List<int> closePlayers = new List<int>();
|
writer.Write(transform.position);
|
||||||
|
writer.Write(transform.rotation);
|
||||||
|
|
||||||
|
return mem.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HandleMessage(string identifier, byte[] message)
|
||||||
|
{
|
||||||
|
switch (identifier)
|
||||||
|
{
|
||||||
|
case "s": // sync message
|
||||||
|
{
|
||||||
|
using MemoryStream mem = new MemoryStream(message);
|
||||||
|
using BinaryReader reader = new BinaryReader(mem);
|
||||||
|
|
||||||
|
targetPosition = reader.ReadVector3();
|
||||||
|
targetRotation = reader.ReadQuaternion();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start is called before the first frame update
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
// player controller shouldn't change ownership, so we can check here once
|
||||||
|
if (owner.isLocal)
|
||||||
|
{
|
||||||
|
StartCoroutine(SyncBehavior());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public byte[] getSyncMessage()
|
private IEnumerator SyncBehavior()
|
||||||
{
|
{
|
||||||
float[] data = new float[7];
|
while (true)
|
||||||
for (int i = 0; i < 3; i++)
|
{
|
||||||
{
|
owner.SendMessage(this, "s", GetSyncMessage());
|
||||||
data[i] = transform.position[i];
|
yield return new WaitForSeconds(.1f);
|
||||||
data[i + 3] = transform.rotation[i];
|
}
|
||||||
}
|
}
|
||||||
data[6] = transform.rotation[3];
|
|
||||||
|
|
||||||
byte[] toReturn = new byte[sizeof(float) * data.Length];
|
// Update is called once per frame
|
||||||
Buffer.BlockCopy(data, 0, toReturn, 0, toReturn.Length);
|
private void Update()
|
||||||
return toReturn;
|
{
|
||||||
}
|
if (owner != null && !owner.isLocal)
|
||||||
|
{
|
||||||
|
transform.position = Vector3.Lerp(transform.position, targetPosition, .1f);
|
||||||
|
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, .1f);
|
||||||
|
}
|
||||||
|
else if (owner != null && owner.isLocal)
|
||||||
|
{
|
||||||
|
Vector3 movement = new Vector3();
|
||||||
|
movement.x += Input.GetAxis("Horizontal");
|
||||||
|
movement.y += Input.GetAxis("Vertical");
|
||||||
|
movement.z = 0;
|
||||||
|
transform.Translate(movement * Time.deltaTime);
|
||||||
|
|
||||||
public override void handleMessage(string identifier, byte[] message)
|
if (Input.GetKeyDown(KeyCode.Space))
|
||||||
{
|
{
|
||||||
switch (identifier)
|
owner.NetworkInstantiate("TestNetworkedGameObject");
|
||||||
{
|
}
|
||||||
case "s": //sync message
|
|
||||||
float[] data = new float[7];
|
|
||||||
Buffer.BlockCopy(message, 0, data, 0, message.Length);
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
targetPosition[i] = data[i];
|
|
||||||
targetRotation[i] = data[i + 3];
|
|
||||||
}
|
|
||||||
targetRotation[3] = data[6];
|
|
||||||
break;
|
|
||||||
case "a": //audio data
|
|
||||||
{
|
|
||||||
if (isSpeaking)
|
|
||||||
{
|
|
||||||
comms.voiceReceived(dissonanceID, message);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "d": //dissonance id (player joined)
|
|
||||||
{
|
|
||||||
if (dissonanceID == "") //I don't have this yet
|
|
||||||
{
|
|
||||||
dissonanceID = Encoding.UTF8.GetString(message);
|
|
||||||
//tell the comms network that this player joined the channel
|
|
||||||
comms.playerJoined(dissonanceID); //tell dissonance
|
|
||||||
comms.comms.TrackPlayerPosition(this); //tell dissonance to track the remote player
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "x": //speaking state
|
|
||||||
{
|
|
||||||
if (message[0]==0)
|
|
||||||
{
|
|
||||||
comms.playerStoppedSpeaking(dissonanceID);
|
|
||||||
isSpeaking = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
comms.playerStartedSpeaking(dissonanceID);
|
if (Input.GetKeyDown(KeyCode.BackQuote))
|
||||||
isSpeaking = true;
|
{
|
||||||
}
|
foreach (KeyValuePair<string, NetworkObject> kvp in NetworkManager.instance.objects)
|
||||||
break;
|
{
|
||||||
}
|
owner.TakeOwnership(kvp.Key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start is called before the first frame update
|
if (Input.GetKeyDown(KeyCode.Backspace))
|
||||||
void Start()
|
{
|
||||||
{
|
foreach (KeyValuePair<string, NetworkObject> kvp in NetworkManager.instance.objects)
|
||||||
|
{
|
||||||
//handle dissonance stuff
|
owner.NetworkDestroy(kvp.Key);
|
||||||
comms = GameObject.FindObjectOfType<VelCommsNetwork>();
|
}
|
||||||
if(comms != null)
|
}
|
||||||
{
|
}
|
||||||
if (owner.isLocal)
|
}
|
||||||
{
|
}
|
||||||
setDissonanceID(comms.dissonanceId);
|
|
||||||
comms.voiceQueued += sendVoiceData;
|
|
||||||
|
|
||||||
//we also need to know when other players join, so we can send the dissonance ID again
|
|
||||||
|
|
||||||
owner.manager.onPlayerJoined += (player) =>
|
|
||||||
{
|
|
||||||
byte[] b = Encoding.UTF8.GetBytes(dissonanceID);
|
|
||||||
owner.sendMessage(this, "d", b);
|
|
||||||
};
|
|
||||||
owner.manager.setupMessageGroup("close", closePlayers.ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (owner.isLocal)
|
|
||||||
{
|
|
||||||
StartCoroutine(syncBehavior());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendVoiceData(ArraySegment<byte> data)
|
|
||||||
{
|
|
||||||
//need to send it
|
|
||||||
if(owner != null && owner.isLocal)
|
|
||||||
{
|
|
||||||
byte[] toSend = new byte[data.Count+4];
|
|
||||||
byte[] lastAudioIdBytes = BitConverter.GetBytes(lastAudioId++);
|
|
||||||
Buffer.BlockCopy(lastAudioIdBytes, 0, toSend, 0, 4);
|
|
||||||
Buffer.BlockCopy(data.Array, data.Offset, toSend, 4, data.Count);
|
|
||||||
owner.sendGroupMessage(this,"close", "a", toSend, false); //send voice data unreliably
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDissonanceID(string id) //this sort of all initializes dissonance
|
|
||||||
{
|
|
||||||
dissonanceID = id;
|
|
||||||
byte[] b = Encoding.UTF8.GetBytes(dissonanceID);
|
|
||||||
owner.sendMessage(this, "d", b);
|
|
||||||
comms.comms.TrackPlayerPosition(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void voiceInitialized(string id)
|
|
||||||
{
|
|
||||||
dissonanceID = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnDestroy()
|
|
||||||
{
|
|
||||||
comms.playerLeft(dissonanceID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
IEnumerator syncBehavior()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
owner.sendMessage(this, "s", getSyncMessage());
|
|
||||||
yield return new WaitForSeconds(.1f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Update is called once per frame
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
if (owner != null && owner.isLocal) {
|
|
||||||
|
|
||||||
PlayerController[] players = GameObject.FindObjectsOfType<PlayerController>();
|
|
||||||
bool shouldUpdate = false;
|
|
||||||
for (int i = 0; i < players.Length; i++)
|
|
||||||
{
|
|
||||||
if (players[i] == this) { continue; }
|
|
||||||
float dist = Vector3.Distance(players[i].transform.position, this.transform.position);
|
|
||||||
if (dist < 2 && !closePlayers.Contains(players[i].owner.userid))
|
|
||||||
{
|
|
||||||
closePlayers.Add(players[i].owner.userid);
|
|
||||||
shouldUpdate = true;
|
|
||||||
}
|
|
||||||
else if(dist >=2 && closePlayers.Contains(players[i].owner.userid))
|
|
||||||
{
|
|
||||||
closePlayers.Remove(players[i].owner.userid);
|
|
||||||
shouldUpdate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (shouldUpdate)
|
|
||||||
{
|
|
||||||
owner.manager.setupMessageGroup("close", closePlayers.ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (owner != null && !owner.isLocal)
|
|
||||||
{
|
|
||||||
transform.position = Vector3.Lerp(transform.position, targetPosition, .1f);
|
|
||||||
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, .1f);
|
|
||||||
}
|
|
||||||
else if(owner != null && owner.isLocal)
|
|
||||||
{
|
|
||||||
|
|
||||||
//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.comms.FindPlayer(dissonanceID).IsSpeaking != isSpeaking) //unfortunately, there does not seem to be an event for this
|
|
||||||
{
|
|
||||||
isSpeaking = !isSpeaking;
|
|
||||||
byte[] toSend = new byte[1];
|
|
||||||
toSend[0] = isSpeaking ? (byte)1 : (byte)0;
|
|
||||||
owner.sendMessage(this, "x", toSend);
|
|
||||||
|
|
||||||
if (!isSpeaking)
|
|
||||||
{
|
|
||||||
lastAudioId = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Vector3 movement = new Vector3();
|
|
||||||
movement.x += Input.GetAxis("Horizontal");
|
|
||||||
movement.y += Input.GetAxis("Vertical");
|
|
||||||
movement.z = 0;
|
|
||||||
transform.Translate(movement * Time.deltaTime);
|
|
||||||
|
|
||||||
if (Input.GetKeyDown(KeyCode.Space))
|
|
||||||
{
|
|
||||||
owner.networkInstantiate("TestNetworkedGameObject");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Input.GetKeyDown(KeyCode.BackQuote))
|
|
||||||
{
|
|
||||||
foreach(KeyValuePair<string,NetworkObject> kvp in owner.manager.objects)
|
|
||||||
{
|
|
||||||
owner.takeOwnership(kvp.Key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Input.GetKeyDown(KeyCode.Backspace))
|
|
||||||
{
|
|
||||||
foreach (KeyValuePair<string, NetworkObject> kvp in owner.manager.objects)
|
|
||||||
{
|
|
||||||
owner.networkDestroy(kvp.Key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -14,6 +14,8 @@ GameObject:
|
||||||
- component: {fileID: 5845716565458182149}
|
- component: {fileID: 5845716565458182149}
|
||||||
- component: {fileID: 5713671764962751473}
|
- component: {fileID: 5713671764962751473}
|
||||||
- component: {fileID: -4404668399269848200}
|
- component: {fileID: -4404668399269848200}
|
||||||
|
- component: {fileID: 7065383111165629622}
|
||||||
|
- component: {fileID: 1181612843795795320}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: PlayerPrefab
|
m_Name: PlayerPrefab
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
|
|
@ -109,15 +111,11 @@ MonoBehaviour:
|
||||||
m_Script: {fileID: 11500000, guid: d8d3b6de660834e3e898725928251405, type: 3}
|
m_Script: {fileID: 11500000, guid: d8d3b6de660834e3e898725928251405, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
myObject: {fileID: -4404668399269848200}
|
|
||||||
userid: 0
|
userid: 0
|
||||||
username:
|
username:
|
||||||
room:
|
room:
|
||||||
manager: {fileID: 0}
|
|
||||||
isLocal: 0
|
isLocal: 0
|
||||||
lastObjectId: 0
|
lastObjectId: 0
|
||||||
commsNetwork: {fileID: 0}
|
|
||||||
dissonanceID:
|
|
||||||
--- !u!114 &-4404668399269848200
|
--- !u!114 &-4404668399269848200
|
||||||
MonoBehaviour:
|
MonoBehaviour:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|
@ -132,5 +130,43 @@ MonoBehaviour:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
owner: {fileID: 5713671764962751473}
|
owner: {fileID: 5713671764962751473}
|
||||||
networkId:
|
networkId:
|
||||||
|
prefabName:
|
||||||
|
isSceneObject: 0
|
||||||
targetPosition: {x: 0, y: 0, z: 0}
|
targetPosition: {x: 0, y: 0, z: 0}
|
||||||
targetRotation: {x: 0, y: 0, z: 0, w: 0}
|
targetRotation: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
--- !u!114 &7065383111165629622
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6139051692386484099}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 5d2009d8e264649749c0315d48765749, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
dissonanceId:
|
||||||
|
comms: {fileID: 0}
|
||||||
|
--- !u!114 &1181612843795795320
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 6139051692386484099}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: c773e094326d413bb1bca7f91cbf7f8c, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
owner: {fileID: 5713671764962751473}
|
||||||
|
networkId:
|
||||||
|
prefabName:
|
||||||
|
isSceneObject: 0
|
||||||
|
dissonanceID:
|
||||||
|
targetPosition: {x: 0, y: 0, z: 0}
|
||||||
|
targetRotation: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
allPlayers: []
|
||||||
|
closePlayers:
|
||||||
|
maxDistance: 0
|
||||||
|
|
|
||||||
|
|
@ -2121,7 +2121,7 @@ MonoBehaviour:
|
||||||
m_Calls:
|
m_Calls:
|
||||||
- m_Target: {fileID: 244561621}
|
- m_Target: {fileID: 244561621}
|
||||||
m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp
|
m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp
|
||||||
m_MethodName: handleJoin
|
m_MethodName: HandleJoin
|
||||||
m_Mode: 1
|
m_Mode: 1
|
||||||
m_Arguments:
|
m_Arguments:
|
||||||
m_ObjectArgument: {fileID: 0}
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
|
@ -2725,7 +2725,7 @@ MonoBehaviour:
|
||||||
m_Calls:
|
m_Calls:
|
||||||
- m_Target: {fileID: 244561621}
|
- m_Target: {fileID: 244561621}
|
||||||
m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp
|
m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp
|
||||||
m_MethodName: handleLogin
|
m_MethodName: HandleLogin
|
||||||
m_Mode: 1
|
m_Mode: 1
|
||||||
m_Arguments:
|
m_Arguments:
|
||||||
m_ObjectArgument: {fileID: 0}
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
|
@ -2858,7 +2858,7 @@ MonoBehaviour:
|
||||||
m_Calls:
|
m_Calls:
|
||||||
- m_Target: {fileID: 244561621}
|
- m_Target: {fileID: 244561621}
|
||||||
m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp
|
m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp
|
||||||
m_MethodName: handleSend
|
m_MethodName: HandleSend
|
||||||
m_Mode: 1
|
m_Mode: 1
|
||||||
m_Arguments:
|
m_Arguments:
|
||||||
m_ObjectArgument: {fileID: 0}
|
m_ObjectArgument: {fileID: 0}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
"self-hosted"
|
"self-hosted"
|
||||||
],
|
],
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Kyle Johnsen",
|
"name": "Virtual Experiences Laboratory",
|
||||||
"email": "kjohnsen@uga.edu",
|
"email": "kjohnsen@uga.edu",
|
||||||
"url": "https://vel.engr.uga.edu"
|
"url": "https://vel.engr.uga.edu"
|
||||||
},
|
},
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
{
|
{
|
||||||
"displayName": "Dissonance Integration",
|
"displayName": "Dissonance Integration",
|
||||||
"description": "Includes support for Dissonance Voice, available separately from the Unity Asset Store.",
|
"description": "Includes support for Dissonance Voice, available separately from the Unity Asset Store.",
|
||||||
"path": "Samples~/DissonanceIntegration"
|
"path": "Samples~/Dissonance Integration"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"displayName": "Example",
|
"displayName": "Example",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue