├── LICENSE ├── README.md └── VoiceChat ├── .gitignore ├── Assets ├── UnityP2P │ ├── P2PClient.cs │ └── P2PServer.cs ├── UnityVOIP │ ├── AudioCapture.cs │ ├── Demo │ │ └── UnityVOIPExample.unity │ ├── Plugins │ │ ├── CSCore.dll │ │ ├── NSpeex.dll │ │ └── samplerate.dll │ ├── VoiceChatUnityClient.cs │ ├── VoiceChatUnityServer.cs │ └── WritableAudioPlayer.cs └── WebRtcNetwork │ ├── LICENSE_WEBRTC.txt │ ├── Plugins │ ├── Byn.Common.dll │ ├── Byn.Common.dll.mdb │ ├── Byn.Common.pdb │ ├── Byn.Common.xml │ ├── Byn.Net.Native.dll │ ├── Byn.Net.Native.dll.mdb │ ├── Byn.Net.Native.pdb │ ├── Byn.Net.Websocket.dll │ ├── Byn.Net.Websocket.dll.mdb │ ├── Byn.Net.Websocket.pdb │ ├── WebGL │ │ └── WebRtcNetwork.jslib │ ├── WebRtcCSharp.dll │ ├── WebRtcCSharp.dll.mdb │ ├── WebRtcCSharp.pdb │ ├── WebSocketSharpUnityMod.dll │ ├── WebSocketSharpUnityMod.dll.mdb │ ├── WebSocketSharpUnityMod.pdb │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── armeabi-v7a │ │ │ └── libwebrtccsharpwrap.so │ │ ├── libjingle_peerconnection_java.jar │ │ └── readme.txt │ ├── mac │ │ └── x64 │ │ │ └── webrtccsharpwrap.bundle │ └── win │ │ ├── x64 │ │ └── webrtccsharpwrap.dll │ │ └── x86 │ │ └── webrtccsharpwrap.dll │ ├── Resources │ └── webrtcnetworkplugin.txt │ ├── changelog.txt │ ├── example │ ├── ChatApp.cs │ ├── ChatApp.prefab │ ├── DebugHelper.cs │ ├── MessageList.cs │ ├── Text.prefab │ ├── chatscene 1.unity │ └── chatscene.unity │ ├── license.txt │ ├── readme.txt │ ├── scripts │ ├── BrowserWebRtcNetwork.cs │ ├── BrowserWebRtcNetworkFactory.cs │ ├── UnitySingleton.cs │ └── WebRtcNetworkFactory.cs │ └── server.zip └── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NavMeshLayers.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Phylliida Dev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityVOIP 2 | Real time peer to peer voice chat in Unity, using CSCore, NSpeex, and UnityP2P 3 | 4 | 5 | Edit: I realized that this doesn't work for more than one speaker and has a few bugs, it is almost ready with those fixed but wait a few min until I remove this message to test it 6 | 7 | Edit edit: Fixed, it should work with any number of speakers now. The audio quality isn't very good but it should work with very little delay :) I'll make tweaks later to let you change the audio quality if you want 8 | 9 | Edit edit edit: This is still pretty bad, I'm going to fix it in a bit and incorporate [P2P.NET](https://github.com/Phylliida/P2P.NET) because it works much better 10 | 11 | This project is now abandoned, but there are still useful tidbits of code in here that people may find useful so I'll keep it up. 12 | -------------------------------------------------------------------------------- /VoiceChat/.gitignore: -------------------------------------------------------------------------------- 1 | # Unity3D .gitignore file. 2 | 3 | # ---------------[ tk2d Toolkit ]--------------------- # 4 | Assets/-tk2d.asset 5 | Assets/-tk2d.asset.meta 6 | 7 | # ---------------[ Unity generated ]------------------ # 8 | [Tt]emp/ 9 | [Oo]bj/ 10 | [Uu]nity[Gg]enerated/ 11 | [Ll]ibrary/ 12 | [Bb]uild/ 13 | 14 | # ----[ Visual Studio / MonoDevelop generated ]------- # 15 | [Ee]xported[Oo]bj/ 16 | *.booproj 17 | *.booproj.meta 18 | *.csproj 19 | *.csproj.meta 20 | *.pidb 21 | *.pidb.meta 22 | *.sln 23 | *.sln.meta 24 | *.sln.DotSettings.user 25 | *.sln.DotSettings.user.meta 26 | *.suo 27 | *.suo.meta 28 | *.svd 29 | *.svd.meta 30 | *.unityproj 31 | *.unityproj.meta 32 | *.user 33 | *.user.meta 34 | *.userprefs 35 | *.userprefs.meta 36 | _Resharper.* 37 | Assets/UnityVS 38 | Assets/UnityVS.meta 39 | 40 | # -------------[ OS generated ]------------------------ # 41 | .DS_Store 42 | .DS_Store? 43 | ._* 44 | .Spotlight-V100 45 | .Trashes 46 | Icon? 47 | ehthumbs.db 48 | Thumbs.db 49 | -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityP2P/P2PClient.cs: -------------------------------------------------------------------------------- 1 | using Byn.Net; 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | public class P2PClient : IDisposable 7 | { 8 | public Dictionary peers; 9 | IBasicNetwork mNetwork = null; 10 | string roomName; 11 | 12 | public P2PClient(string signalingServer, string roomName) 13 | { 14 | this.roomName = roomName; 15 | peers = new Dictionary(); 16 | //mNetwork = WebRtcNetworkFactory.Instance.CreateDefault("wss://nameless-scrubland-88927.herokuapp.com", new IceServer[] { new IceServer("stun:stun.l.google.com:19302") }); 17 | mNetwork = WebRtcNetworkFactory.Instance.CreateDefault(signalingServer, new IceServer[] { new IceServer("stun:stun.l.google.com:19302") }); 18 | if (mNetwork == null) 19 | { 20 | PrintDebug("failed to setup network"); 21 | return; 22 | } 23 | 24 | mNetwork.Connect(roomName); 25 | } 26 | 27 | 28 | public delegate void ReceivedMessageCallback(NetworkEvent message); 29 | public event ReceivedMessageCallback OnReceivedMessage; 30 | 31 | public delegate void OnConnectionCallback(ConnectionId connectionId); 32 | public event OnConnectionCallback OnConnection; 33 | 34 | public delegate void OnDisconnectionCallback(ConnectionId connectionId); 35 | public event OnDisconnectionCallback OnDisconnection; 36 | 37 | 38 | public void SendMessage(ConnectionId connectionId, byte[] data, bool isReliable) 39 | { 40 | SendMessage(connectionId, data, 0, data.Length, isReliable); 41 | } 42 | 43 | public void SendMessage(ConnectionId connectionId, byte[] data, int dataOffset, int dataLen, bool isReliable) 44 | { 45 | if (mNetwork != null && peers.ContainsKey(connectionId.ToString())) 46 | { 47 | mNetwork.SendData(connectionId, data, dataOffset, dataLen, isReliable); 48 | } 49 | else if (mNetwork == null) 50 | { 51 | PrintDebug("Can't send message, network isn't initialized"); 52 | } 53 | else 54 | { 55 | PrintDebug("Can't send message, connection id " + connectionId.ToString() + " is not a currently connected peer"); 56 | } 57 | } 58 | 59 | public void SendMessageToAll(byte[] data, bool isReliable) 60 | { 61 | SendMessageToAll(data, 0, data.Length, isReliable); 62 | } 63 | 64 | public void SendMessageToAll(byte[] data, int dataOffset, int dataLen, bool isReliable) 65 | { 66 | if (mNetwork != null) 67 | { 68 | foreach (KeyValuePair peer in peers) 69 | { 70 | mNetwork.SendData(peer.Value, data, dataOffset, dataLen, isReliable); 71 | } 72 | } 73 | else 74 | { 75 | PrintDebug("Can't send message, network isn't initialized"); 76 | } 77 | } 78 | 79 | private void Cleanup() 80 | { 81 | if (mNetwork != null) 82 | { 83 | mNetwork.Dispose(); 84 | mNetwork = null; 85 | } 86 | } 87 | 88 | void PrintDebug(string message) 89 | { 90 | Debug.Log(message); 91 | } 92 | 93 | int frameCount = 0; 94 | 95 | public void UpdateClient() 96 | { 97 | 98 | frameCount++; 99 | 100 | if (peers.Count == 0 && frameCount % 10000 == 0) 101 | { 102 | mNetwork.Connect(roomName); 103 | } 104 | 105 | 106 | HandleNetwork(); 107 | 108 | } 109 | 110 | 111 | void HandleNetwork() 112 | { 113 | //check if the network was created 114 | if (mNetwork != null) 115 | { 116 | //first update it to read the data from the underlaying network system 117 | mNetwork.Update(); 118 | 119 | //handle all new events that happened since the last update 120 | NetworkEvent evt; 121 | //check for new messages and keep checking if mNetwork is available. it might get destroyed 122 | //due to an event 123 | while (mNetwork != null && mNetwork.Dequeue(out evt)) 124 | { 125 | //check every message 126 | switch (evt.Type) 127 | { 128 | case NetEventType.ServerInitialized: 129 | { 130 | //server initialized message received 131 | //this is the reaction to StartServer -> switch GUI mode 132 | string address = evt.Info; 133 | PrintDebug("Server started. Address: " + address); 134 | //uRoomName.text = "" + address; 135 | } 136 | break; 137 | case NetEventType.ServerInitFailed: 138 | { 139 | //user tried to start the server but it failed 140 | //maybe the user is offline or signaling server down? 141 | PrintDebug("Server start failed."); 142 | } 143 | break; 144 | case NetEventType.ServerClosed: 145 | { 146 | mNetwork.Connect(roomName); 147 | } 148 | break; 149 | case NetEventType.NewConnection: 150 | { 151 | // mConnections.Add(evt.ConnectionId); 152 | //either user runs a client and connected to a server or the 153 | //user runs the server and a new client connected 154 | PrintDebug("New local connection! ID: " + evt.ConnectionId); 155 | peers[evt.ConnectionId.ToString()] = evt.ConnectionId; 156 | if (OnConnection != null) 157 | { 158 | OnConnection(evt.ConnectionId); 159 | } 160 | } 161 | break; 162 | case NetEventType.ConnectionFailed: 163 | { 164 | //Outgoing connection failed. Inform the user. 165 | PrintDebug("Connection failed"); 166 | mNetwork.Connect(roomName); 167 | } 168 | break; 169 | case NetEventType.Disconnected: 170 | { 171 | //mConnections.Remove(evt.ConnectionId); 172 | //A connection was disconnected 173 | //If this was the client then he was disconnected from the server 174 | //if it was the server this just means that one of the clients left 175 | PrintDebug("Local Connection ID " + evt.ConnectionId + " disconnected"); 176 | 177 | 178 | if (peers.ContainsKey(evt.ConnectionId.ToString())) 179 | { 180 | peers.Remove(evt.ConnectionId.ToString()); 181 | } 182 | 183 | if (OnDisconnection != null) 184 | { 185 | OnDisconnection(evt.ConnectionId); 186 | } 187 | } 188 | break; 189 | case NetEventType.ReliableMessageReceived: 190 | { 191 | if (OnReceivedMessage != null) 192 | { 193 | OnReceivedMessage(evt); 194 | } 195 | // Maybe call 196 | // evt.MessageData.Dispose(); 197 | // ? Idk. Same for Unreliable 198 | } 199 | break; 200 | case NetEventType.UnreliableMessageReceived: 201 | { 202 | if (OnReceivedMessage != null) 203 | { 204 | OnReceivedMessage(evt); 205 | } 206 | } 207 | break; 208 | } 209 | } 210 | 211 | //finish this update by flushing the messages out if the network wasn't destroyed during update 212 | if (mNetwork != null) 213 | mNetwork.Flush(); 214 | } 215 | } 216 | 217 | ~P2PClient() 218 | { 219 | Cleanup(); 220 | } 221 | 222 | public void Dispose() 223 | { 224 | Cleanup(); 225 | } 226 | } -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityP2P/P2PServer.cs: -------------------------------------------------------------------------------- 1 | using Byn.Net; 2 | using System; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | 7 | public class P2PServer : IDisposable 8 | { 9 | public Dictionary peers; 10 | IBasicNetwork mNetwork = null; 11 | bool mIsServer = false; 12 | string roomName; 13 | 14 | DateTime lastTimeGotAnything; 15 | 16 | public P2PServer(string signalingServer, string roomName) 17 | { 18 | this.roomName = roomName; 19 | lastTimeGotAnything = DateTime.Now; 20 | peers = new Dictionary(); 21 | //mNetwork = WebRtcNetworkFactory.Instance.CreateDefault("wss://nameless-scrubland-88927.herokuapp.com", new IceServer[] { new IceServer("stun:stun.l.google.com:19302") }); 22 | mNetwork = WebRtcNetworkFactory.Instance.CreateDefault(signalingServer, new IceServer[] { new IceServer("stun:stun.l.google.com:19302") }); 23 | if (mNetwork == null) 24 | { 25 | PrintDebug("failed to setup network"); 26 | return; 27 | } 28 | 29 | mNetwork.StartServer(roomName); 30 | } 31 | 32 | 33 | public delegate void ReceivedMessageCallback(NetworkEvent message); 34 | public event ReceivedMessageCallback OnReceivedMessage; 35 | 36 | public delegate void OnConnectionCallback(ConnectionId connectionId); 37 | public event OnConnectionCallback OnConnection; 38 | 39 | public delegate void OnDisconnectionCallback(ConnectionId connectionId); 40 | public event OnDisconnectionCallback OnDisconnection; 41 | 42 | public void SendMessage(ConnectionId connectionId, byte[] data, bool isReliable) 43 | { 44 | SendMessage(connectionId, data, 0, data.Length, isReliable); 45 | } 46 | 47 | public void SendMessage(ConnectionId connectionId, byte[] data, int dataOffset, int dataLen, bool isReliable) 48 | { 49 | lock (peers) 50 | { 51 | if (mNetwork != null && peers.ContainsKey(connectionId.ToString())) 52 | { 53 | mNetwork.SendData(connectionId, data, dataOffset, dataLen, isReliable); 54 | } 55 | else if (mNetwork == null) 56 | { 57 | PrintDebug("Can't send message, network isn't initialized"); 58 | } 59 | else 60 | { 61 | PrintDebug("Can't send message, connection id " + connectionId.ToString() + " is not a currently connected peer"); 62 | } 63 | } 64 | } 65 | 66 | public void SendMessageToAll(byte[] data, bool isReliable) 67 | { 68 | SendMessageToAll(data, 0, data.Length, isReliable); 69 | } 70 | 71 | public void SendMessageToAll(byte[] data, int dataOffset, int dataLen, bool isReliable) 72 | { 73 | if (mNetwork != null) 74 | { 75 | lock (peers) 76 | { 77 | foreach (KeyValuePair peer in peers) 78 | { 79 | mNetwork.SendData(peer.Value, data, dataOffset, dataLen, isReliable); 80 | } 81 | } 82 | } 83 | else 84 | { 85 | PrintDebug("Can't send message, network isn't initialized"); 86 | } 87 | } 88 | 89 | 90 | 91 | private void Cleanup() 92 | { 93 | if (mNetwork != null) 94 | { 95 | if (mIsServer) 96 | { 97 | mNetwork.StopServer(); 98 | mIsServer = false; 99 | } 100 | mNetwork.Dispose(); 101 | mNetwork = null; 102 | } 103 | } 104 | 105 | private void OnDestroy() 106 | { 107 | Cleanup(); 108 | } 109 | 110 | void PrintDebug(string message) 111 | { 112 | Debug.Log(message); 113 | } 114 | 115 | private void OnApplicationQuit() 116 | { 117 | Cleanup(); 118 | } 119 | 120 | long frameCount = 0; 121 | // Update is called once per frame 122 | public void UpdateServer() 123 | { 124 | frameCount++; 125 | 126 | if (!mIsServer && frameCount % 50000 == 0) 127 | { 128 | mNetwork.StartServer(roomName); 129 | } 130 | 131 | // It has been 40 seconds since got any messages, reset server before it decides to die 132 | if ((DateTime.Now - lastTimeGotAnything).TotalSeconds > 40) 133 | { 134 | PrintDebug("Server timeout after 40 seconds, restarting server"); 135 | if (mIsServer) 136 | { 137 | mNetwork.StopServer(); 138 | } 139 | mIsServer = false; 140 | mNetwork.StartServer(roomName); 141 | lastTimeGotAnything = DateTime.Now; 142 | } 143 | 144 | HandleNetwork(); 145 | } 146 | 147 | 148 | 149 | private void HandleNetwork() 150 | { 151 | //check if the network was created 152 | if (mNetwork != null) 153 | { 154 | //first update it to read the data from the underlaying network system 155 | mNetwork.Update(); 156 | 157 | //handle all new events that happened since the last update 158 | NetworkEvent evt; 159 | //check for new messages and keep checking if mNetwork is available. it might get destroyed 160 | //due to an event 161 | while (mNetwork != null && mNetwork.Dequeue(out evt)) 162 | { 163 | lastTimeGotAnything = DateTime.Now; 164 | //check every message 165 | switch (evt.Type) 166 | { 167 | case NetEventType.ServerInitialized: 168 | { 169 | //server initialized message received 170 | mIsServer = true; 171 | string address = evt.Info; 172 | PrintDebug("Server started. Address: " + address); 173 | } 174 | break; 175 | case NetEventType.ServerInitFailed: 176 | { 177 | //user tried to start the server but it failed 178 | //maybe the user is offline or signaling server down? 179 | PrintDebug("Server start failed."); 180 | mIsServer = false; 181 | } 182 | break; 183 | case NetEventType.ServerClosed: 184 | { 185 | PrintDebug("Server closed"); 186 | mNetwork.StartServer(roomName); 187 | } 188 | break; 189 | case NetEventType.NewConnection: 190 | { 191 | //user runs a server. announce to everyone the new connection 192 | //using the server side connection id as identification 193 | string msg = "New user " + evt.ConnectionId + " joined the room."; 194 | PrintDebug(msg); 195 | 196 | lock (peers) 197 | { 198 | peers[evt.ConnectionId.ToString()] = evt.ConnectionId; 199 | } 200 | 201 | if (OnConnection != null) 202 | { 203 | OnConnection(evt.ConnectionId); 204 | } 205 | } 206 | break; 207 | case NetEventType.ConnectionFailed: 208 | { 209 | //Outgoing connection failed. Inform the user. 210 | PrintDebug("Connection failed"); 211 | } 212 | break; 213 | case NetEventType.Disconnected: 214 | { 215 | //mConnections.Remove(evt.ConnectionId); 216 | //A connection was disconnected 217 | //If this was the client then he was disconnected from the server 218 | //if it was the server this just means that one of the clients left 219 | PrintDebug("Local Connection ID " + evt.ConnectionId + " disconnected"); 220 | lock (peers) 221 | { 222 | if (peers.ContainsKey(evt.ConnectionId.ToString())) 223 | { 224 | peers.Remove(evt.ConnectionId.ToString()); 225 | } 226 | } 227 | if (OnDisconnection != null) 228 | { 229 | OnDisconnection(evt.ConnectionId); 230 | } 231 | } 232 | break; 233 | case NetEventType.ReliableMessageReceived: 234 | { 235 | if (OnReceivedMessage != null) 236 | { 237 | OnReceivedMessage(evt); 238 | } 239 | } 240 | break; 241 | case NetEventType.UnreliableMessageReceived: 242 | { 243 | if (OnReceivedMessage != null) 244 | { 245 | OnReceivedMessage(evt); 246 | } 247 | } 248 | break; 249 | } 250 | } 251 | 252 | //finish this update by flushing the messages out if the network wasn't destroyed during update 253 | if (mNetwork != null) 254 | mNetwork.Flush(); 255 | } 256 | } 257 | 258 | 259 | ~P2PServer() 260 | { 261 | Cleanup(); 262 | } 263 | 264 | public void Dispose() 265 | { 266 | Cleanup(); 267 | } 268 | } -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityVOIP/AudioCapture.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using CSCore; 3 | using CSCore.SoundIn; 4 | using CSCore.Streams; 5 | using System; 6 | using CSCore.SoundOut; 7 | using CSCore.CoreAudioAPI; 8 | using System.Runtime.InteropServices; 9 | using System.Collections.Generic; 10 | using Byn.Net; 11 | 12 | namespace UnityVOIP 13 | { 14 | public class AudioCapture : IDisposable 15 | { 16 | public WasapiCapture capture; 17 | public IWaveSource actualSource; 18 | PureDataSource dataSource; 19 | 20 | public enum ConverterQuality 21 | { 22 | SRC_SINC_FASTEST = 2, 23 | SRC_SINC_MEDIUM_QUALITY = 1, 24 | SRC_SINC_BEST_QUALITY = 0 25 | }; 26 | 27 | [DllImport("samplerate", EntryPoint = "src_simple_plain")] 28 | public static extern int src_simple_plain(float[] data_in, float[] data_out, int input_frames, int output_frames, float src_ratio, ConverterQuality converter_type, int channels); 29 | 30 | private int sampleRate; 31 | public int SampleRate 32 | { 33 | get 34 | { 35 | return sampleRate; 36 | } 37 | private set 38 | { 39 | 40 | } 41 | } 42 | private int sampleSize; 43 | public int SampleSize 44 | { 45 | get 46 | { 47 | return sampleSize; 48 | } 49 | private set 50 | { 51 | 52 | } 53 | } 54 | IWaveSource finalSource; 55 | public AudioCapture(int sampleRate, int sampleSize) 56 | { 57 | this.sampleRate = sampleRate; 58 | this.sampleSize = sampleSize; 59 | 60 | if (sampleSize <= 0) 61 | { 62 | throw new ArgumentException("Sample size must be > 0, instead it is " + sampleSize); 63 | } 64 | 65 | resSamples = new float[this.sampleSize]; 66 | var ayy = new MMDeviceEnumerator(); 67 | // This uses the wasapi api to get any sound data played by the computer 68 | capture = new WasapiCapture(false, AudioClientShareMode.Shared, 100); 69 | capture.Device = ayy.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Multimedia); 70 | capture.Initialize(); 71 | capture.DataAvailable += Capture_DataAvailable; 72 | 73 | IWaveSource source = new SoundInSource(capture); 74 | 75 | 76 | dataSource = new PureDataSource(new WaveFormat(sampleRate, 8, 1), source.ToSampleSource()); 77 | dataSource.OnDataRead += DataSource_OnDataRead; 78 | 79 | finalSource = dataSource.ToWaveSource(); 80 | 81 | capture.Start(); 82 | } 83 | 84 | public delegate void OnDataReadCallback(float[] data, int offset, int len); 85 | 86 | public event OnDataReadCallback OnDataRead; 87 | 88 | 89 | float[] remainingSamples = new float[100000]; 90 | int numRemainingSamples = 0; 91 | float[] resSamples; 92 | 93 | public void Poll() 94 | { 95 | if (numRemainingSamples >= SampleSize) 96 | { 97 | //Buffer.BlockCopy(remainingSamples, 0, resSamples, 0, SampleSize * sizeof(float)); 98 | 99 | int fadeSize = 10; 100 | fadeSize = Mathf.Min(fadeSize, SampleSize / 2 - 1); 101 | if (fadeSize > 1) 102 | { 103 | int startInd = 0 + SampleSize - fadeSize; 104 | for (int i = 0; i < fadeSize; i++) 105 | { 106 | float fade = 1 - (i / (float)(fadeSize - 1)); 107 | remainingSamples[startInd + i] *= fade * fade; 108 | float startFade = 1 - fade; 109 | remainingSamples[i] *= startFade * startFade; 110 | } 111 | } 112 | 113 | if (OnDataRead != null) 114 | { 115 | OnDataRead(remainingSamples, 0, SampleSize); 116 | } 117 | int numLeft = numRemainingSamples - SampleSize; 118 | lock (cleanupLock) 119 | { 120 | if (numLeft > 0) 121 | { 122 | Buffer.BlockCopy(remainingSamples, SampleSize * sizeof(float), remainingSamples, 0, numLeft * sizeof(float)); 123 | } 124 | numRemainingSamples -= SampleSize; 125 | } 126 | } 127 | } 128 | 129 | private void DataSource_OnDataRead(float[] data, int dataOffset, int len) 130 | { 131 | if (len == 0) 132 | { 133 | return; 134 | } 135 | lock (cleanupLock) 136 | { 137 | if (!cleanedUp) 138 | { 139 | if (sampleSize > 0) 140 | { 141 | if (len + numRemainingSamples > remainingSamples.Length) 142 | { 143 | len = remainingSamples.Length - numRemainingSamples; 144 | } 145 | if (len == 0) 146 | { 147 | return; 148 | } 149 | 150 | 151 | int fadeSize = 7; 152 | fadeSize = Mathf.Min(fadeSize, len / 2 - 1); 153 | if (fadeSize > 1) 154 | { 155 | int startInd = dataOffset + len - fadeSize; 156 | for (int i = 0; i < fadeSize; i++) 157 | { 158 | float fade = 1 - (i / (float)(fadeSize - 1)); 159 | data[startInd + i] *= fade * fade; 160 | float startFade = 1 - fade; 161 | data[dataOffset + i] *= startFade * startFade; 162 | } 163 | } 164 | 165 | 166 | Buffer.BlockCopy(data, dataOffset*sizeof(float), remainingSamples, numRemainingSamples * sizeof(float), len * sizeof(float)); 167 | numRemainingSamples += len; 168 | } 169 | } 170 | } 171 | /* 172 | return; 173 | 174 | //server.UpdateServer(); 175 | //client.UpdateClient(); 176 | if (data != null && len > 0) 177 | { 178 | Debug.Log("writing"); 179 | outSource.Write(data, dataOffset, len); 180 | } 181 | } 182 | } 183 | return; 184 | 185 | while (true) 186 | { 187 | byte[] packet = codec.GetPacket(); 188 | if (packet == null) 189 | { 190 | break; 191 | } 192 | lock (cleanupLock) 193 | { 194 | if (!cleanedUp) 195 | { 196 | //server.SendMessageToAll(packet, false); 197 | server.SendMessageToAll(packet, 0, packet.Length, true); 198 | } 199 | } 200 | } 201 | */ 202 | } 203 | 204 | bool wantsToCleanUp = false; 205 | bool isEditor; 206 | 207 | 208 | private void Capture_DataAvailable(object sender, DataAvailableEventArgs e) 209 | { 210 | try 211 | { 212 | if (wantsToCleanUp || capture == null) 213 | { 214 | return; 215 | } 216 | 217 | 218 | if (!cleanedUp) 219 | { 220 | byte[] curData = new byte[e.ByteCount]; 221 | finalSource.Read(curData, 0, e.ByteCount); 222 | } 223 | } 224 | 225 | catch (Exception ex) 226 | { 227 | Debug.Log(ex.Message); 228 | } 229 | } 230 | 231 | [HideInInspector] 232 | public bool cleanedUp = false; 233 | 234 | object cleanupLock = new object(); 235 | 236 | void Cleanup() 237 | { 238 | wantsToCleanUp = true; 239 | lock (cleanupLock) 240 | { 241 | if (!cleanedUp) 242 | { 243 | cleanedUp = true; 244 | if (capture != null) 245 | { 246 | while (capture.RecordingState == RecordingState.Recording) 247 | { 248 | capture.Stop(); 249 | } 250 | capture.Dispose(); 251 | capture = null; 252 | } 253 | } 254 | } 255 | } 256 | 257 | 258 | private void OnDestroy() 259 | { 260 | Cleanup(); 261 | } 262 | 263 | 264 | void OnApplicationQuit() 265 | { 266 | Cleanup(); 267 | } 268 | 269 | public void Dispose() 270 | { 271 | Cleanup(); 272 | } 273 | 274 | ~AudioCapture() 275 | { 276 | Dispose(); 277 | } 278 | 279 | public class PureDataSource : ISampleSource 280 | { 281 | public long Length 282 | { 283 | get 284 | { 285 | return 0; 286 | } 287 | } 288 | 289 | public long Position 290 | { 291 | get 292 | { 293 | return 0; 294 | } 295 | 296 | set 297 | { 298 | throw new NotImplementedException(); 299 | } 300 | } 301 | private WaveFormat _WaveFormat; 302 | public WaveFormat WaveFormat 303 | { 304 | get 305 | { 306 | return _WaveFormat; 307 | } 308 | } 309 | 310 | private int _Patch = 0; 311 | public int Patch 312 | { 313 | get { return _Patch; } 314 | //set { _Patch = value; } 315 | } 316 | 317 | public bool CanSeek 318 | { 319 | get 320 | { 321 | throw new NotImplementedException(); 322 | } 323 | } 324 | 325 | public delegate void DataReadCallback(float[] data, int dataOffset, int len); 326 | 327 | public event DataReadCallback OnDataRead; 328 | 329 | public ISampleSource source; 330 | 331 | public PureDataSource(WaveFormat waveFormat, ISampleSource source) 332 | { 333 | _WaveFormat = waveFormat; 334 | this.source = source; 335 | } 336 | 337 | public ConverterQuality quality; 338 | 339 | float[] tempBuffer1 = new float[80000 * 20]; 340 | float[] tempBuffer2 = new float[80000 * 20]; 341 | float lastThing = 0; 342 | 343 | public int Read(float[] buffer, int offset, int count) 344 | { 345 | int numRead = ActualRead(buffer, offset, count); 346 | //int numRead = source.Read(buffer, offset, count); 347 | 348 | 349 | 350 | if (OnDataRead != null && numRead > 0) 351 | { 352 | if (source.WaveFormat.Channels == 2) 353 | { 354 | for (int i = 0; i < numRead / 2; i++) 355 | { 356 | tempBuffer1[i] = (buffer[offset + i * 2] + buffer[offset + i * 2 + 1]) / 2.0f; 357 | } 358 | OnDataRead(tempBuffer1, 0, numRead/2); 359 | } 360 | else 361 | { 362 | OnDataRead(buffer, offset, numRead); 363 | } 364 | } 365 | return count; 366 | return numRead; 367 | } 368 | 369 | private int ActualRead(float[] buffer, int offset, int count) 370 | { 371 | int sourceSampleRate = source.WaveFormat.SampleRate; 372 | int mySampleRate = WaveFormat.SampleRate; 373 | 374 | int numTheirSamples = (int)Mathf.Floor((count * (float)sourceSampleRate / mySampleRate)); 375 | if (source == null) 376 | { 377 | return 0; 378 | } 379 | int res = 100; 380 | try 381 | { 382 | res = source.Read(tempBuffer1, 0, numTheirSamples); 383 | if (res == 0) 384 | { 385 | if (count == 0) 386 | { 387 | return 0; 388 | } 389 | if (count == 1) 390 | { 391 | buffer[offset] = lastThing; 392 | return 1; 393 | } 394 | if (count >= 2) 395 | { 396 | buffer[offset] = lastThing * 0.8f; 397 | buffer[offset + 1] = lastThing * 0.6f; 398 | return 2; 399 | } 400 | } 401 | int numOurSamples = (int)Mathf.Round((res * (float)mySampleRate / sourceSampleRate)); 402 | res = src_simple_plain(tempBuffer1, tempBuffer2, res, numOurSamples, (float)mySampleRate / sourceSampleRate, ConverterQuality.SRC_SINC_FASTEST, source.WaveFormat.Channels); 403 | if (res > count) 404 | { 405 | res = count; 406 | } 407 | Buffer.BlockCopy(tempBuffer2, 0, buffer, offset*sizeof(float), res * sizeof(float)); 408 | } 409 | catch (Exception e) 410 | { 411 | Debug.Log("failed read: " + e.Message); 412 | } 413 | 414 | return Mathf.Max(res, 2); 415 | } 416 | 417 | public void Dispose() 418 | { 419 | 420 | } 421 | } 422 | 423 | public ConverterQuality quality = ConverterQuality.SRC_SINC_BEST_QUALITY; 424 | } 425 | } 426 | -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityVOIP/Demo/UnityVOIPExample.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 7 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 29 | m_HaloStrength: 0.5 30 | m_FlareStrength: 1 31 | m_FlareFadeSpeed: 3 32 | m_HaloTexture: {fileID: 0} 33 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 34 | m_DefaultReflectionMode: 0 35 | m_DefaultReflectionResolution: 128 36 | m_ReflectionBounces: 1 37 | m_ReflectionIntensity: 1 38 | m_CustomReflection: {fileID: 0} 39 | m_Sun: {fileID: 0} 40 | m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} 41 | --- !u!157 &3 42 | LightmapSettings: 43 | m_ObjectHideFlags: 0 44 | serializedVersion: 7 45 | m_GIWorkflowMode: 0 46 | m_GISettings: 47 | serializedVersion: 2 48 | m_BounceScale: 1 49 | m_IndirectOutputScale: 1 50 | m_AlbedoBoost: 1 51 | m_TemporalCoherenceThreshold: 1 52 | m_EnvironmentLightingMode: 0 53 | m_EnableBakedLightmaps: 1 54 | m_EnableRealtimeLightmaps: 1 55 | m_LightmapEditorSettings: 56 | serializedVersion: 4 57 | m_Resolution: 2 58 | m_BakeResolution: 40 59 | m_TextureWidth: 1024 60 | m_TextureHeight: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_Padding: 2 66 | m_LightmapParameters: {fileID: 0} 67 | m_LightmapsBakeMode: 1 68 | m_TextureCompression: 1 69 | m_DirectLightInLightProbes: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_LightingDataAsset: {fileID: 0} 75 | m_RuntimeCPUUsage: 25 76 | --- !u!196 &4 77 | NavMeshSettings: 78 | serializedVersion: 2 79 | m_ObjectHideFlags: 0 80 | m_BuildSettings: 81 | serializedVersion: 2 82 | agentTypeID: 0 83 | agentRadius: 0.5 84 | agentHeight: 2 85 | agentSlope: 45 86 | agentClimb: 0.4 87 | ledgeDropHeight: 0 88 | maxJumpAcrossDistance: 0 89 | minRegionArea: 2 90 | manualCellSize: 0 91 | cellSize: 0.16666667 92 | accuratePlacement: 0 93 | m_NavMeshData: {fileID: 0} 94 | --- !u!1 &392286490 95 | GameObject: 96 | m_ObjectHideFlags: 0 97 | m_PrefabParentObject: {fileID: 0} 98 | m_PrefabInternal: {fileID: 0} 99 | serializedVersion: 5 100 | m_Component: 101 | - component: {fileID: 392286495} 102 | - component: {fileID: 392286494} 103 | - component: {fileID: 392286493} 104 | - component: {fileID: 392286492} 105 | - component: {fileID: 392286491} 106 | - component: {fileID: 392286498} 107 | - component: {fileID: 392286497} 108 | - component: {fileID: 392286496} 109 | m_Layer: 0 110 | m_Name: Main Camera 111 | m_TagString: MainCamera 112 | m_Icon: {fileID: 0} 113 | m_NavMeshLayer: 0 114 | m_StaticEditorFlags: 0 115 | m_IsActive: 1 116 | --- !u!81 &392286491 117 | AudioListener: 118 | m_ObjectHideFlags: 0 119 | m_PrefabParentObject: {fileID: 0} 120 | m_PrefabInternal: {fileID: 0} 121 | m_GameObject: {fileID: 392286490} 122 | m_Enabled: 1 123 | --- !u!124 &392286492 124 | Behaviour: 125 | m_ObjectHideFlags: 0 126 | m_PrefabParentObject: {fileID: 0} 127 | m_PrefabInternal: {fileID: 0} 128 | m_GameObject: {fileID: 392286490} 129 | m_Enabled: 1 130 | --- !u!92 &392286493 131 | Behaviour: 132 | m_ObjectHideFlags: 0 133 | m_PrefabParentObject: {fileID: 0} 134 | m_PrefabInternal: {fileID: 0} 135 | m_GameObject: {fileID: 392286490} 136 | m_Enabled: 1 137 | --- !u!20 &392286494 138 | Camera: 139 | m_ObjectHideFlags: 0 140 | m_PrefabParentObject: {fileID: 0} 141 | m_PrefabInternal: {fileID: 0} 142 | m_GameObject: {fileID: 392286490} 143 | m_Enabled: 1 144 | serializedVersion: 2 145 | m_ClearFlags: 1 146 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 147 | m_NormalizedViewPortRect: 148 | serializedVersion: 2 149 | x: 0 150 | y: 0 151 | width: 1 152 | height: 1 153 | near clip plane: 0.3 154 | far clip plane: 1000 155 | field of view: 60 156 | orthographic: 0 157 | orthographic size: 5 158 | m_Depth: -1 159 | m_CullingMask: 160 | serializedVersion: 2 161 | m_Bits: 4294967295 162 | m_RenderingPath: -1 163 | m_TargetTexture: {fileID: 0} 164 | m_TargetDisplay: 0 165 | m_TargetEye: 3 166 | m_HDR: 0 167 | m_OcclusionCulling: 1 168 | m_StereoConvergence: 10 169 | m_StereoSeparation: 0.022 170 | m_StereoMirrorMode: 0 171 | --- !u!4 &392286495 172 | Transform: 173 | m_ObjectHideFlags: 0 174 | m_PrefabParentObject: {fileID: 0} 175 | m_PrefabInternal: {fileID: 0} 176 | m_GameObject: {fileID: 392286490} 177 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 178 | m_LocalPosition: {x: 0, y: 1, z: -10} 179 | m_LocalScale: {x: 1, y: 1, z: 1} 180 | m_Children: [] 181 | m_Father: {fileID: 0} 182 | m_RootOrder: 0 183 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 184 | --- !u!114 &392286496 185 | MonoBehaviour: 186 | m_ObjectHideFlags: 0 187 | m_PrefabParentObject: {fileID: 0} 188 | m_PrefabInternal: {fileID: 0} 189 | m_GameObject: {fileID: 392286490} 190 | m_Enabled: 1 191 | m_EditorHideFlags: 0 192 | m_Script: {fileID: 11500000, guid: 6f0f8c169f955d04285aef2284020595, type: 3} 193 | m_Name: 194 | m_EditorClassIdentifier: 195 | inputSampleRate: 8000 196 | --- !u!114 &392286497 197 | MonoBehaviour: 198 | m_ObjectHideFlags: 0 199 | m_PrefabParentObject: {fileID: 0} 200 | m_PrefabInternal: {fileID: 0} 201 | m_GameObject: {fileID: 392286490} 202 | m_Enabled: 1 203 | m_EditorHideFlags: 0 204 | m_Script: {fileID: 11500000, guid: bf25b0bf4fd3b6049939e4dfa78bd975, type: 3} 205 | m_Name: 206 | m_EditorClassIdentifier: 207 | serverURL: wss://nameless-scrubland-88927.herokuapp.com 208 | roomName: voicechattest22 209 | --- !u!114 &392286498 210 | MonoBehaviour: 211 | m_ObjectHideFlags: 0 212 | m_PrefabParentObject: {fileID: 0} 213 | m_PrefabInternal: {fileID: 0} 214 | m_GameObject: {fileID: 392286490} 215 | m_Enabled: 1 216 | m_EditorHideFlags: 0 217 | m_Script: {fileID: 11500000, guid: 79db4a53d9ccbfa41a25ba68e4ef17ac, type: 3} 218 | m_Name: 219 | m_EditorClassIdentifier: 220 | serverURL: wss://nameless-scrubland-88927.herokuapp.com 221 | roomName: voicechattest22 222 | player: {fileID: 392286496} 223 | --- !u!1 &1570744208 224 | GameObject: 225 | m_ObjectHideFlags: 0 226 | m_PrefabParentObject: {fileID: 0} 227 | m_PrefabInternal: {fileID: 0} 228 | serializedVersion: 5 229 | m_Component: 230 | - component: {fileID: 1570744210} 231 | - component: {fileID: 1570744209} 232 | m_Layer: 0 233 | m_Name: Directional Light 234 | m_TagString: Untagged 235 | m_Icon: {fileID: 0} 236 | m_NavMeshLayer: 0 237 | m_StaticEditorFlags: 0 238 | m_IsActive: 1 239 | --- !u!108 &1570744209 240 | Light: 241 | m_ObjectHideFlags: 0 242 | m_PrefabParentObject: {fileID: 0} 243 | m_PrefabInternal: {fileID: 0} 244 | m_GameObject: {fileID: 1570744208} 245 | m_Enabled: 1 246 | serializedVersion: 7 247 | m_Type: 1 248 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 249 | m_Intensity: 1 250 | m_Range: 10 251 | m_SpotAngle: 30 252 | m_CookieSize: 10 253 | m_Shadows: 254 | m_Type: 2 255 | m_Resolution: -1 256 | m_CustomResolution: -1 257 | m_Strength: 1 258 | m_Bias: 0.05 259 | m_NormalBias: 0.4 260 | m_NearPlane: 0.2 261 | m_Cookie: {fileID: 0} 262 | m_DrawHalo: 0 263 | m_Flare: {fileID: 0} 264 | m_RenderMode: 0 265 | m_CullingMask: 266 | serializedVersion: 2 267 | m_Bits: 4294967295 268 | m_Lightmapping: 4 269 | m_AreaSize: {x: 1, y: 1} 270 | m_BounceIntensity: 1 271 | m_ShadowRadius: 0 272 | m_ShadowAngle: 0 273 | --- !u!4 &1570744210 274 | Transform: 275 | m_ObjectHideFlags: 0 276 | m_PrefabParentObject: {fileID: 0} 277 | m_PrefabInternal: {fileID: 0} 278 | m_GameObject: {fileID: 1570744208} 279 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 280 | m_LocalPosition: {x: 0, y: 3, z: 0} 281 | m_LocalScale: {x: 1, y: 1, z: 1} 282 | m_Children: [] 283 | m_Father: {fileID: 0} 284 | m_RootOrder: 1 285 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 286 | -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityVOIP/Plugins/CSCore.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/UnityVOIP/Plugins/CSCore.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityVOIP/Plugins/NSpeex.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/UnityVOIP/Plugins/NSpeex.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityVOIP/Plugins/samplerate.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/UnityVOIP/Plugins/samplerate.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityVOIP/VoiceChatUnityClient.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System; 4 | using System.Collections.Generic; 5 | using UnityEngine.Networking; 6 | using Byn.Net; 7 | 8 | namespace UnityVOIP 9 | { 10 | public class VoiceChatUnityClient : MonoBehaviour 11 | { 12 | public string serverURL = "wss://nameless-scrubland-88927.herokuapp.com"; 13 | public string roomName = "voicechattest"; 14 | 15 | public AudioCapture recorder; 16 | public WritableAudioPlayer player; 17 | P2PClient client; 18 | Queue packets = new Queue(16); 19 | 20 | System.Random random; 21 | void Start() 22 | { 23 | client = new P2PClient(serverURL, roomName); 24 | recorder = new AudioCapture(8000, 320); 25 | recorder.OnDataRead += Recorder_OnDataRead; 26 | client.OnReceivedMessage += Client_OnReceivedMessage; 27 | 28 | random = new System.Random(); 29 | myId = (int)random.Next(); 30 | 31 | byte[] bytes = BitConverter.GetBytes(myId); 32 | id1 = bytes[0]; 33 | id2 = bytes[1]; 34 | id3 = bytes[2]; 35 | id4 = bytes[3]; 36 | } 37 | 38 | bool isRecording = false; 39 | 40 | byte id1, id2, id3, id4; 41 | int myId; 42 | 43 | byte isSpeechId = 10; 44 | 45 | private void Recorder_OnDataRead(float[] data, int offset, int len) 46 | { 47 | if (!isRecording) 48 | { 49 | //return; 50 | } 51 | ToShortArray(data, outBufferShort, offset, len); 52 | int resLen = speexEnc.Encode(outBufferShort, 0, len, outBuffer, 5, 5*320); 53 | outBuffer[0] = isSpeechId; 54 | outBuffer[1] = id1; 55 | outBuffer[2] = id2; 56 | outBuffer[3] = id3; 57 | outBuffer[4] = id4; 58 | client.SendMessageToAll(outBuffer, 0, resLen, true); 59 | 60 | } 61 | 62 | 63 | NSpeex.SpeexDecoder speexDec = new NSpeex.SpeexDecoder(NSpeex.BandMode.Narrow); 64 | NSpeex.SpeexEncoder speexEnc = new NSpeex.SpeexEncoder(NSpeex.BandMode.Narrow); 65 | private void Client_OnReceivedMessage(Byn.Net.NetworkEvent message) 66 | { 67 | if (message.MessageData.ContentLength < 5) 68 | { 69 | return; 70 | } 71 | int offset = message.MessageData.Offset; 72 | byte[] messageBuffer = message.MessageData.Buffer; 73 | 74 | int messageId = messageBuffer[offset]; 75 | int pid = BitConverter.ToInt32(messageBuffer, offset + 1); 76 | 77 | offset += 5; 78 | 79 | if (messageId == isSpeechId) 80 | { 81 | int resLen = speexDec.Decode(message.MessageData.Buffer, offset, message.MessageData.ContentLength, outBufferShort, 0, false); 82 | ToFloatArray(outBufferShort, outBufferFloat, resLen); 83 | int bean = message.ConnectionId.id; 84 | player.PlayAudio(outBufferFloat, 0, resLen, pid); 85 | } 86 | } 87 | 88 | public void OnDestroy() 89 | { 90 | recorder.Dispose(); 91 | } 92 | 93 | public void OnApplicationQuit() 94 | { 95 | recorder.Dispose(); 96 | } 97 | 98 | byte[] outBuffer = new byte[100000]; 99 | 100 | short[] outBufferShort = new short[100000]; 101 | float[] outBufferFloat = new float[100000]; 102 | 103 | static void ToShortArray(float[] input, short[] output, int offset, int len) 104 | { 105 | for (int i = 0; i < len; ++i) 106 | { 107 | output[i] = (short)Mathf.Clamp((int)(input[i+ offset] * 32767.0f), short.MinValue, short.MaxValue); 108 | } 109 | } 110 | 111 | static void ToFloatArray(short[] input, float[] output, int length) 112 | { 113 | for (int i = 0; i < length; ++i) 114 | { 115 | output[i] = input[i] / (float)short.MaxValue; 116 | } 117 | } 118 | 119 | void FixedUpdate() 120 | { 121 | recorder.Poll(); 122 | client.UpdateClient(); 123 | } 124 | 125 | private void Update() 126 | { 127 | isRecording = Input.GetKey(KeyCode.P); 128 | if (client.peers.Count > 0) 129 | { 130 | //while(packets.Count > 2) 131 | { 132 | //packets.Dequeue(); 133 | } 134 | } 135 | } 136 | } 137 | } -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityVOIP/VoiceChatUnityServer.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using Byn.Net; 4 | using System.Collections.Generic; 5 | 6 | namespace UnityVOIP 7 | { 8 | public class VoiceChatUnityServer : MonoBehaviour 9 | { 10 | P2PServer server; 11 | public string serverURL = "wss://nameless-scrubland-88927.herokuapp.com"; 12 | public string roomName = "voicechattest"; 13 | void Start() 14 | { 15 | server = new P2PServer(serverURL, roomName); 16 | server.OnReceivedMessage += Server_OnReceivedMessage; 17 | } 18 | 19 | private void Server_OnReceivedMessage(NetworkEvent message) 20 | { 21 | byte[] messageBytes = message.GetDataAsByteArray(); 22 | lock(server.peers) 23 | { 24 | foreach (KeyValuePair peer in server.peers) 25 | { 26 | if (peer.Value != message.ConnectionId) 27 | { 28 | server.SendMessage(peer.Value, messageBytes, false); 29 | } 30 | } 31 | } 32 | } 33 | 34 | private void Update() 35 | { 36 | server.UpdateServer(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /VoiceChat/Assets/UnityVOIP/WritableAudioPlayer.cs: -------------------------------------------------------------------------------- 1 | using CSCore; 2 | using CSCore.CoreAudioAPI; 3 | using CSCore.SoundOut; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Runtime.InteropServices; 7 | using UnityEngine; 8 | 9 | namespace UnityVOIP 10 | { 11 | public class WritableAudioPlayer : MonoBehaviour 12 | { 13 | Dictionary outputs; 14 | Dictionary sources; 15 | 16 | public int inputSampleRate = 8000; 17 | 18 | bool cleanedUp = false; 19 | object cleanupLock = new object(); 20 | 21 | private void Start() 22 | { 23 | outputs = new Dictionary(); 24 | sources = new Dictionary(); 25 | 26 | } 27 | // Use this for initialization 28 | void MakeOutput(out WasapiOut output, out WritablePureDataSource outSource) 29 | { 30 | var ayy = new MMDeviceEnumerator(); 31 | output = new WasapiOut(false, AudioClientShareMode.Shared, 100); 32 | output.Device = ayy.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); 33 | outSource = new WritablePureDataSource(new WaveFormat(inputSampleRate, 8, 1), new WaveFormat(output.Device.DeviceFormat.SampleRate, 8, output.Device.DeviceFormat.Channels)); 34 | 35 | output.Initialize(outSource.ToWaveSource()); 36 | 37 | output.Play(); 38 | } 39 | 40 | public float TimeUntilDone(int id) 41 | { 42 | if (outputs.ContainsKey(id)) 43 | { 44 | return sources[id].numUnprocessed / (float)sources[id].waveFormatIn.SampleRate; 45 | } 46 | else 47 | { 48 | throw new ArgumentException("Id " + id + " does not have an output yet"); 49 | } 50 | } 51 | 52 | 53 | public void PlayAudio(float[] audio, int offset, int len, int audioId) 54 | { 55 | lock (cleanupLock) 56 | { 57 | if (!cleanedUp) 58 | { 59 | if (outputs.ContainsKey(audioId)) 60 | { 61 | sources[audioId].Write(audio, offset, len); 62 | } 63 | else 64 | { 65 | WasapiOut output; 66 | WritablePureDataSource source; 67 | MakeOutput(out output, out source); 68 | sources[audioId] = source; 69 | outputs[audioId] = output; 70 | source.Write(audio, offset, len); 71 | } 72 | } 73 | } 74 | } 75 | public void PlayAudio(float[] audio, int audioId) 76 | { 77 | PlayAudio(audio, 0, audio.Length, audioId); 78 | } 79 | 80 | void Cleanup() 81 | { 82 | lock (cleanupLock) 83 | { 84 | if (!cleanedUp) 85 | { 86 | cleanedUp = true; 87 | 88 | foreach (KeyValuePair keyOutput in outputs) 89 | { 90 | WasapiOut output = keyOutput.Value; 91 | if (output.PlaybackState == PlaybackState.Paused) 92 | { 93 | output.Stop(); 94 | } 95 | while (output.PlaybackState == PlaybackState.Playing) 96 | { 97 | output.Stop(); 98 | } 99 | output.Dispose(); 100 | } 101 | } 102 | } 103 | } 104 | 105 | void OnDestroy() 106 | { 107 | Cleanup(); 108 | } 109 | void OnApplicationQuit() 110 | { 111 | Cleanup(); 112 | } 113 | } 114 | 115 | 116 | public enum ConverterQuality 117 | { 118 | SRC_SINC_FASTEST = 2, 119 | SRC_SINC_MEDIUM_QUALITY = 1, 120 | SRC_SINC_BEST_QUALITY = 0 121 | }; 122 | 123 | public class WritablePureDataSource : ISampleSource 124 | { 125 | 126 | [DllImport("samplerate", EntryPoint = "src_simple_plain")] 127 | public static extern int src_simple_plain(float[] data_in, float[] data_out, int input_frames, int output_frames, float src_ratio, ConverterQuality converter_type, int channels); 128 | 129 | 130 | public long Length 131 | { 132 | get 133 | { 134 | return 0; 135 | } 136 | } 137 | 138 | public long Position 139 | { 140 | get 141 | { 142 | return 0; 143 | } 144 | 145 | set 146 | { 147 | throw new NotImplementedException(); 148 | } 149 | } 150 | private WaveFormat _WaveFormat; 151 | public WaveFormat WaveFormat 152 | { 153 | get 154 | { 155 | return _WaveFormat; 156 | } 157 | } 158 | 159 | private int _Patch = 0; 160 | public int Patch 161 | { 162 | get { return _Patch; } 163 | //set { _Patch = value; } 164 | } 165 | 166 | public bool CanSeek 167 | { 168 | get 169 | { 170 | throw new NotImplementedException(); 171 | } 172 | } 173 | 174 | public WaveFormat waveFormatIn; 175 | public WaveFormat waveFormatOut; 176 | 177 | public WritablePureDataSource(WaveFormat waveFormatIn, WaveFormat waveFormatOut) 178 | { 179 | this.waveFormatIn = waveFormatIn; 180 | _WaveFormat = waveFormatOut; 181 | this.waveFormatOut = waveFormatOut; 182 | 183 | dats = new Queue(); 184 | offsets = new Queue(); 185 | lens = new Queue(); 186 | } 187 | 188 | 189 | 190 | 191 | 192 | 193 | float[] tempBuffer1 = new float[80000 * 20]; 194 | float[] tempBuffer2 = new float[80000 * 20]; 195 | float[] tempBuffer3 = new float[80000 * 20]; 196 | 197 | float[] unprocessedAudio = new float[80000*20]; 198 | public int numUnprocessed = 0; 199 | 200 | Queue dats; 201 | Queue offsets; 202 | Queue lens; 203 | 204 | private void AddToUnprocessedData(float[] data, int offset, int numBytes, int inChannels) 205 | { 206 | if (inChannels == 1 && waveFormatOut.Channels == 2) 207 | { 208 | int pos = 0; 209 | for (int i = 0; i < numBytes && pos < tempBuffer3.Length - 2; i++) 210 | { 211 | tempBuffer3[pos++] = data[i + offset]; 212 | tempBuffer3[pos++] = data[i + offset]; 213 | } 214 | AddToUnprocessedData(tempBuffer3, 0, numBytes * 2, 2); 215 | return; 216 | } 217 | if (numUnprocessed + numBytes > unprocessedAudio.Length) 218 | { 219 | numBytes = unprocessedAudio.Length - numUnprocessed; 220 | } 221 | if (numBytes == 0) 222 | { 223 | return; 224 | } 225 | 226 | Buffer.BlockCopy(data, offset * sizeof(float), unprocessedAudio, numUnprocessed * sizeof(float), numBytes * sizeof(float)); 227 | 228 | numUnprocessed += numBytes; 229 | 230 | while (numUnprocessed > 320*6) 231 | { 232 | Buffer.BlockCopy(data, 320 * sizeof(float), data, 0, numUnprocessed - 320); 233 | numUnprocessed -= 320; 234 | } 235 | } 236 | 237 | public void Write(float[] buffer, int offset, int count) 238 | { 239 | lock (unprocessedAudio) 240 | { 241 | AddToUnprocessedData(buffer, offset, count, waveFormatIn.Channels); 242 | /* 243 | dats.Enqueue(buffer); 244 | offsets.Enqueue(offset); 245 | lens.Enqueue(count); 246 | 247 | while (dats.Count > 100) 248 | { 249 | dats.Dequeue(); 250 | offsets.Dequeue(); 251 | lens.Dequeue(); 252 | } 253 | */ 254 | 255 | } 256 | } 257 | 258 | public int ReadUnprocessedData(float[] buffer, int offset, int count) 259 | { 260 | lock (unprocessedAudio) 261 | { 262 | int countUsing = Mathf.Min(count, numUnprocessed); 263 | 264 | if (countUsing <= 0) 265 | { 266 | if (count > 0) 267 | { 268 | Array.Clear(buffer, offset, count); 269 | return count; 270 | } 271 | else 272 | { 273 | return 0; 274 | } 275 | } 276 | Buffer.BlockCopy(unprocessedAudio, 0, buffer, offset * sizeof(float), countUsing * sizeof(float)); // size is in bytes 277 | 278 | int numLeft = numUnprocessed - countUsing; 279 | if (numUnprocessed > 0) 280 | { 281 | Buffer.BlockCopy(unprocessedAudio, countUsing * sizeof(float), unprocessedAudio, 0, numLeft * sizeof(float)); 282 | } 283 | numUnprocessed = numLeft; 284 | 285 | 286 | return countUsing; 287 | } 288 | } 289 | 290 | 291 | 292 | 293 | public ConverterQuality quality; 294 | 295 | public int Read(float[] buffer, int offset, int count) 296 | { 297 | Array.Clear(buffer, offset, count); 298 | int sourceSampleRate = waveFormatIn.SampleRate; 299 | int mySampleRate = waveFormatOut.SampleRate; 300 | 301 | int numTheirSamples = (int)Mathf.Floor((count * (float)sourceSampleRate / mySampleRate)); 302 | 303 | int res = 100; 304 | try 305 | { 306 | res = ReadUnprocessedData(tempBuffer1, 0, numTheirSamples); 307 | if (res == 0) 308 | { 309 | if (count == 0) 310 | { 311 | return 0; 312 | } 313 | else 314 | { 315 | return count; 316 | } 317 | } 318 | int numOurSamples = (int)Mathf.Round((res * (float)mySampleRate / sourceSampleRate)); 319 | res = src_simple_plain(tempBuffer1, tempBuffer2, res, numOurSamples, (float)mySampleRate / sourceSampleRate, ConverterQuality.SRC_SINC_FASTEST, waveFormatOut.Channels); 320 | if (res > count) 321 | { 322 | res = count; 323 | } 324 | Buffer.BlockCopy(tempBuffer2, 0, buffer, offset * sizeof(float), res * sizeof(float)); 325 | } 326 | catch (Exception e) 327 | { 328 | Debug.Log("failed read: " + e.Message); 329 | return count; 330 | } 331 | int fadeSize = 100; 332 | fadeSize = Mathf.Min(fadeSize, res/2 - 1); 333 | if (fadeSize > 1) 334 | { 335 | int startInd = offset + res - fadeSize; 336 | for (int i = 0; i < fadeSize; i++) 337 | { 338 | float fade = 1 - (i / (float)(fadeSize - 1)); 339 | buffer[startInd + i] *= fade* fade; 340 | float startFade = 1 - fade; 341 | buffer[offset + i] *= startFade* startFade; 342 | } 343 | } 344 | if (res < count) 345 | { 346 | for (int i = res; i < count; i++) 347 | { 348 | buffer[offset+i] = 0; 349 | } 350 | } 351 | return count; 352 | return Mathf.Min(Mathf.Max(res, 20), count); 353 | } 354 | 355 | public void Dispose() 356 | { 357 | 358 | } 359 | } 360 | } -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/LICENSE_WEBRTC.txt: -------------------------------------------------------------------------------- 1 | Full patent and license information can be found at https://webrtc.org/license/ 2 | 3 | 4 | 5 | 6 | 7 | 8 | Copyright (c) 2011, The WebRTC project authors. All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are 12 | met: 13 | 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | * Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in 19 | the documentation and/or other materials provided with the 20 | distribution. 21 | 22 | * Neither the name of Google nor the names of its contributors may 23 | be used to endorse or promote products derived from this software 24 | without specific prior written permission. 25 | 26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Common.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Common.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Common.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Common.dll.mdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Common.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Common.pdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Common.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Byn.Common 5 | 6 | 7 | 8 | 9 | Connection id idendifies one specific endpoint in a IBaseNetwork. 10 | 11 | The id is only unique locally for a specific IBaseNetwork. The same connection 12 | can have a different id on the other end point of the connection! 13 | 14 | 15 | 16 | 17 | Specific id that is used to represent an invalid id. 18 | 19 | Value might change to 0 in the future to make sure C# initializes empty id's to 20 | invalid values. 21 | 22 | 23 | 24 | 25 | Stores the id as a short. 26 | 27 | 28 | 29 | 30 | Creates a new id. Only for internal use. 31 | 32 | 33 | 34 | 35 | 36 | Returns true if the id has a valid value. 37 | 38 | 39 | 40 | 41 | 42 | Used to set up some default values such as free ice servers and signaling server. They are only meant 43 | to make the use of the library easier at the beginning. 44 | 45 | Don't use them in production. 46 | 47 | 48 | 49 | 50 | Returns a copy of an array containing default ice servers for webrtc. 51 | Use this only for testing and easy setup! 52 | 53 | 54 | 55 | 56 | Returns the default signaling server. Use for testing only! 57 | 58 | 59 | 60 | 61 | A work around for the unity. 62 | Unity stalls sometimes during SslStream AuthenticateAsClient calls. 63 | This workaround will attempt a call for 5 seconds and then kill the stream 64 | if it gets stuck and retry with a higher timeout value. It usually works 65 | after the first retry. 66 | 67 | The default is false as the work around might cause other problems on other 68 | platforms. 69 | 70 | 71 | 72 | 73 | Interface to a network that doesn't enforce storing any states. 74 | 75 | Anything more is reusable between multiple different networks. 76 | 77 | 78 | 79 | 80 | This will return the incoming network events. Call this method and handle the incoming events until it returns false. 81 | 82 | 83 | Returns true if the parameter evt contains a new event. False if there are no events to process left. 84 | 85 | 86 | 87 | Will return the first event in the queue without removing it. 88 | 89 | 90 | 91 | 92 | 93 | 94 | Sends buffered data. 95 | 96 | 97 | 98 | 99 | Sends the content if a byte array to the given connection. 100 | 101 | The id of the recipient 102 | Byte array containing the data to send 103 | The index in data where the network should start to send 104 | Length in bytes you want to send 105 | True to send a reliable message(TCP style) and false to send unreliable (UDP style) 106 | 107 | 108 | 109 | Disconnects the given connection 110 | 111 | Id of the connection to disconnect. 112 | 113 | 114 | 115 | Disconnects all connection and shuts down the server if started. 116 | Dequeue will still return the confirmation messages such as Disconnected event for each connection. 117 | 118 | 119 | 120 | 121 | 122 | Call this every frame if you intend to read incoming messages using Dequeue. This will make 123 | sure all data is read received by the network. 124 | 125 | 126 | 127 | 128 | Used to represent a network interface that can allow incoming connections or connect to another network. 129 | 130 | Address can be any kind of string. This could be a ip address and port, websockets or an key in a dictionary 131 | on a server to get the exact connection details from somewhere else. 132 | 133 | 134 | 135 | 136 | Starts a server + asking for it to have a certain address. 137 | The use of the address is not guaranteed. If the address is in 138 | use the underlying system will return ServerConnectionFailed. 139 | (This can also be triggered if anything else fails in the process) 140 | 141 | 142 | 143 | 144 | 145 | Stops incoming connections. This usually doesn't close existing connections thus can be used 146 | to enforce a certain amount of maximum allowed connections. 147 | 148 | 149 | 150 | 151 | Connects to a given address or room name. 152 | 153 | This call will result in one of those 2 events in response: 154 | * NewConnection if the connection was established 155 | * ConnectionFailed if the connection failed. 156 | 157 | 158 | 159 | A string that identifies the target. 160 | Returns the Connection id the established connection will have (only supported by WebRtcNetwork). 161 | 162 | 163 | 164 | This will allow more detailed access to webrtc for different platforms. Not yet implemented. 165 | 166 | 167 | 168 | 169 | Represents an ice server entry 170 | 171 | 172 | 173 | 174 | Returns a copy of the given urls 175 | 176 | 177 | 178 | 179 | Returns the username 180 | 181 | 182 | 183 | 184 | Returns the credential / password 185 | 186 | 187 | 188 | 189 | Creates an ice server entry with the given urls, username and credential (password, tokens might be supported later) 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | Creates an ice server entry with the given url, username and credential (password, tokens might be supported later) 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | LocalNetwork. Simulate the IBasicNetwork locally in a single applicaiton. 206 | 207 | 208 | 209 | 210 | 211 | 212 | This interface is used to return binary message data. 213 | 214 | Use MessageDataBuffer.Buffer only to read data between 215 | the index Offset and Offset + MessageDataBuffer.ContentLength. 216 | 217 | After reading use Dispose to allow the network to 218 | reuse this buffer and spare the Garbage Collector 219 | the work. 220 | 221 | Make sure not to keep any references to 222 | MessageDataBuffer.Buffer after calling Dispose! 223 | If you need to store the byte array create a copy 224 | of the content before using Dispose. 225 | 226 | 227 | 228 | 229 | Returns the buffer that contains the message data. 230 | Don't use Buffer.Length! The buffer might be longer than the actually message. 231 | use ContentLength to get the length of the content 232 | 233 | 234 | 235 | 236 | Returns the length of the buffers content. 237 | The byte array might be longer than the actual content! 238 | Always use this property not Buffer.Length !!! 239 | 240 | 241 | 242 | 243 | Reads the byte buffer as a UTF8 string 244 | 245 | 246 | 247 | 248 | 249 | 250 | Reads the buffer as unicode string 251 | 252 | 253 | 254 | 255 | 256 | 257 | Type of the received network event. 258 | 259 | 260 | 261 | 262 | Contains information about events received by the network. 263 | 264 | The type of the network event decides the content it can contain. 265 | 266 | Most important are: 267 | 268 | UnreliableMessageReceived / ReliableMessageReceived: 269 | A new message was received. The property MessageData will return 270 | a buffer + byte array containing the data received. 271 | 272 | ServerInitialized: 273 | A call to StartServer was successful. The Info property will return the address 274 | the server can be accessed by. 275 | 276 | 277 | 278 | 279 | 280 | 281 | Returns the type of the message. 282 | 283 | 284 | 285 | 286 | Returns the related connection id or ConnecitonId.Invalid if there is none. 287 | 288 | 289 | 290 | 291 | Returns an object belonging to the event. 292 | This can be a MessageDataBuffer containing a byte array or a string. 293 | 294 | 295 | 296 | 297 | Returns the content of the messages if the event type is 298 | UnreliableMessageReceived or ReliableMessageReceived. 299 | 300 | null for all other message types. 301 | 302 | 303 | 304 | 305 | Returns the a copy of the message data as a new byte array with the exact size of the content 306 | instead of the buffer. 307 | 308 | Copy of the message data or null if no message data available 309 | 310 | 311 | 312 | Contains additional information or null 313 | Only used so far for NetEventType.ServerInitialized to return the servers address information. 314 | 315 | 316 | 317 | 318 | Creates a new network event of a certain type setting 319 | connection id to invalid and data to null. 320 | 321 | Internal only. Do not use. 322 | 323 | The type of this event 324 | 325 | 326 | 327 | Creates a network event with the given content 328 | 329 | Internal only. Do not use. 330 | 331 | Type name 332 | ConnectionId the event is from / relates to 333 | Data. String or MessageDataBuffer 334 | 335 | 336 | 337 | Converts the event to string. Use for debugging only. 338 | 339 | A string representation of the network event. 340 | 341 | 342 | 343 | Reverse of ToByteArray. 344 | 345 | 346 | 347 | 348 | 349 | 350 | Mainly used by WebsocketNetwork. It serializes network events into a byte array to allow 351 | to process the events on a different system than where it actually occurred. 352 | 353 | e.g. WebsocketNetwork uses a server that will receive incoming connects and then 354 | serializes that event into a byte array and send it to the client which holds the 355 | address of the incoming connection to process the event 356 | 357 | NOTE: This method is not optimized and shouldn't be used with a lot of data! 358 | 359 | Network event to be serialized 360 | Newly created byte array representing the network event 361 | 362 | 363 | 364 | Logger used in the Byn namespace. Use SetLogger 365 | to log custom messages and implement your own filter. 366 | Object is the source of the log and string contains a list of 367 | tags related to the message to make filtering easier. 368 | 369 | Note the logging system isn't fully implemented. 370 | 371 | 372 | 373 | 374 | Special tag always used in LW calls 375 | 376 | Used for calls that might negatively affect the program. 377 | 378 | 379 | 380 | 381 | Always used in LE calls. 382 | Used for calls that affect the behavior of the program 383 | 384 | 385 | 386 | 387 | Always used in LogException calls 388 | 389 | 390 | 391 | 392 | Always used L calls. 393 | Log message that should always be delivered to the end user but 394 | are not essential. 395 | 396 | 397 | 398 | 399 | 400 | Used for LD calls 401 | 402 | 403 | 404 | 405 | Used for LV calls 406 | 407 | 408 | 409 | 410 | Used to receive the logging messages. 411 | 412 | Use the string[] in the callback to filter the log messages 413 | based on tags. 414 | 415 | 416 | 417 | 418 | 419 | Logs an exception. 420 | 421 | message as string or object that implements toString 422 | 423 | 424 | 425 | 426 | Logs an error. 427 | 428 | message as string or object that implements toString 429 | 430 | 431 | 432 | 433 | Logs a warning 434 | 435 | message as string or object that implements toString 436 | 437 | 438 | 439 | 440 | Verbose log. Only available in debug mode! 441 | Used for logging pretty much anything. 442 | 443 | Might require an additional flag for verbose mode in the future to avoid 444 | wasting CPU time / generating too much garbage for the GC 445 | 446 | message as string or object that implements toString 447 | 448 | 449 | 450 | 451 | Used for debugging. Only used for current updates that need to be tested! 452 | 453 | 454 | 455 | 456 | 457 | 458 | Default log. Unless LD and LV this log will always be available. 459 | 460 | Used to log important events that might help debugging crashes but not 461 | something that happens on a frame - frame basis! 462 | 463 | 464 | 465 | 466 | 467 | 468 | -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Native.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Native.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Native.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Native.dll.mdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Native.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Native.pdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Websocket.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Websocket.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Websocket.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Websocket.dll.mdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Websocket.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/Byn.Net.Websocket.pdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/WebGL/WebRtcNetwork.jslib: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | 7 | var UnityWebRtcNetwork = 8 | { 9 | UnityWebRtcNetworkIsAvailable:function() 10 | { 11 | if(typeof CAPIWebRtcNetworkIsAvailable === 'function') 12 | { 13 | return CAPIWebRtcNetworkIsAvailable(); 14 | } 15 | return false; 16 | }, 17 | UnityWebRtcNetworkCreate:function(lConfiguration) 18 | { 19 | return CAPIWebRtcNetworkCreate(Pointer_stringify(lConfiguration)); 20 | }, 21 | UnityWebRtcNetworkRelease:function(lIndex) 22 | { 23 | CAPIWebRtcNetworkRelease(lIndex); 24 | }, 25 | UnityWebRtcNetworkConnect:function(lIndex, lRoom) 26 | { 27 | return CAPIWebRtcNetworkConnect(lIndex, Pointer_stringify(lRoom)); 28 | }, 29 | UnityWebRtcNetworkStartServer:function(lIndex, lRoom) 30 | { 31 | CAPIWebRtcNetworkStartServer(lIndex, Pointer_stringify(lRoom)); 32 | }, 33 | UnityWebRtcNetworkStopServer:function(lIndex) 34 | { 35 | CAPIWebRtcNetworkStopServer(lIndex); 36 | }, 37 | UnityWebRtcNetworkDisconnect:function(lIndex, lConnectionId) 38 | { 39 | CAPIWebRtcNetworkDisconnect(lIndex, lConnectionId); 40 | }, 41 | UnityWebRtcNetworkShutdown:function(lIndex) 42 | { 43 | CAPIWebRtcNetworkShutdown(lIndex); 44 | }, 45 | UnityWebRtcNetworkUpdate:function(lIndex) 46 | { 47 | CAPIWebRtcNetworkUpdate(lIndex); 48 | }, 49 | UnityWebRtcNetworkFlush:function(lIndex) 50 | { 51 | CAPIWebRtcNetworkFlush(lIndex); 52 | }, 53 | UnityWebRtcNetworkSendData:function(lIndex, lConnectionId, lUint8ArrayDataPtr, lUint8ArrayDataOffset, lUint8ArrayDataLength, lReliable) 54 | { 55 | var sndReliable = true; 56 | if(lReliable == false || lReliable == 0 || lReliable == "false" || lReliable == "False") 57 | sndReliable = false; 58 | CAPIWebRtcNetworkSendDataEm(lIndex, lConnectionId, HEAPU8, lUint8ArrayDataPtr + lUint8ArrayDataOffset, lUint8ArrayDataLength, sndReliable); 59 | }, 60 | UnityWebRtcNetworkPeekEventDataLength:function(lIndex) 61 | { 62 | return CAPIWebRtcNetworkPeekEventDataLength(lIndex); 63 | }, 64 | UnityWebRtcNetworkDequeue:function(lIndex, lTypeIntArrayPtr, lConidIntArrayPtr, lUint8ArrayDataPtr, lUint8ArrayDataOffset, lUint8ArrayDataLength, lDataLenIntArrayPtr ) 65 | { 66 | var val = CAPIWebRtcNetworkDequeueEm(lIndex, HEAP32, lTypeIntArrayPtr >> 2, HEAP32, lConidIntArrayPtr >> 2, HEAPU8, lUint8ArrayDataPtr + lUint8ArrayDataOffset, lUint8ArrayDataLength, HEAP32, lDataLenIntArrayPtr >> 2); 67 | return val; 68 | }, 69 | UnityWebRtcNetworkPeek:function(lIndex, lTypeIntArrayPtr, lConidIntArrayPtr, lUint8ArrayDataPtr, lUint8ArrayDataOffset, lUint8ArrayDataLength, lDataLenIntArrayPtr ) 70 | { 71 | var val = CAPIWebRtcNetworkPeekEm(lIndex, HEAP32, lTypeIntArrayPtr >> 2, HEAP32, lConidIntArrayPtr >> 2, HEAPU8, lUint8ArrayDataPtr + lUint8ArrayDataOffset, lUint8ArrayDataLength, HEAP32, lDataLenIntArrayPtr >> 2); 72 | return val; 73 | } 74 | }; 75 | 76 | mergeInto(LibraryManager.library, UnityWebRtcNetwork); -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/WebRtcCSharp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/WebRtcCSharp.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/WebRtcCSharp.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/WebRtcCSharp.dll.mdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/WebRtcCSharp.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/WebRtcCSharp.pdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/WebSocketSharpUnityMod.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/WebSocketSharpUnityMod.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/WebSocketSharpUnityMod.dll.mdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/WebSocketSharpUnityMod.dll.mdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/WebSocketSharpUnityMod.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/WebSocketSharpUnityMod.pdb -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/android/armeabi-v7a/libwebrtccsharpwrap.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/android/armeabi-v7a/libwebrtccsharpwrap.so -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/android/libjingle_peerconnection_java.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/android/libjingle_peerconnection_java.jar -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/android/readme.txt: -------------------------------------------------------------------------------- 1 | Copy the AndroidManifest.xml to Assets\Plugins\Android to include it into android builds! -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/mac/x64/webrtccsharpwrap.bundle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/mac/x64/webrtccsharpwrap.bundle -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/win/x64/webrtccsharpwrap.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/win/x64/webrtccsharpwrap.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/Plugins/win/x86/webrtccsharpwrap.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/Plugins/win/x86/webrtccsharpwrap.dll -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/changelog.txt: -------------------------------------------------------------------------------- 1 | Change Log 2 | 0.973 3 | - BUG0006 fixed: Disposing of message buffers could cause stalling / exceptions 4 | 5 | 0.972 - Update WebRTC version to the same as Chrome 53 6 | - Stun server and signaling server can be changed in prefabs 7 | - Bugfixes 8 | 9 | 0.97 - Added support for Android and OSX (Video support isn't stable yet and might lead to crashes!) 10 | - Clean up of the CallApp 11 | 12 | 0.96 - Added support for broadcast / multicast networks 13 | - Added server node.js app (see server.zip) 14 | 15 | 0.95 - Mayor rewrite 16 | * Added support for the native library 17 | * Updated factory and interfaces to support both: native and browser based WebRTC 18 | * Replaced firebase signaling with a websocket signaling protocol using the same IBasicNetwork interface as the WebRTC network 19 | * Moved the browser based library out of this project. webrtcnetworkplugin.txt contains the js code 20 | (based on a new typescript version) 21 | 22 | If you want to use the old browser version of WebRTC Network check out 23 | https://github.com/devluz/webrtcnetwork 24 | 25 | 0.9 - Initial release 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/example/ChatApp.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using UnityEngine; 7 | using System.Collections; 8 | using UnityEngine.UI; 9 | using System.Text; 10 | using System; 11 | using Byn.Net; 12 | using System.Collections.Generic; 13 | using Byn.Common; 14 | 15 | /// 16 | /// Contains a complete chat example. 17 | /// It can run on Windows x86/x64 and in browsers. More platforms will be added soon. 18 | /// 19 | /// The chat app will report during start which system it uses. 20 | /// 21 | /// The user can enter a room name and click the "Open room" button to start a server and wait for 22 | /// incoming connections or use the "Join room" button to join an already existing room. 23 | /// 24 | /// 25 | /// 26 | /// 27 | /// As the system implements a server/client style connection all messages will first be sent to the 28 | /// server and the server delivers it to each client. The server side ConnectionId is used to 29 | /// identify a user. 30 | /// 31 | /// 32 | /// 33 | public class ChatApp : MonoBehaviour 34 | { 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | /// 43 | /// This is a test server. Don't use in production! The server code is in a zip file in WebRtcNetwork 44 | /// 45 | public string uSignalingUrl = "wss://because-why-not.com:12777/chatapp"; 46 | 47 | /// 48 | /// Mozilla stun server. Used to get trough the firewall and establish direct connections. 49 | /// Replace this with your own production server as well. 50 | /// 51 | public string uStunServer = "stun:stun.l.google.com:19302"; 52 | 53 | /// 54 | /// Set true to use send the WebRTC log + wrapper log output to the unity log. 55 | /// 56 | public bool uLog = false; 57 | 58 | /// 59 | /// Debug console to be able to see the unity log on every platform 60 | /// 61 | public bool uDebugConsole = false; 62 | 63 | #region UI 64 | /// 65 | /// Input field used to enter the room name. 66 | /// 67 | public InputField uRoomName; 68 | 69 | /// 70 | /// Input field to enter a new message. 71 | /// 72 | public InputField uMessageInput; 73 | 74 | /// 75 | /// Output message list to show incoming and sent messages + output messages of the 76 | /// system itself. 77 | /// 78 | public MessageList uOutput; 79 | 80 | /// 81 | /// Join button to connect to a server. 82 | /// 83 | public Button uJoin; 84 | 85 | /// 86 | /// Send button. 87 | /// 88 | public Button uSend; 89 | 90 | /// 91 | /// Open room button to start a server. 92 | /// 93 | public Button uOpenRoom; 94 | 95 | /// 96 | /// Button to leave the room 97 | /// 98 | public Button uLeave; 99 | #endregion 100 | /// 101 | /// The network interface. 102 | /// This can be native webrtc or the browser webrtc version. 103 | /// (Can also be the old or new unity network but this isn't part of this package) 104 | /// 105 | private IBasicNetwork mNetwork = null; 106 | 107 | /// 108 | /// True if the user opened an own room allowing incoming connections 109 | /// 110 | private bool mIsServer = false; 111 | 112 | /// 113 | /// Keeps track of all current connections 114 | /// 115 | private List mConnections = new List(); 116 | 117 | 118 | private const int MAX_CODE_LENGTH = 256; 119 | 120 | 121 | 122 | /// 123 | /// Will setup webrtc and create the network object 124 | /// 125 | private void Start () 126 | { 127 | //shows the console on all platforms. for debugging only 128 | if(uDebugConsole) 129 | DebugHelper.ActivateConsole(); 130 | if(uLog) 131 | SLog.SetLogger(OnLog); 132 | 133 | SLog.LV("Verbose log is active!"); 134 | SLog.LD("Debug mode is active"); 135 | 136 | Append("Setting up WebRtcNetworkFactory"); 137 | WebRtcNetworkFactory factory = WebRtcNetworkFactory.Instance; 138 | if(factory != null) 139 | Append("WebRtcNetworkFactory created"); 140 | 141 | } 142 | private void OnLog(object msg, string[] tags) 143 | { 144 | StringBuilder builder = new StringBuilder(); 145 | TimeSpan time = DateTime.Now - DateTime.Today; 146 | builder.Append(time); 147 | builder.Append("["); 148 | for (int i = 0; i< tags.Length; i++) 149 | { 150 | if(i != 0) 151 | builder.Append(","); 152 | builder.Append(tags[i]); 153 | } 154 | builder.Append("]"); 155 | builder.Append(msg); 156 | Debug.Log(builder.ToString()); 157 | } 158 | 159 | private void Setup() 160 | { 161 | Append("Initializing webrtc network"); 162 | 163 | 164 | mNetwork = WebRtcNetworkFactory.Instance.CreateDefault(uSignalingUrl, new IceServer[] { new IceServer(uStunServer) }); 165 | if (mNetwork != null) 166 | { 167 | Append("WebRTCNetwork created"); 168 | } 169 | else 170 | { 171 | Append("Failed to access webrtc "); 172 | } 173 | SetGuiState(false); 174 | } 175 | 176 | private void Reset() 177 | { 178 | Debug.Log("Cleanup!"); 179 | 180 | mIsServer = false; 181 | mConnections = new List(); 182 | Cleanup(); 183 | SetGuiState(true); 184 | } 185 | 186 | /// 187 | /// called during reset and destroy 188 | /// 189 | private void Cleanup() 190 | { 191 | mNetwork.Dispose(); 192 | mNetwork = null; 193 | } 194 | 195 | private void OnDestroy() 196 | { 197 | if (mNetwork != null) 198 | { 199 | Cleanup(); 200 | } 201 | } 202 | 203 | private void FixedUpdate() 204 | { 205 | //check each fixed update if we have got new events 206 | HandleNetwork(); 207 | } 208 | private void HandleNetwork() 209 | { 210 | //check if the network was created 211 | if (mNetwork != null) 212 | { 213 | //first update it to read the data from the underlaying network system 214 | mNetwork.Update(); 215 | 216 | //handle all new events that happened since the last update 217 | NetworkEvent evt; 218 | //check for new messages and keep checking if mNetwork is available. it might get destroyed 219 | //due to an event 220 | while (mNetwork != null && mNetwork.Dequeue(out evt)) 221 | { 222 | //print to the console for debugging 223 | Debug.Log(evt); 224 | 225 | //check every message 226 | switch (evt.Type) 227 | { 228 | case NetEventType.ServerInitialized: 229 | { 230 | //server initialized message received 231 | //this is the reaction to StartServer -> switch GUI mode 232 | mIsServer = true; 233 | string address = evt.Info; 234 | Append("Server started. Address: " + address); 235 | uRoomName.text = "" + address; 236 | } break; 237 | case NetEventType.ServerInitFailed: 238 | { 239 | //user tried to start the server but it failed 240 | //maybe the user is offline or signaling server down? 241 | mIsServer = false; 242 | Append("Server start failed."); 243 | Reset(); 244 | } break; 245 | case NetEventType.ServerClosed: 246 | { 247 | //server shut down. reaction to "Shutdown" call or 248 | //StopServer or the connection broke down 249 | mIsServer = false; 250 | Append("Server closed. No incoming connections possible until restart."); 251 | } break; 252 | case NetEventType.NewConnection: 253 | { 254 | mConnections.Add(evt.ConnectionId); 255 | //either user runs a client and connected to a server or the 256 | //user runs the server and a new client connected 257 | Append("New local connection! ID: " + evt.ConnectionId); 258 | 259 | //if server -> send announcement to everyone and use the local id as username 260 | if(mIsServer) 261 | { 262 | //user runs a server. announce to everyone the new connection 263 | //using the server side connection id as identification 264 | string msg = "New user " + evt.ConnectionId + " joined the room."; 265 | Append(msg); 266 | //SendString(msg); 267 | } 268 | } break; 269 | case NetEventType.ConnectionFailed: 270 | { 271 | //Outgoing connection failed. Inform the user. 272 | Append("Connection failed"); 273 | Reset(); 274 | } break; 275 | case NetEventType.Disconnected: 276 | { 277 | mConnections.Remove(evt.ConnectionId); 278 | //A connection was disconnected 279 | //If this was the client then he was disconnected from the server 280 | //if it was the server this just means that one of the clients left 281 | Append("Local Connection ID " + evt.ConnectionId + " disconnected"); 282 | if (mIsServer == false) 283 | { 284 | Reset(); 285 | } 286 | else 287 | { 288 | string userLeftMsg = "User " + evt.ConnectionId + " left the room."; 289 | 290 | //show the server the message 291 | Append(userLeftMsg); 292 | 293 | //other users left? inform them 294 | if (mConnections.Count > 0) 295 | { 296 | // SendString(userLeftMsg); 297 | } 298 | } 299 | } break; 300 | case NetEventType.ReliableMessageReceived: 301 | { 302 | HandleIncommingMessage(ref evt); 303 | 304 | 305 | 306 | 307 | } break; 308 | case NetEventType.UnreliableMessageReceived: 309 | { 310 | HandleIncommingMessage(ref evt); 311 | } break; 312 | } 313 | } 314 | 315 | //finish this update by flushing the messages out if the network wasn't destroyed during update 316 | if(mNetwork != null) 317 | mNetwork.Flush(); 318 | } 319 | } 320 | 321 | private void HandleIncommingMessage(ref NetworkEvent evt) 322 | { 323 | MessageDataBuffer buffer = (MessageDataBuffer)evt.MessageData; 324 | 325 | if (buffer.Buffer[0] == 0) 326 | { 327 | 328 | 329 | } 330 | 331 | string msg = Encoding.UTF8.GetString(buffer.Buffer, 0, buffer.ContentLength); 332 | 333 | //if server -> forward the message to everyone else including the sender 334 | if (mIsServer) 335 | { 336 | //we use the server side connection id to identify the client 337 | string idAndMessage = evt.ConnectionId + ":" + msg; 338 | SendString(idAndMessage); 339 | Append(idAndMessage); 340 | } 341 | else 342 | { 343 | //client received a message from the server -> simply print 344 | Append(msg); 345 | } 346 | 347 | //return the buffer so the network can reuse it 348 | buffer.Dispose(); 349 | } 350 | 351 | 352 | /// 353 | /// Sends a string as UTF8 byte array to all connections 354 | /// 355 | /// String containing the message to send 356 | /// false to use unreliable messages / true to use reliable messages 357 | private void SendString(string msg, bool reliable = true) 358 | { 359 | if (mNetwork == null || mConnections.Count == 0) 360 | { 361 | Append("No connection. Can't send message."); 362 | } 363 | else 364 | { 365 | byte[] msgData = Encoding.UTF8.GetBytes(msg); 366 | foreach (ConnectionId id in mConnections) 367 | { 368 | mNetwork.SendData(id, msgData, 0, msgData.Length, reliable); 369 | } 370 | } 371 | } 372 | 373 | 374 | 375 | #region UI 376 | 377 | private void OnGUI() 378 | { 379 | //draws the debug console (or the show button in the corner to open it) 380 | DebugHelper.DrawConsole(); 381 | } 382 | 383 | /// 384 | /// Adds a new message to the message view 385 | /// 386 | /// 387 | private void Append(string text) 388 | { 389 | Debug.Log("chat: " + text); 390 | uOutput.AddTextEntry(text); 391 | } 392 | 393 | 394 | /// 395 | /// Changes the gui depending on if the user is connected 396 | /// or disconnected 397 | /// 398 | /// true = user is connected. false = user isn't connected 399 | private void SetGuiState(bool showSetup) 400 | { 401 | uJoin.interactable = showSetup; 402 | uOpenRoom.interactable = showSetup; 403 | 404 | uSend.interactable = !showSetup; 405 | uLeave.interactable = !showSetup; 406 | uMessageInput.interactable = !showSetup; 407 | } 408 | 409 | /// 410 | /// Join button pressed. Tries to join a room. 411 | /// 412 | public void JoinRoomButtonPressed() 413 | { 414 | Setup(); 415 | mNetwork.Connect(uRoomName.text); 416 | Append("Connecting to " + uRoomName.text + " ..."); 417 | } 418 | private void EnsureLength() 419 | { 420 | if(uRoomName.text.Length > MAX_CODE_LENGTH) 421 | { 422 | uRoomName.text = uRoomName.text.Substring(0, MAX_CODE_LENGTH); 423 | } 424 | } 425 | 426 | /// 427 | /// Shuts the app down and waits for a restart 428 | /// 429 | public void LeaveButtonPressed() 430 | { 431 | Reset(); 432 | SetGuiState(true); 433 | } 434 | /// 435 | /// Open room button pressed. 436 | /// 437 | /// Opens a room / starts a server 438 | /// 439 | public void OpenRoomButtonPressed() 440 | { 441 | Setup(); 442 | EnsureLength(); 443 | mNetwork.StartServer(uRoomName.text); 444 | 445 | Debug.Log("StartServer " + uRoomName.text); 446 | } 447 | 448 | public void InputOnEndEdit() 449 | { 450 | if (Input.GetKey(KeyCode.Return)) 451 | { 452 | SendButtonPressed(); 453 | } 454 | } 455 | 456 | /// 457 | /// This is called if the send button 458 | /// 459 | public void SendButtonPressed() 460 | { 461 | //get the message written into the text field 462 | string msg = uMessageInput.text; 463 | 464 | 465 | if (msg.StartsWith("/disconnect")) 466 | { 467 | string[] slt = msg.Split(' '); 468 | if(slt.Length >= 2) 469 | { 470 | ConnectionId conId; 471 | if (short.TryParse(slt[1], out conId.id)) 472 | { 473 | mNetwork.Disconnect(conId); 474 | } 475 | } 476 | } 477 | 478 | //if we are the server -> add 0 in front as the server id 479 | if(mIsServer) 480 | { 481 | //the server has the authority thus -> we can print it directly adding the 0 as server id 482 | msg = "0:" + msg; 483 | Append(msg); 484 | SendString(msg); 485 | } 486 | else 487 | { 488 | //clients just send it directly to the server. the server will decide what to do with it 489 | SendString(msg); 490 | } 491 | uMessageInput.text = ""; 492 | 493 | //make sure the text box is in focus again so the user can continue typing without clicking it again 494 | //select another element first. without this the input field is in focus after return pressed 495 | uSend.Select(); 496 | uMessageInput.Select(); 497 | } 498 | #endregion 499 | } 500 | -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/example/DebugHelper.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using UnityEngine; 11 | 12 | /// 13 | /// Shows the console on all platforms. For debugging. 14 | /// 15 | public class DebugHelper 16 | { 17 | public static bool sShowConsole = false; 18 | public static bool sConsoleAutoScroll = true; 19 | 20 | private static Vector2 mDebugConsoleScrollPos = new Vector2(); 21 | private static StringBuilder mLog = null; 22 | private static int mLines = 0; 23 | 24 | public static void ActivateConsole() 25 | { 26 | if (mLog != null) 27 | return; 28 | mLog = new StringBuilder(); 29 | Application.logMessageReceived += LogType; 30 | } 31 | private static void LogType(string condition, string stackTrace, LogType type) 32 | { 33 | int lines = 0; 34 | mLog.Append(condition); 35 | if (type == UnityEngine.LogType.Exception) 36 | { 37 | lines += stackTrace.Count((x) => { return x == '\n'; }); 38 | mLog.Append(stackTrace); 39 | } 40 | mLog.Append("\n"); 41 | lines++; 42 | 43 | mLines += lines; 44 | 45 | int foundLines = 0; 46 | for (int i = mLog.Length - 1; i >= 0; i--) 47 | { 48 | if (mLog[i] == '\n') 49 | { 50 | foundLines++; 51 | if (foundLines == 100) 52 | { 53 | mLog.Remove(0, i + 1); 54 | break; 55 | } 56 | } 57 | } 58 | } 59 | public static void DrawConsole() 60 | { 61 | if (mLog == null) 62 | return;; 63 | 64 | if (sShowConsole == false) 65 | { 66 | if (GUI.Button(new Rect(Screen.width - 40, Screen.height - 20, 40, 20), "Show")) 67 | { 68 | sShowConsole = true; 69 | } 70 | } 71 | else 72 | { 73 | if (GUI.Button(new Rect(Screen.width - 40, Screen.height * 0.75f - 20, 40, 20), "Hide")) 74 | { 75 | sShowConsole = false; 76 | } 77 | if (GUI.Button(new Rect(Screen.width - 90, Screen.height * 0.75f - 20, 40, 20), "Auto")) 78 | { 79 | sConsoleAutoScroll = !sConsoleAutoScroll; 80 | } 81 | 82 | GUIStyle textStyle = new GUIStyle(); 83 | 84 | textStyle.normal.textColor = Color.white; 85 | textStyle.richText = true; 86 | 87 | GUI.Box(new Rect(0, Screen.height * 0.75f, Screen.width, Screen.height * 0.25f), ""); 88 | GUILayout.BeginArea(new Rect(0, Screen.height * 0.75f, Screen.width, Screen.height * 0.25f)); 89 | mDebugConsoleScrollPos = GUILayout.BeginScrollView(mDebugConsoleScrollPos); 90 | if(sConsoleAutoScroll) 91 | mDebugConsoleScrollPos = new Vector2(0, 1000000000); 92 | GUILayout.TextArea(mLog.ToString(), textStyle); 93 | GUILayout.EndScrollView(); 94 | GUILayout.EndArea(); 95 | } 96 | } 97 | } -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/example/MessageList.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using UnityEngine; 7 | using System.Collections; 8 | using System.Collections.Generic; 9 | using UnityEngine.UI; 10 | 11 | /// 12 | /// Shows a list of a text prefab. 13 | /// 14 | /// Used to show the messages that are sent/received in the ChatApp. 15 | /// 16 | public class MessageList : MonoBehaviour 17 | { 18 | /// 19 | /// References to the "Text" prefab. 20 | /// 21 | /// Needs to contain RectTransform and Text element. 22 | /// 23 | public GameObject uEntryPrefab; 24 | 25 | 26 | 27 | /// 28 | /// Reference to the own rect transform 29 | /// 30 | private RectTransform mOwnTransform; 31 | 32 | /// 33 | /// Number of messages until the older messages will be deleted. 34 | /// 35 | private int mMaxMessages = 50; 36 | 37 | 38 | private int mCounter = 0; 39 | 40 | private void Awake() 41 | { 42 | mOwnTransform = this.GetComponent(); 43 | } 44 | 45 | private void Start() 46 | { 47 | foreach(var v in mOwnTransform.GetComponentsInChildren()) 48 | { 49 | if(v != mOwnTransform) 50 | { 51 | v.name = "Element " + mCounter; 52 | mCounter++; 53 | } 54 | } 55 | } 56 | 57 | /// 58 | /// Allows the Chatapp to add new entires to the list 59 | /// 60 | /// Text to be added 61 | public void AddTextEntry(string text) 62 | { 63 | GameObject ngp = Instantiate(uEntryPrefab); 64 | Text t = ngp.GetComponentInChildren(); 65 | t.text = text; 66 | 67 | RectTransform transform = ngp.GetComponent(); 68 | transform.SetParent(mOwnTransform, false); 69 | 70 | GameObject go = transform.gameObject; 71 | go.name = "Element " + mCounter; 72 | mCounter++; 73 | } 74 | 75 | 76 | /// 77 | /// Destroys old messages if needed and repositions the existing messages. 78 | /// 79 | private void Update() 80 | { 81 | int destroy = mOwnTransform.childCount - mMaxMessages; 82 | for(int i = 0; i < destroy; i++) 83 | { 84 | var child = mOwnTransform.GetChild(i).gameObject; 85 | Destroy(child); 86 | } 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/example/Text.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &109896 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_PrefabParentObject: {fileID: 0} 7 | m_PrefabInternal: {fileID: 100100000} 8 | serializedVersion: 4 9 | m_Component: 10 | - 224: {fileID: 22437312} 11 | - 222: {fileID: 22231624} 12 | - 114: {fileID: 11421282} 13 | m_Layer: 5 14 | m_Name: Text 15 | m_TagString: Untagged 16 | m_Icon: {fileID: 0} 17 | m_NavMeshLayer: 0 18 | m_StaticEditorFlags: 0 19 | m_IsActive: 1 20 | --- !u!114 &11421282 21 | MonoBehaviour: 22 | m_ObjectHideFlags: 1 23 | m_PrefabParentObject: {fileID: 0} 24 | m_PrefabInternal: {fileID: 100100000} 25 | m_GameObject: {fileID: 109896} 26 | m_Enabled: 1 27 | m_EditorHideFlags: 0 28 | m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3} 29 | m_Name: 30 | m_EditorClassIdentifier: 31 | m_Material: {fileID: 0} 32 | m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} 33 | m_RaycastTarget: 1 34 | m_OnCullStateChanged: 35 | m_PersistentCalls: 36 | m_Calls: [] 37 | m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, 38 | Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 39 | m_FontData: 40 | m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} 41 | m_FontSize: 14 42 | m_FontStyle: 0 43 | m_BestFit: 0 44 | m_MinSize: 10 45 | m_MaxSize: 40 46 | m_Alignment: 3 47 | m_AlignByGeometry: 1 48 | m_RichText: 1 49 | m_HorizontalOverflow: 0 50 | m_VerticalOverflow: 1 51 | m_LineSpacing: 1 52 | m_Text: Call App started 53 | --- !u!222 &22231624 54 | CanvasRenderer: 55 | m_ObjectHideFlags: 1 56 | m_PrefabParentObject: {fileID: 0} 57 | m_PrefabInternal: {fileID: 100100000} 58 | m_GameObject: {fileID: 109896} 59 | --- !u!224 &22437312 60 | RectTransform: 61 | m_ObjectHideFlags: 1 62 | m_PrefabParentObject: {fileID: 0} 63 | m_PrefabInternal: {fileID: 100100000} 64 | m_GameObject: {fileID: 109896} 65 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 66 | m_LocalPosition: {x: 0, y: 0, z: 0} 67 | m_LocalScale: {x: 1, y: 1, z: 1} 68 | m_Children: [] 69 | m_Father: {fileID: 0} 70 | m_RootOrder: 0 71 | m_AnchorMin: {x: 0, y: 0} 72 | m_AnchorMax: {x: 0, y: 0} 73 | m_AnchoredPosition: {x: 0, y: 0} 74 | m_SizeDelta: {x: 0, y: 0} 75 | m_Pivot: {x: 0.5, y: 1} 76 | --- !u!1001 &100100000 77 | Prefab: 78 | m_ObjectHideFlags: 1 79 | serializedVersion: 2 80 | m_Modification: 81 | m_TransformParent: {fileID: 0} 82 | m_Modifications: 83 | - target: {fileID: 0} 84 | propertyPath: m_SizeDelta.y 85 | value: 20 86 | objectReference: {fileID: 0} 87 | m_RemovedComponents: [] 88 | m_ParentPrefab: {fileID: 0} 89 | m_RootGameObject: {fileID: 109896} 90 | m_IsPrefabParent: 1 91 | -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/license.txt: -------------------------------------------------------------------------------- 1 | Disclaimer: 2 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 3 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 4 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 5 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 6 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 7 | DEALINGS IN THE SOFTWARE. 8 | 9 | 10 | 11 | Unity Asset Store legal and license information: 12 | http://unity3d.com/legal/ -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/readme.txt: -------------------------------------------------------------------------------- 1 | Introduction: 2 | 3 | WebRTC Network is a plugin for Unity WebGL and windows (more coming soon) that allows two 4 | games to connect DIRECTLY to each other and send reliable/unreliable messages using WebRTC 5 | Datachannels. This makes it well suited for any fast paced real time multiplayer games. 6 | 7 | WebRTC still requires a server to initialize the connection between two users. 8 | This version will automatically use a test server for this purpose but you can set up and use your own 9 | server any time. 10 | 11 | Features: 12 | - Very simple programming interface. These are all methods you need: Start/StopServer, Connect, 13 | Disconnect, SendMessage + a Dequeue method to read incomming network events! 14 | - Send messages reliable or unreliable 15 | - Contains a complete chat app as an example 16 | - Platforms supported: WebGL (Firefox, Chrome) + Windows x86 and x64. 17 | - Unlike many other network libraries for unity WebRtcNetwork fully supports peer-to-peer! You can have multiple 18 | incoming and outgoing connections at the same time! 19 | 20 | Note that Google and Mozilla treat WebRTC still as an experimental technology! 21 | If you have any questions feel free to contact me. 22 | 23 | Visit http://because-why-not.com/webrtc/webrtc-network/ to find the detail documentation 24 | + API! 25 | 26 | =============================================================================================================== 27 | Setup: 28 | Make sure you tick "Run in background" in your player settings and add the scene 29 | "WebRtcNetwork\example\chatscene" to your build settings. 30 | 31 | 32 | Example ChatApp: 33 | The chat app allows a user to create or join a chat room. After entering a room the users can 34 | send chat messages to everyone in the room. The user that created the room will act as a server 35 | and relay the messages to all connected users. 36 | 37 | The examples are stored in the folder WebRtcNetwork\example. The file ChatApp.cs contains 38 | most of the code and is fully documented. Use this example to learn how to use the library 39 | to send any data across the network. 40 | 41 | The example contains two instances of the ChatApp. You can simply connect the two instances 42 | or start the programm twice and connect them this way. 43 | 44 | 45 | 46 | Important folders, files and classes: 47 | Assets/WebRtcNetwork/Plugins: 48 | The folder contains all platform specific components of the library. 49 | 50 | WebGL - contains the plugin for WebGL. Make sure it is set to active for WebGL! 51 | win/x64 - contains the 64-bit version for Windows. Needs to be activated for 52 | Unity Editor x86_x64 Windows and Standalone x86_x64 Windows 53 | win/x86 - same but for 32 Bit Windows Standalone and Unity Editor 54 | 55 | Byn.Common.dll - contains the IBasicNetwork interface and reusable classes for all platforms (keep at Any Platform in unity) 56 | 57 | WebRtcCSharp.dll and Byn.WebRtcNetwork.Native.dll are for all native platforms 58 | (Standalone Windows x86_x64, x64 + Unity Editor x86_x64, x64 but Any Platform should work as well) 59 | 60 | 61 | Assets/WebRtcNetwork/Resources: 62 | Stores a file "webrtcnetworkplugin.txt". It contains the browser side code of the library. It will be 63 | automatically injected into the website during setup. 64 | 65 | Assets/WebRtcNetwork/scripts/WebRtcNetworkFactory.cs: 66 | This cs file contains a factory class that allows you to create new Network objects. 67 | 68 | 69 | Assets/server.zip 70 | Contains an open source example server used for the signaling process of WebRTC. 71 | This is needed to exchange connection information between two peers allowing them 72 | to connect. The library uses a development server by default but for a release 73 | version you need to provide your own server! Extract the file and follow the 74 | instruction of the readme.txt inside. 75 | 76 | 77 | Do you have questions or problems using the library? 78 | You can find up to date contact information at http://because-why-not.com/about/ and 79 | the newest information about this library at http://because-why-not.com/webrtc-network/ ! 80 | 81 | -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/scripts/BrowserWebRtcNetwork.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Christoph Kutza 3 | * 4 | * Please refer to the LICENSE file for license information 5 | */ 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Runtime.InteropServices; 10 | using System.Text; 11 | using UnityEngine; 12 | 13 | namespace Byn.Net 14 | { 15 | /// 16 | /// Uses an underlaying java script library to give network access in browsers. 17 | /// 18 | /// Use WebRtcNetwork.IsAvailable() first to check if it can run. If the java script part of the library 19 | /// is included + the browser supports WebRtc it should return true. If the java script part of the 20 | /// library is not included you can inject it at runtime by using 21 | /// WebRtcNetwork.InjectJsCode(). It is recommended to include the js files though. 22 | /// 23 | /// To allow incoming connections use StartServer() or StartServer("my room name") 24 | /// To connect others use Connect("room name"); 25 | /// To send messages use SendData. 26 | /// You will need to handle incoming events by polling the Dequeue method. 27 | /// 28 | public class BrowserWebRtcNetwork : IWebRtcNetwork 29 | { 30 | 31 | //these are functions implemented in the java script plugin file WebRtcNetwork.jslib 32 | #region CAPI imports 33 | [DllImport("__Internal")] 34 | private static extern bool UnityWebRtcNetworkIsAvailable(); 35 | 36 | [DllImport("__Internal")] 37 | private static extern int UnityWebRtcNetworkCreate(string lConfiguration); 38 | 39 | [DllImport("__Internal")] 40 | private static extern void UnityWebRtcNetworkRelease(int lIndex); 41 | 42 | [DllImport("__Internal")] 43 | private static extern int UnityWebRtcNetworkConnect(int lIndex, string lRoom); 44 | 45 | [DllImport("__Internal")] 46 | private static extern void UnityWebRtcNetworkStartServer(int lIndex, string lRoom); 47 | [DllImport("__Internal")] 48 | private static extern void UnityWebRtcNetworkStopServer(int lIndex); 49 | 50 | [DllImport("__Internal")] 51 | private static extern void UnityWebRtcNetworkDisconnect(int lIndex, int lConnectionId); 52 | 53 | [DllImport("__Internal")] 54 | private static extern void UnityWebRtcNetworkShutdown(int lIndex); 55 | [DllImport("__Internal")] 56 | private static extern void UnityWebRtcNetworkUpdate(int lIndex); 57 | [DllImport("__Internal")] 58 | private static extern void UnityWebRtcNetworkFlush(int lIndex); 59 | 60 | [DllImport("__Internal")] 61 | private static extern void UnityWebRtcNetworkSendData(int lIndex, int lConnectionId, byte[] lUint8ArrayDataPtr, int lUint8ArrayDataOffset, int lUint8ArrayDataLength, bool lReliable); 62 | 63 | [DllImport("__Internal")] 64 | private static extern int UnityWebRtcNetworkPeekEventDataLength(int lIndex); 65 | 66 | [DllImport("__Internal")] 67 | private static extern bool UnityWebRtcNetworkDequeue(int lIndex, 68 | int[] lTypeIntArrayPtr, 69 | int[] lConidIntArrayPtr, 70 | byte[] lUint8ArrayDataPtr, int lUint8ArrayDataOffset, int lUint8ArrayDataLength, 71 | int[] lDataLenIntArray); 72 | [DllImport("__Internal")] 73 | private static extern bool UnityWebRtcNetworkPeek(int lIndex, 74 | int[] lTypeIntArrayPtr, 75 | int[] lConidIntArrayPtr, 76 | byte[] lUint8ArrayDataPtr, int lUint8ArrayDataOffset, int lUint8ArrayDataLength, 77 | int[] lDataLenIntArray); 78 | #endregion 79 | 80 | private static bool sInjectionTried = false; 81 | 82 | /// 83 | /// This injects the library using ExternalEval. Browsers seem to load some libraries asynchronously though. 84 | /// This means that directly after InjectJsCode some things aren't available yet. 85 | /// So starting a server/connecting won't work directly after this call yet. Add at least 1-2 seconds waiting time 86 | /// for the browser to download the libraries or better -> include everything needed into the websites header 87 | /// so this call isn't needed at all! 88 | /// 89 | static public void InjectJsCode() 90 | { 91 | 92 | //use sInjectionTried to block multiple calls. 93 | if (Application.platform == RuntimePlatform.WebGLPlayer && sInjectionTried == false) 94 | { 95 | sInjectionTried = true; 96 | Debug.Log("injecting webrtcnetworkplugin"); 97 | TextAsset txt = Resources.Load("webrtcnetworkplugin"); 98 | if(txt == null) 99 | { 100 | Debug.LogError("Failed to find webrtcnetworkplugin.txt in Resource folder. Can't inject the JS plugin!"); 101 | return; 102 | } 103 | Application.ExternalEval(txt.text); 104 | } 105 | } 106 | /// 107 | /// Will return true if the environment supports the WebRTCNetwork plugin 108 | /// (needs to run in Chrome or Firefox + the javascript file needs to be loaded in the html page!) 109 | /// 110 | /// 111 | /// 112 | public static bool IsAvailable() 113 | { 114 | try 115 | { 116 | return UnityWebRtcNetworkIsAvailable(); 117 | }catch(EntryPointNotFoundException) 118 | { 119 | //not available at all 120 | return false; 121 | } 122 | } 123 | 124 | 125 | protected int mReference = -1; 126 | 127 | /// 128 | /// Returns true if the server is running or the client is connected. 129 | /// 130 | public bool IsRunning 131 | { 132 | get 133 | { 134 | if (mIsServer) 135 | return true; 136 | 137 | if (mConnections.Count > 0) 138 | return true; 139 | return false; 140 | } 141 | } 142 | 143 | private bool mIsServer = false; 144 | /// 145 | /// True if the server is running allowing incoming connections 146 | /// 147 | public bool IsServer 148 | { 149 | get { return mIsServer; } 150 | } 151 | 152 | 153 | 154 | 155 | 156 | private List mConnections = new List(); 157 | 158 | 159 | 160 | private int[] mTypeidBuffer = new int[1]; 161 | private int[] mConidBuffer = new int[1]; 162 | private int[] mDataWrittenLenBuffer = new int[1]; 163 | 164 | private Queue mEvents = new Queue(); 165 | 166 | 167 | /// 168 | /// Creates a new network by using a JSON configuration string. This is used to configure the server connection for the signaling channel 169 | /// and to define webrtc specific configurations such as stun server used to connect through firewalls. 170 | /// 171 | /// might look like this: 172 | /// string config = "{ 'signaling' : { 'class': 'WebsocketNetwork', 'param' : 'wss://localhost:12777'}, 'iceServers':['stun:stun.l.google.com:19302']}"; 173 | /// 174 | /// Make sure all json " signs are escaped. The JSON object will be parsed in java script and then given to the library. So their content is 175 | /// dependent on the underlaying library. Check out the webrtcnetwork.js to understand the details. 176 | /// 177 | /// 178 | public BrowserWebRtcNetwork(string config) 179 | { 180 | Debug.Log(config); 181 | mReference = UnityWebRtcNetworkCreate(config); 182 | } 183 | /// 184 | /// For subclasses that provide their own init process 185 | /// 186 | protected BrowserWebRtcNetwork() 187 | { 188 | 189 | } 190 | 191 | /// 192 | /// Destructor to make sure everything gets disposed. Sadly, WebGL doesn't seem to call this ever. 193 | /// 194 | ~BrowserWebRtcNetwork() 195 | { 196 | Dispose(false); 197 | } 198 | 199 | /// 200 | /// Disposes the underlaying java script library. If you have long running systems that don't reuse instances make sure 201 | /// you always call dispose as unity doesn't seem to call destructors reliably. You might fill up your java script 202 | /// memory with lots of unused instances. 203 | /// 204 | public void Dispose() 205 | { 206 | Dispose(true); 207 | GC.SuppressFinalize(this); 208 | } 209 | 210 | protected virtual void Dispose(bool disposing) 211 | { 212 | //just to follow the pretty dispose pattern 213 | if (disposing) 214 | { 215 | if (mReference != -1) 216 | { 217 | UnityWebRtcNetworkRelease(mReference); 218 | mReference = -1; 219 | } 220 | } 221 | else 222 | { 223 | if (mReference != -1) 224 | UnityWebRtcNetworkRelease(mReference); 225 | } 226 | } 227 | 228 | /// 229 | /// Starts a server using a random number as address/name. 230 | /// 231 | /// Read the ServerInitialized events Info property to get the address name. 232 | /// 233 | public void StartServer() 234 | { 235 | StartServer("" + UnityEngine.Random.Range(0, 16777216)); 236 | } 237 | 238 | /// 239 | /// Allows to listen to incoming connections using a given name/address. 240 | /// 241 | /// This is in addition to the definition of the IBaseNetwork interface which is 242 | /// shared with other network systems enforcing the use of ip:port as address, thus 243 | /// can't allow custom addresses. 244 | /// 245 | /// Name/Address can be any kind of string. There might be restrictions though depending 246 | /// on the underlaying signaling channel. 247 | /// An invalid name will result in an InitFailed event being return in Dequeue. 248 | public void StartServer(string name) 249 | { 250 | if (this.mIsServer == true) 251 | { 252 | UnityEngine.Debug.LogError("Already in server mode."); 253 | return; 254 | } 255 | UnityWebRtcNetworkStartServer(mReference, name); 256 | } 257 | 258 | public void StopServer() 259 | { 260 | UnityWebRtcNetworkStopServer(mReference); 261 | } 262 | 263 | 264 | /// 265 | /// Connects to the given name or address. 266 | /// 267 | /// The address identifying the server 268 | /// 269 | /// The connection id. (WebRTCNetwork doesn't allow multiple connections yet! So you can ignore this for now) 270 | /// 271 | public ConnectionId Connect(string name) 272 | { 273 | //until fully supported -> block connecting to others while running a server 274 | if (this.mIsServer == true) 275 | { 276 | UnityEngine.Debug.LogError("Can't create outgoing connections while in server mode!"); 277 | return ConnectionId.INVALID; 278 | } 279 | 280 | ConnectionId id = new ConnectionId(); 281 | id.id = (short)UnityWebRtcNetworkConnect(mReference, name); 282 | return id; 283 | } 284 | 285 | 286 | /// 287 | /// Retrieves an event from the js library, handles it internally and then adds it to a queue for delivery to the user. 288 | /// 289 | /// The new network event or an empty struct if none is found. 290 | /// True if event found, false if no events queued. 291 | private bool DequeueInternal(out NetworkEvent evt) 292 | { 293 | int length = UnityWebRtcNetworkPeekEventDataLength(mReference); 294 | if(length == -1) //-1 == no event available 295 | { 296 | evt = new NetworkEvent(); 297 | return false; 298 | } 299 | else 300 | { 301 | ByteArrayBuffer buf = ByteArrayBuffer.Get(length); 302 | bool eventFound = UnityWebRtcNetworkDequeue(mReference, mTypeidBuffer, mConidBuffer, buf.array, 0, buf.array.Length, mDataWrittenLenBuffer); 303 | //set the write correctly 304 | buf.PositionWriteRelative = mDataWrittenLenBuffer[0]; 305 | 306 | NetEventType type = (NetEventType)mTypeidBuffer[0]; 307 | ConnectionId id; 308 | id.id = (short)mConidBuffer[0]; 309 | object data = null; 310 | 311 | if (buf.PositionWriteRelative == 0 || buf.PositionWriteRelative == -1) //no data 312 | { 313 | data = null; 314 | //was an empty buffer -> release it and 315 | buf.Dispose(); 316 | } 317 | else if (type == NetEventType.ReliableMessageReceived || type == NetEventType.UnreliableMessageReceived) 318 | { 319 | //store the data for the user to use 320 | data = buf; 321 | } 322 | else 323 | { 324 | //non data message with data attached -> can only be a string 325 | string stringData = Encoding.ASCII.GetString(buf.array, 0, buf.PositionWriteRelative); 326 | data = stringData; 327 | buf.Dispose(); 328 | 329 | } 330 | 331 | 332 | evt = new NetworkEvent(type, id, data); 333 | UnityEngine.Debug.Log("event" + type + " received"); 334 | HandleEventInternally(ref evt); 335 | return eventFound; 336 | } 337 | 338 | } 339 | 340 | /// 341 | /// Handles events internally. Needed to change the internal states: Server flag and connection id list. 342 | /// 343 | /// Would be better to remove that in the future from the main library and treat it separately. 344 | /// 345 | /// event to handle 346 | private void HandleEventInternally(ref NetworkEvent evt) 347 | { 348 | if(evt.Type == NetEventType.NewConnection) 349 | { 350 | mConnections.Add(evt.ConnectionId); 351 | }else if(evt.Type == NetEventType.Disconnected) 352 | { 353 | mConnections.Remove(evt.ConnectionId); 354 | }else if(evt.Type == NetEventType.ServerInitialized) 355 | { 356 | mIsServer = true; 357 | } 358 | else if (evt.Type == NetEventType.ServerClosed || evt.Type == NetEventType.ServerInitFailed) 359 | { 360 | mIsServer = false; 361 | } 362 | } 363 | 364 | /// 365 | /// Sends a byte array 366 | /// 367 | /// Connection id the message should be delivered to. 368 | /// Content/Buffer that contains the content 369 | /// Start index of the content in data 370 | /// Length of the content in data 371 | /// True to use the ordered, reliable transfer, false for unordered and unreliable 372 | public void SendData(ConnectionId conId, byte[] data, int offset, int length, bool reliable) 373 | { 374 | UnityWebRtcNetworkSendData(mReference, conId.id, data, offset, length, reliable); 375 | } 376 | 377 | /// 378 | /// Shuts webrtc down. All connection will be disconnected + if the server is started it will be stopped. 379 | /// 380 | /// The instance itself isn't released yet! Use Dispose to destroy the network entirely. 381 | /// 382 | public void Shutdown() 383 | { 384 | UnityWebRtcNetworkShutdown(mReference); 385 | } 386 | 387 | /// 388 | /// Dequeues a new event 389 | /// 390 | /// 391 | /// 392 | public bool Dequeue(out NetworkEvent evt) 393 | { 394 | evt = new NetworkEvent(); 395 | if (mEvents.Count == 0) 396 | return false; 397 | 398 | evt = mEvents.Dequeue(); 399 | return true; 400 | } 401 | 402 | public bool Peek(out NetworkEvent evt) 403 | { 404 | evt = new NetworkEvent(); 405 | if (mEvents.Count == 0) 406 | return false; 407 | 408 | evt = mEvents.Peek(); 409 | return true; 410 | } 411 | 412 | /// 413 | /// Needs to be called to read data from the underlaying network and update this class. 414 | /// 415 | /// Use Dequeue to get the events it read. 416 | /// 417 | public virtual void Update() 418 | { 419 | UnityWebRtcNetworkUpdate(mReference); 420 | 421 | NetworkEvent ev = new NetworkEvent(); 422 | 423 | //DequeueInternal will read the message from js, change the state of this object 424 | //e.g. if a server is successfully opened it will set mIsServer to true 425 | while(DequeueInternal(out ev)) 426 | { 427 | //add it for delivery to the user 428 | mEvents.Enqueue(ev); 429 | } 430 | } 431 | 432 | /// 433 | /// Flushes messages. Not needed in WebRtcNetwork but use it at the end of a frame 434 | /// if you want to be able to replace WebRtcNetwork with other implementations 435 | /// 436 | public void Flush() 437 | { 438 | UnityWebRtcNetworkFlush(mReference); 439 | } 440 | 441 | /// 442 | /// Disconnects the given connection id. 443 | /// 444 | /// Id to disconnect 445 | public void Disconnect(ConnectionId id) 446 | { 447 | UnityWebRtcNetworkDisconnect(mReference, id.id); 448 | } 449 | 450 | } 451 | } 452 | -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/scripts/BrowserWebRtcNetworkFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UnityEngine; 6 | 7 | namespace Byn.Net 8 | { 9 | public class BrowserWebRtcNetworkFactory : IWebRtcNetworkFactory 10 | { 11 | private bool disposedValue = false; 12 | 13 | 14 | public IBasicNetwork CreateDefault(string websocketUrl, IceServer[] iceServers) 15 | { 16 | 17 | if (iceServers == null || iceServers.Length == 0 || iceServers[0] == null //one server must be set 18 | || iceServers[0].Urls == null || iceServers[0].Urls.Count == 0 || 19 | string.IsNullOrEmpty(iceServers[0].Urls[0])) //make sure there is at least 1 valid url 20 | { 21 | Debug.LogError("Ice server missing or server url missing."); 22 | return null; 23 | } 24 | if (string.IsNullOrEmpty(websocketUrl)) 25 | { 26 | Debug.LogError("websocketUrl missing."); 27 | return null; 28 | } 29 | if (iceServers.Length > 0 || string.IsNullOrEmpty(iceServers[0].Username) == false) 30 | { 31 | Debug.LogWarning("Current web implementation doesn't support username, password yet and only supports one ice server"); 32 | } 33 | 34 | string[] urls = iceServers[0].Urls.ToArray(); 35 | 36 | string iceUrlsJson = "\"" + urls[0] + "\""; 37 | for (int i = 1; i < urls.Length; i++) 38 | { 39 | iceUrlsJson += ", \"" + urls[i] + "\""; 40 | } 41 | 42 | 43 | //string websocketUrl = "ws://localhost:12776"; 44 | string conf; 45 | if (websocketUrl == null) 46 | { 47 | conf = "{ \"signaling\" : { \"class\": \"LocalNetwork\", \"param\" : null}, \"iceServers\":[" + iceUrlsJson + "]}"; 48 | 49 | } 50 | else 51 | { 52 | conf = "{ \"signaling\" : { \"class\": \"WebsocketNetwork\", \"param\" : \"" + websocketUrl + "\"}, \"iceServers\":[" + iceUrlsJson + "]}"; 53 | } 54 | 55 | 56 | return new BrowserWebRtcNetwork(conf); 57 | } 58 | 59 | 60 | protected virtual void Dispose(bool disposing) 61 | { 62 | if (!disposedValue) 63 | { 64 | if (disposing) 65 | { 66 | //free managed 67 | } 68 | //free unmanaged 69 | 70 | disposedValue = true; 71 | } 72 | } 73 | public void Dispose() 74 | { 75 | Dispose(true); 76 | } 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/scripts/UnitySingleton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using UnityEngine; 6 | 7 | namespace Byn.Common 8 | { 9 | public class UnitySingleton : MonoBehaviour where T : MonoBehaviour 10 | { 11 | private static T sInstance; 12 | private static bool mIsQuitting = false; 13 | private static object sLock = new object(); 14 | 15 | public static T Instance 16 | { 17 | get 18 | { 19 | if (mIsQuitting) 20 | { 21 | Debug.LogWarning(typeof(T).Name + " is already destroyed due to shutdown! Returning null."); 22 | return null; 23 | } 24 | 25 | lock (sLock) 26 | { 27 | if (sInstance == null) 28 | { 29 | sInstance = (T)FindObjectOfType(typeof(T)); 30 | 31 | if (FindObjectsOfType(typeof(T)).Length > 1) 32 | { 33 | Debug.LogError(typeof(T).Name + " multiple instances in scene! Make sure only one Singleton is in the scene at the same time!"); 34 | return sInstance; 35 | } 36 | 37 | if (sInstance == null) 38 | { 39 | GameObject singleton = new GameObject(); 40 | sInstance = singleton.AddComponent(); 41 | singleton.name = typeof(T).Name; 42 | 43 | DontDestroyOnLoad(singleton); 44 | } 45 | } 46 | return sInstance; 47 | } 48 | } 49 | } 50 | protected virtual void OnDestroy() 51 | { 52 | mIsQuitting = true; 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/scripts/WebRtcNetworkFactory.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using Byn.Common; 5 | using System; 6 | 7 | namespace Byn.Net 8 | { 9 | 10 | //TODO: List that keeps track of created networks will be moved into the 11 | //underlaying factories 12 | public class WebRtcNetworkFactory : UnitySingleton 13 | { 14 | 15 | //android needs a static init process. 16 | /// 17 | /// True if the platform specific init process was tried 18 | /// 19 | private static bool sStaticInitTried = false; 20 | 21 | /// 22 | /// true if the static init process was successful. false if not yet tried or failed. 23 | /// 24 | private static bool sStaticInitSuccessful = false; 25 | 26 | private IWebRtcNetworkFactory mFactory = null; 27 | private List mCreatedNetworks = new List(); 28 | 29 | public static bool StaticInitSuccessful 30 | { 31 | get 32 | { 33 | return sStaticInitSuccessful; 34 | } 35 | } 36 | 37 | private WebRtcNetworkFactory() 38 | { 39 | 40 | //try to setup (this also checks if the platform is even supported) 41 | TryStaticInitialize(); 42 | //setup failed? factory will be null so nothing can be created 43 | if (sStaticInitSuccessful == false) 44 | { 45 | Debug.LogError("Initialization of the webrtc plugin failed. StaticInitSuccessful is false. "); 46 | mFactory = null; 47 | return; 48 | } 49 | #if UNITY_WEBGL && !UNITY_EDITOR 50 | 51 | mFactory = new Byn.Net.BrowserWebRtcNetworkFactory(); 52 | Debug.Log("Using BrowserWebRtcNetworkFactory"); 53 | 54 | #else 55 | LogNativeSupportInfo(); 56 | Byn.Net.Native.NativeWebRtcNetworkFactory factory = new Byn.Net.Native.NativeWebRtcNetworkFactory(); 57 | factory.Initialize(); 58 | mFactory = factory; 59 | Debug.Log("Using Wrapper: " + WebRtcCSharp.WebRtcWrap.GetVersion() + " WebRTC: " + WebRtcCSharp.WebRtcWrap.GetWebRtcVersion()); 60 | 61 | #endif 62 | 63 | } 64 | 65 | /// 66 | /// Internal use only! 67 | /// Used to check if the current platform is supported 68 | /// Used for other libraries building on top of WebRtcNetwork. 69 | /// 70 | /// True if the platform is supported, false if not. 71 | public static bool CheckNativeSupport() 72 | { 73 | //do not access any platform specific code here. only check if there if the platform is supported 74 | //keep up to date with LogNativeSupportInfo() 75 | #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN 76 | return true; 77 | #elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX 78 | return true; 79 | #elif UNITY_ANDROID 80 | return true; 81 | #else 82 | return false; 83 | #endif 84 | } 85 | 86 | /// 87 | /// Prints platform specific info to the unity log 88 | /// 89 | internal static void LogNativeSupportInfo() 90 | { 91 | 92 | #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN 93 | Debug.Log("Initializing native webrtc for windows ..."); 94 | #elif UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX 95 | Debug.LogWarning("Trying to initialize native webrtc for OSX. Note that this OS isn't fully supported yet!"); 96 | #elif UNITY_ANDROID 97 | Debug.LogWarning("Trying to initialize native webrtc for Android. Note that this OS isn't fully supported yet!"); 98 | #else 99 | Debug.LogError("Platform not supported! Platform: " + Application.platform); 100 | #endif 101 | } 102 | 103 | /// 104 | /// Internally used. No need to manually call this. 105 | /// 106 | /// This function will initialize the wrapper (if needed) before the first webrtc factory can be created. 107 | /// 108 | /// It will set sStaticInitSuccessful to false if the platform isn't supported or the init process failed. 109 | /// 110 | /// 111 | public static void TryStaticInitialize() 112 | { 113 | //make sure it is called only once. no need for multiple static inits... 114 | if (sStaticInitTried) 115 | return; 116 | sStaticInitTried = true; 117 | 118 | Debug.Log("Using workaround for the SslStream.AuthenticateAsClient unity bug"); 119 | //activate workaround for unity bug 120 | DefaultValues.AuthenticateAsClientBugWorkaround = true; 121 | 122 | #if UNITY_WEBGL && !UNITY_EDITOR 123 | 124 | //check if the java script part is available 125 | if (BrowserWebRtcNetwork.IsAvailable() == false) 126 | { 127 | //js part is missing -> inject the code into the browser 128 | BrowserWebRtcNetwork.InjectJsCode(); 129 | } 130 | //if still not available something failed. setting sStaticInitSuccessful to false 131 | //will block the use of the factories 132 | sStaticInitSuccessful = BrowserWebRtcNetwork.IsAvailable(); 133 | if(sStaticInitSuccessful == false) 134 | { 135 | Debug.LogError("Failed to create the call factory. This might be because of browser incompatibility or a missing java script plugin!"); 136 | return; 137 | } 138 | #else 139 | 140 | LogNativeSupportInfo(); 141 | Debug.Log("Version info: [" + Native.NativeWebRtcNetworkFactory.GetVersion() + "] / [" + Native.NativeWebRtcNetworkFactory.GetWrapperVersion() + "] / [" + Native.NativeWebRtcNetworkFactory.GetWebRtcVersion() + "]"); 142 | sStaticInitSuccessful = CheckNativeSupport(); 143 | if (sStaticInitSuccessful == false) 144 | return; 145 | #endif 146 | 147 | //android version needs a special init method in addition 148 | #if UNITY_ANDROID && !UNITY_EDITOR 149 | try 150 | { 151 | sStaticInitSuccessful = TryInitAndroid(); 152 | }catch(Exception e) 153 | { 154 | sStaticInitSuccessful = false; 155 | Debug.LogError("Android specific init process failed due to an exception."); 156 | Debug.LogException(e); 157 | } 158 | if (sStaticInitSuccessful == false) 159 | return; 160 | #endif 161 | } 162 | //#if UNITY_ANDROID && !UNITY_EDITOR 163 | private static bool TryInitAndroid() 164 | { 165 | 166 | 167 | Debug.Log("TryInitAndroid"); 168 | 169 | 170 | Debug.Log("get activity"); 171 | AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 172 | AndroidJavaObject activity = unityPlayer.GetStatic("currentActivity"); 173 | AndroidJavaObject context = activity.Call("getApplicationContext"); 174 | 175 | Debug.Log("call InitAndroidContext"); 176 | bool successful = WebRtcCSharp.RTCPeerConnectionFactory.InitAndroidContext(context.GetRawObject()); 177 | 178 | if (successful) 179 | { 180 | Debug.Log("Android plugin successful initialized."); 181 | } 182 | else 183 | { 184 | Debug.LogError("Failed to initialize android plugin."); 185 | } 186 | return successful; 187 | } 188 | //#endif 189 | public IBasicNetwork CreateDefault(string websocketUrl, IceServer[] urls = null) 190 | { 191 | IBasicNetwork network = mFactory.CreateDefault(websocketUrl, urls); 192 | mCreatedNetworks.Add(network); 193 | return network; 194 | } 195 | 196 | 197 | protected override void OnDestroy() 198 | { 199 | base.OnDestroy(); 200 | 201 | Debug.Log("Network factory is being destroyed. All created basic networks will be destroyed as well!"); 202 | foreach (IBasicNetwork net in mCreatedNetworks) 203 | { 204 | net.Dispose(); 205 | } 206 | mCreatedNetworks.Clear(); 207 | 208 | //cleanup 209 | if (mFactory != null) 210 | { 211 | mFactory.Dispose(); 212 | } 213 | } 214 | } 215 | } -------------------------------------------------------------------------------- /VoiceChat/Assets/WebRtcNetwork/server.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/Assets/WebRtcNetwork/server.zip -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 0 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_DisableAudio: 0 15 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | m_Gravity: {x: 0, y: -9.81000042, z: 0} 7 | m_DefaultMaterial: {fileID: 0} 8 | m_BounceThreshold: 2 9 | m_SleepThreshold: .00499999989 10 | m_DefaultContactOffset: .00999999978 11 | m_SolverIterationCount: 6 12 | m_RaycastsHitTriggers: 1 13 | m_EnableAdaptiveForce: 0 14 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 15 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/UnityVOIP/Demo/UnityVOIPExample.unity 10 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_ExternalVersionControlSupport: 1 8 | m_SerializationMode: 2 9 | m_WebSecurityEmulationEnabled: 0 10 | m_WebSecurityEmulationHostUrl: http://www.mydomain.com/mygame.unity3d 11 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 9 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10782, guid: 0000000000000000f000000000000000, type: 0} 38 | m_PreloadedShaders: [] 39 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 40 | type: 0} 41 | m_TierSettings_Tier1: 42 | renderingPath: 1 43 | useCascadedShadowMaps: 1 44 | m_TierSettings_Tier2: 45 | renderingPath: 1 46 | useCascadedShadowMaps: 1 47 | m_TierSettings_Tier3: 48 | renderingPath: 1 49 | useCascadedShadowMaps: 1 50 | m_DefaultRenderingPath: 1 51 | m_DefaultMobileRenderingPath: 1 52 | m_TierSettings: [] 53 | m_LightmapStripping: 0 54 | m_FogStripping: 0 55 | m_LightmapKeepPlain: 1 56 | m_LightmapKeepDirCombined: 1 57 | m_LightmapKeepDirSeparate: 1 58 | m_LightmapKeepDynamicPlain: 1 59 | m_LightmapKeepDynamicDirCombined: 1 60 | m_LightmapKeepDynamicDirSeparate: 1 61 | m_FogKeepLinear: 1 62 | m_FogKeepExp: 1 63 | m_FogKeepExp2: 1 64 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: .00100000005 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: .00100000005 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: .00100000005 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: .00100000005 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left cmd 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: .00100000005 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: .00100000005 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: .100000001 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: .100000001 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: .100000001 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Window Shake X 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0 162 | sensitivity: .100000001 163 | snap: 0 164 | invert: 0 165 | type: 3 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Window Shake Y 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0 178 | sensitivity: .100000001 179 | snap: 0 180 | invert: 0 181 | type: 3 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Horizontal 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 0 193 | dead: .189999998 194 | sensitivity: 1 195 | snap: 0 196 | invert: 0 197 | type: 2 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Vertical 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 0 209 | dead: .189999998 210 | sensitivity: 1 211 | snap: 0 212 | invert: 1 213 | type: 2 214 | axis: 1 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire1 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 0 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: .00100000005 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Fire2 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 1 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: .00100000005 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Fire3 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: joystick button 2 254 | altNegativeButton: 255 | altPositiveButton: 256 | gravity: 1000 257 | dead: .00100000005 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Jump 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: joystick button 3 270 | altNegativeButton: 271 | altPositiveButton: 272 | gravity: 1000 273 | dead: .00100000005 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Submit 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: return 286 | altNegativeButton: 287 | altPositiveButton: joystick button 0 288 | gravity: 1000 289 | dead: .00100000005 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | - serializedVersion: 3 297 | m_Name: Submit 298 | descriptiveName: 299 | descriptiveNegativeName: 300 | negativeButton: 301 | positiveButton: enter 302 | altNegativeButton: 303 | altPositiveButton: space 304 | gravity: 1000 305 | dead: .00100000005 306 | sensitivity: 1000 307 | snap: 0 308 | invert: 0 309 | type: 0 310 | axis: 0 311 | joyNum: 0 312 | - serializedVersion: 3 313 | m_Name: Cancel 314 | descriptiveName: 315 | descriptiveNegativeName: 316 | negativeButton: 317 | positiveButton: escape 318 | altNegativeButton: 319 | altPositiveButton: joystick button 1 320 | gravity: 1000 321 | dead: .00100000005 322 | sensitivity: 1000 323 | snap: 0 324 | invert: 0 325 | type: 0 326 | axis: 0 327 | joyNum: 0 328 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshAreas: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/NavMeshLayers.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Phylliida/UnityVOIP/719817fce5d7727a7fd624db0bc9ff8a72566698/VoiceChat/ProjectSettings/NavMeshLayers.asset -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | m_Gravity: {x: 0, y: -9.81000042} 7 | m_DefaultMaterial: {fileID: 0} 8 | m_VelocityIterations: 8 9 | m_PositionIterations: 3 10 | m_VelocityThreshold: 1 11 | m_MaxLinearCorrection: .200000003 12 | m_MaxAngularCorrection: 8 13 | m_MaxTranslationSpeed: 100 14 | m_MaxRotationSpeed: 360 15 | m_MinPenetrationForPenalty: .00999999978 16 | m_BaumgarteScale: .200000003 17 | m_BaumgarteTimeOfImpactScale: .75 18 | m_TimeToSleep: .5 19 | m_LinearSleepTolerance: .00999999978 20 | m_AngularSleepTolerance: 2 21 | m_RaycastsHitTriggers: 1 22 | m_RaycastsStartInColliders: 1 23 | m_ChangeStopsCallbacks: 0 24 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 25 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 10 7 | productGUID: 22ad8ebd23fdd9541909295b9a1ee225 8 | AndroidProfiler: 0 9 | defaultScreenOrientation: 0 10 | targetDevice: 2 11 | useOnDemandResources: 0 12 | accelerometerFrequency: 60 13 | companyName: Fredrik 14 | productName: VoiceChat 15 | defaultCursor: {fileID: 0} 16 | cursorHotspot: {x: 0, y: 0} 17 | m_SplashScreenBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21176471, a: 1} 18 | m_ShowUnitySplashScreen: 1 19 | m_ShowUnitySplashLogo: 1 20 | m_SplashScreenOverlayOpacity: 1 21 | m_SplashScreenAnimation: 1 22 | m_SplashScreenLogoStyle: 1 23 | m_SplashScreenDrawMode: 0 24 | m_SplashScreenBackgroundAnimationZoom: 1 25 | m_SplashScreenLogoAnimationZoom: 1 26 | m_SplashScreenBackgroundLandscapeAspect: 1 27 | m_SplashScreenBackgroundPortraitAspect: 1 28 | m_SplashScreenBackgroundLandscapeUvs: 29 | serializedVersion: 2 30 | x: 0 31 | y: 0 32 | width: 1 33 | height: 1 34 | m_SplashScreenBackgroundPortraitUvs: 35 | serializedVersion: 2 36 | x: 0 37 | y: 0 38 | width: 1 39 | height: 1 40 | m_SplashScreenLogos: [] 41 | m_SplashScreenBackgroundLandscape: {fileID: 0} 42 | m_SplashScreenBackgroundPortrait: {fileID: 0} 43 | m_VirtualRealitySplashScreen: {fileID: 0} 44 | m_HolographicTrackingLossScreen: {fileID: 0} 45 | defaultScreenWidth: 640 46 | defaultScreenHeight: 360 47 | defaultScreenWidthWeb: 960 48 | defaultScreenHeightWeb: 600 49 | m_StereoRenderingPath: 0 50 | m_ActiveColorSpace: 0 51 | m_MTRendering: 1 52 | m_MobileMTRendering: 0 53 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 54 | iosShowActivityIndicatorOnLoading: -1 55 | androidShowActivityIndicatorOnLoading: -1 56 | tizenShowActivityIndicatorOnLoading: -1 57 | iosAppInBackgroundBehavior: 0 58 | displayResolutionDialog: 0 59 | iosAllowHTTPDownload: 1 60 | allowedAutorotateToPortrait: 1 61 | allowedAutorotateToPortraitUpsideDown: 1 62 | allowedAutorotateToLandscapeRight: 1 63 | allowedAutorotateToLandscapeLeft: 1 64 | useOSAutorotation: 1 65 | use32BitDisplayBuffer: 0 66 | disableDepthAndStencilBuffers: 0 67 | defaultIsFullScreen: 0 68 | defaultIsNativeResolution: 1 69 | runInBackground: 1 70 | captureSingleScreen: 0 71 | muteOtherAudioSources: 0 72 | Prepare IOS For Recording: 0 73 | submitAnalytics: 1 74 | usePlayerLog: 1 75 | bakeCollisionMeshes: 0 76 | forceSingleInstance: 0 77 | resizableWindow: 0 78 | useMacAppStoreValidation: 0 79 | gpuSkinning: 0 80 | graphicsJobs: 0 81 | xboxPIXTextureCapture: 0 82 | xboxEnableAvatar: 0 83 | xboxEnableKinect: 0 84 | xboxEnableKinectAutoTracking: 0 85 | xboxEnableFitness: 0 86 | visibleInBackground: 0 87 | allowFullscreenSwitch: 1 88 | macFullscreenMode: 2 89 | d3d9FullscreenMode: 1 90 | d3d11FullscreenMode: 1 91 | xboxSpeechDB: 0 92 | xboxEnableHeadOrientation: 0 93 | xboxEnableGuest: 0 94 | xboxEnablePIXSampling: 0 95 | n3dsDisableStereoscopicView: 0 96 | n3dsEnableSharedListOpt: 1 97 | n3dsEnableVSync: 0 98 | uiUse16BitDepthBuffer: 0 99 | ignoreAlphaClear: 0 100 | xboxOneResolution: 0 101 | xboxOneMonoLoggingLevel: 0 102 | xboxOneLoggingLevel: 1 103 | videoMemoryForVertexBuffers: 0 104 | psp2PowerMode: 0 105 | psp2AcquireBGM: 1 106 | wiiUTVResolution: 0 107 | wiiUGamePadMSAA: 1 108 | wiiUSupportsNunchuk: 0 109 | wiiUSupportsClassicController: 0 110 | wiiUSupportsBalanceBoard: 0 111 | wiiUSupportsMotionPlus: 0 112 | wiiUSupportsProController: 0 113 | wiiUAllowScreenCapture: 1 114 | wiiUControllerCount: 0 115 | m_SupportedAspectRatios: 116 | 4:3: 1 117 | 5:4: 1 118 | 16:10: 1 119 | 16:9: 1 120 | Others: 1 121 | bundleIdentifier: com.Company.ProductName 122 | bundleVersion: 1.0 123 | preloadedAssets: [] 124 | metroInputSource: 0 125 | m_HolographicPauseOnTrackingLoss: 1 126 | xboxOneDisableKinectGpuReservation: 0 127 | protectGraphicsMemory: 0 128 | AndroidBundleVersionCode: 1 129 | AndroidMinSdkVersion: 9 130 | AndroidPreferredInstallLocation: 1 131 | aotOptions: 132 | apiCompatibilityLevel: 1 133 | stripEngineCode: 1 134 | iPhoneStrippingLevel: 0 135 | iPhoneScriptCallOptimization: 0 136 | iPhoneBuildNumber: 0 137 | ForceInternetPermission: 0 138 | ForceSDCardPermission: 0 139 | CreateWallpaper: 0 140 | APKExpansionFiles: 0 141 | preloadShaders: 0 142 | StripUnusedMeshComponents: 0 143 | VertexChannelCompressionMask: 144 | serializedVersion: 2 145 | m_Bits: 238 146 | iPhoneSdkVersion: 988 147 | iOSTargetOSVersionString: 6.0 148 | tvOSSdkVersion: 0 149 | tvOSRequireExtendedGameController: 0 150 | tvOSTargetOSVersionString: 151 | uIPrerenderedIcon: 0 152 | uIRequiresPersistentWiFi: 0 153 | uIRequiresFullScreen: 1 154 | uIStatusBarHidden: 1 155 | uIExitOnSuspend: 0 156 | uIStatusBarStyle: 0 157 | iPhoneSplashScreen: {fileID: 0} 158 | iPhoneHighResSplashScreen: {fileID: 0} 159 | iPhoneTallHighResSplashScreen: {fileID: 0} 160 | iPhone47inSplashScreen: {fileID: 0} 161 | iPhone55inPortraitSplashScreen: {fileID: 0} 162 | iPhone55inLandscapeSplashScreen: {fileID: 0} 163 | iPadPortraitSplashScreen: {fileID: 0} 164 | iPadHighResPortraitSplashScreen: {fileID: 0} 165 | iPadLandscapeSplashScreen: {fileID: 0} 166 | iPadHighResLandscapeSplashScreen: {fileID: 0} 167 | appleTVSplashScreen: {fileID: 0} 168 | tvOSSmallIconLayers: [] 169 | tvOSLargeIconLayers: [] 170 | tvOSTopShelfImageLayers: [] 171 | tvOSTopShelfImageWideLayers: [] 172 | iOSLaunchScreenType: 0 173 | iOSLaunchScreenPortrait: {fileID: 0} 174 | iOSLaunchScreenLandscape: {fileID: 0} 175 | iOSLaunchScreenBackgroundColor: 176 | serializedVersion: 2 177 | rgba: 0 178 | iOSLaunchScreenFillPct: 100 179 | iOSLaunchScreenSize: 100 180 | iOSLaunchScreenCustomXibPath: 181 | iOSLaunchScreeniPadType: 0 182 | iOSLaunchScreeniPadImage: {fileID: 0} 183 | iOSLaunchScreeniPadBackgroundColor: 184 | serializedVersion: 2 185 | rgba: 0 186 | iOSLaunchScreeniPadFillPct: 100 187 | iOSLaunchScreeniPadSize: 100 188 | iOSLaunchScreeniPadCustomXibPath: 189 | iOSDeviceRequirements: [] 190 | iOSURLSchemes: [] 191 | iOSBackgroundModes: 0 192 | iOSMetalForceHardShadows: 0 193 | appleDeveloperTeamID: 194 | AndroidTargetDevice: 0 195 | AndroidSplashScreenScale: 0 196 | androidSplashScreen: {fileID: 0} 197 | AndroidKeystoreName: 198 | AndroidKeyaliasName: 199 | AndroidTVCompatibility: 1 200 | AndroidIsGame: 1 201 | androidEnableBanner: 1 202 | m_AndroidBanners: 203 | - width: 320 204 | height: 180 205 | banner: {fileID: 0} 206 | androidGamepadSupportLevel: 0 207 | resolutionDialogBanner: {fileID: 0} 208 | m_BuildTargetIcons: 209 | - m_BuildTarget: 210 | m_Icons: 211 | - serializedVersion: 2 212 | m_Icon: {fileID: 0} 213 | m_Width: 128 214 | m_Height: 128 215 | m_BuildTargetBatching: [] 216 | m_BuildTargetGraphicsAPIs: [] 217 | m_BuildTargetVRSettings: [] 218 | openGLRequireES31: 0 219 | openGLRequireES31AEP: 0 220 | webPlayerTemplate: APPLICATION:Default 221 | m_TemplateCustomTags: {} 222 | wiiUTitleID: 0005000011000000 223 | wiiUGroupID: 00010000 224 | wiiUCommonSaveSize: 4096 225 | wiiUAccountSaveSize: 2048 226 | wiiUOlvAccessKey: 0 227 | wiiUTinCode: 0 228 | wiiUJoinGameId: 0 229 | wiiUJoinGameModeMask: 0000000000000000 230 | wiiUCommonBossSize: 0 231 | wiiUAccountBossSize: 0 232 | wiiUAddOnUniqueIDs: [] 233 | wiiUMainThreadStackSize: 3072 234 | wiiULoaderThreadStackSize: 1024 235 | wiiUSystemHeapSize: 128 236 | wiiUTVStartupScreen: {fileID: 0} 237 | wiiUGamePadStartupScreen: {fileID: 0} 238 | wiiUDrcBufferDisabled: 0 239 | wiiUProfilerLibPath: 240 | actionOnDotNetUnhandledException: 1 241 | enableInternalProfiler: 0 242 | logObjCUncaughtExceptions: 1 243 | enableCrashReportAPI: 0 244 | cameraUsageDescription: 245 | locationUsageDescription: 246 | microphoneUsageDescription: 247 | XboxTitleId: 248 | XboxImageXexPath: 249 | XboxSpaPath: 250 | XboxGenerateSpa: 0 251 | XboxDeployKinectResources: 0 252 | XboxSplashScreen: {fileID: 0} 253 | xboxEnableSpeech: 0 254 | xboxAdditionalTitleMemorySize: 0 255 | xboxDeployKinectHeadOrientation: 0 256 | xboxDeployKinectHeadPosition: 0 257 | ps4NPAgeRating: 12 258 | ps4NPTitleSecret: 259 | ps4NPTrophyPackPath: 260 | ps4ParentalLevel: 1 261 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 262 | ps4Category: 0 263 | ps4MasterVersion: 01.00 264 | ps4AppVersion: 01.00 265 | ps4AppType: 0 266 | ps4ParamSfxPath: 267 | ps4VideoOutPixelFormat: 0 268 | ps4VideoOutInitialWidth: 1920 269 | ps4VideoOutReprojectionRate: 120 270 | ps4PronunciationXMLPath: 271 | ps4PronunciationSIGPath: 272 | ps4BackgroundImagePath: 273 | ps4StartupImagePath: 274 | ps4SaveDataImagePath: 275 | ps4SdkOverride: 276 | ps4BGMPath: 277 | ps4ShareFilePath: 278 | ps4ShareOverlayImagePath: 279 | ps4PrivacyGuardImagePath: 280 | ps4NPtitleDatPath: 281 | ps4RemotePlayKeyAssignment: -1 282 | ps4RemotePlayKeyMappingDir: 283 | ps4PlayTogetherPlayerCount: 0 284 | ps4EnterButtonAssignment: 1 285 | ps4ApplicationParam1: 0 286 | ps4ApplicationParam2: 0 287 | ps4ApplicationParam3: 0 288 | ps4ApplicationParam4: 0 289 | ps4DownloadDataSize: 0 290 | ps4GarlicHeapSize: 2048 291 | ps4Passcode: eaoEiIgxIX4a2dREbbSqWy6yhKIDCdJO 292 | ps4UseDebugIl2cppLibs: 0 293 | ps4pnSessions: 1 294 | ps4pnPresence: 1 295 | ps4pnFriends: 1 296 | ps4pnGameCustomData: 1 297 | playerPrefsSupport: 0 298 | restrictedAudioUsageRights: 0 299 | ps4UseResolutionFallback: 0 300 | ps4ReprojectionSupport: 0 301 | ps4UseAudio3dBackend: 0 302 | ps4SocialScreenEnabled: 0 303 | ps4ScriptOptimizationLevel: 3 304 | ps4Audio3dVirtualSpeakerCount: 14 305 | ps4attribCpuUsage: 0 306 | ps4PatchPkgPath: 307 | ps4PatchLatestPkgPath: 308 | ps4PatchChangeinfoPath: 309 | ps4PatchDayOne: 0 310 | ps4attribUserManagement: 0 311 | ps4attribMoveSupport: 0 312 | ps4attrib3DSupport: 0 313 | ps4attribShareSupport: 0 314 | ps4attribExclusiveVR: 0 315 | ps4disableAutoHideSplash: 0 316 | ps4IncludedModules: [] 317 | monoEnv: 318 | psp2Splashimage: {fileID: 0} 319 | psp2NPTrophyPackPath: 320 | psp2NPSupportGBMorGJP: 0 321 | psp2NPAgeRating: 12 322 | psp2NPTitleDatPath: 323 | psp2NPCommsID: 324 | psp2NPCommunicationsID: 325 | psp2NPCommsPassphrase: 326 | psp2NPCommsSig: 327 | psp2ParamSfxPath: 328 | psp2ManualPath: 329 | psp2LiveAreaGatePath: 330 | psp2LiveAreaBackroundPath: 331 | psp2LiveAreaPath: 332 | psp2LiveAreaTrialPath: 333 | psp2PatchChangeInfoPath: 334 | psp2PatchOriginalPackage: 335 | psp2PackagePassword: yapnxrpMCARCr4zdGc81tBDKsMlaZTXC 336 | psp2KeystoneFile: 337 | psp2MemoryExpansionMode: 0 338 | psp2DRMType: 0 339 | psp2StorageType: 0 340 | psp2MediaCapacity: 0 341 | psp2DLCConfigPath: 342 | psp2ThumbnailPath: 343 | psp2BackgroundPath: 344 | psp2SoundPath: 345 | psp2TrophyCommId: 346 | psp2TrophyPackagePath: 347 | psp2PackagedResourcesPath: 348 | psp2SaveDataQuota: 10240 349 | psp2ParentalLevel: 1 350 | psp2ShortTitle: Not Set 351 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF 352 | psp2Category: 0 353 | psp2MasterVersion: 01.00 354 | psp2AppVersion: 01.00 355 | psp2TVBootMode: 0 356 | psp2EnterButtonAssignment: 2 357 | psp2TVDisableEmu: 0 358 | psp2AllowTwitterDialog: 1 359 | psp2Upgradable: 0 360 | psp2HealthWarning: 0 361 | psp2UseLibLocation: 0 362 | psp2InfoBarOnStartup: 0 363 | psp2InfoBarColor: 0 364 | psp2UseDebugIl2cppLibs: 0 365 | psmSplashimage: {fileID: 0} 366 | splashScreenBackgroundSourceLandscape: {fileID: 0} 367 | splashScreenBackgroundSourcePortrait: {fileID: 0} 368 | spritePackerPolicy: 369 | webGLMemorySize: 256 370 | webGLExceptionSupport: 1 371 | webGLDataCaching: 0 372 | webGLDebugSymbols: 0 373 | webGLEmscriptenArgs: 374 | webGLModulesDirectory: 375 | webGLTemplate: APPLICATION:Default 376 | webGLAnalyzeBuildSize: 0 377 | webGLUseEmbeddedResources: 0 378 | webGLUseWasm: 0 379 | webGLCompressionFormat: 1 380 | scriptingDefineSymbols: {} 381 | platformArchitecture: 382 | iOS: 2 383 | scriptingBackend: 384 | Metro: 2 385 | Standalone: 0 386 | WP8: 2 387 | WebGL: 1 388 | iOS: 1 389 | incrementalIl2cppBuild: 390 | iOS: 0 391 | additionalIl2CppArgs: 392 | m_RenderingPath: 1 393 | m_MobileRenderingPath: 1 394 | metroPackageName: VoiceChat 395 | metroPackageVersion: 396 | metroCertificatePath: 397 | metroCertificatePassword: 398 | metroCertificateSubject: 399 | metroCertificateIssuer: 400 | metroCertificateNotAfter: 0000000000000000 401 | metroApplicationDescription: VoiceChat 402 | wsaImages: {} 403 | metroTileShortName: 404 | metroCommandLineArgsFile: 405 | metroTileShowName: 0 406 | metroMediumTileShowName: 0 407 | metroLargeTileShowName: 0 408 | metroWideTileShowName: 0 409 | metroDefaultTileSize: 1 410 | metroTileForegroundText: 1 411 | metroTileBackgroundColor: {r: 0, g: 0, b: 0, a: 1} 412 | metroSplashScreenBackgroundColor: {r: 0, g: 0, b: 0, a: 1} 413 | metroSplashScreenUseBackgroundColor: 0 414 | platformCapabilities: {} 415 | metroFTAName: 416 | metroFTAFileTypes: [] 417 | metroProtocolName: 418 | metroCompilationOverrides: 1 419 | tizenProductDescription: 420 | tizenProductURL: 421 | tizenSigningProfileName: 422 | tizenGPSPermissions: 0 423 | tizenMicrophonePermissions: 0 424 | tizenDeploymentTarget: 425 | tizenDeploymentTargetType: 15 426 | tizenMinOSVersion: 0 427 | n3dsUseExtSaveData: 0 428 | n3dsCompressStaticMem: 1 429 | n3dsExtSaveDataNumber: 0x12345 430 | n3dsStackSize: 131072 431 | n3dsTargetPlatform: 2 432 | n3dsRegion: 7 433 | n3dsMediaSize: 0 434 | n3dsLogoStyle: 3 435 | n3dsTitle: GameName 436 | n3dsProductCode: 437 | n3dsApplicationId: 0xFF3FF 438 | stvDeviceAddress: 439 | stvProductDescription: 440 | stvProductAuthor: 441 | stvProductAuthorEmail: 442 | stvProductLink: 443 | stvProductCategory: 0 444 | XboxOneProductId: 445 | XboxOneUpdateKey: 446 | XboxOneSandboxId: 447 | XboxOneContentId: 448 | XboxOneTitleId: 449 | XboxOneSCId: 450 | XboxOneGameOsOverridePath: 451 | XboxOnePackagingOverridePath: 452 | XboxOneAppManifestOverridePath: 453 | XboxOnePackageEncryption: 0 454 | XboxOnePackageUpdateGranularity: 2 455 | XboxOneDescription: 456 | XboxOneLanguage: 457 | - enus 458 | XboxOneCapability: [] 459 | XboxOneGameRating: {} 460 | XboxOneIsContentPackage: 0 461 | XboxOneEnableGPUVariability: 0 462 | XboxOneSockets: {} 463 | XboxOneSplashScreen: {fileID: 0} 464 | XboxOneAllowedProductIds: [] 465 | XboxOnePersistentLocalStorageSize: 0 466 | vrEditorSettings: {} 467 | cloudServicesEnabled: {} 468 | cloudProjectId: 469 | projectName: 470 | organizationId: 471 | cloudEnabled: 0 472 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.5.0f3 2 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 3 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Fastest 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowCascade2Split: .333333343 18 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 19 | blendWeights: 1 20 | textureQuality: 1 21 | anisotropicTextures: 0 22 | antiAliasing: 0 23 | softParticles: 0 24 | softVegetation: 0 25 | realtimeReflectionProbes: 0 26 | billboardsFaceCameraPosition: 0 27 | vSyncCount: 0 28 | lodBias: .300000012 29 | maximumLODLevel: 0 30 | particleRaycastBudget: 4 31 | excludedTargetPlatforms: [] 32 | - serializedVersion: 2 33 | name: Fast 34 | pixelLightCount: 0 35 | shadows: 0 36 | shadowResolution: 0 37 | shadowProjection: 1 38 | shadowCascades: 1 39 | shadowDistance: 20 40 | shadowCascade2Split: .333333343 41 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 42 | blendWeights: 2 43 | textureQuality: 0 44 | anisotropicTextures: 0 45 | antiAliasing: 0 46 | softParticles: 0 47 | softVegetation: 0 48 | realtimeReflectionProbes: 0 49 | billboardsFaceCameraPosition: 0 50 | vSyncCount: 0 51 | lodBias: .400000006 52 | maximumLODLevel: 0 53 | particleRaycastBudget: 16 54 | excludedTargetPlatforms: [] 55 | - serializedVersion: 2 56 | name: Simple 57 | pixelLightCount: 1 58 | shadows: 1 59 | shadowResolution: 0 60 | shadowProjection: 1 61 | shadowCascades: 1 62 | shadowDistance: 20 63 | shadowCascade2Split: .333333343 64 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 65 | blendWeights: 2 66 | textureQuality: 0 67 | anisotropicTextures: 1 68 | antiAliasing: 0 69 | softParticles: 0 70 | softVegetation: 0 71 | realtimeReflectionProbes: 0 72 | billboardsFaceCameraPosition: 0 73 | vSyncCount: 0 74 | lodBias: .699999988 75 | maximumLODLevel: 0 76 | particleRaycastBudget: 64 77 | excludedTargetPlatforms: [] 78 | - serializedVersion: 2 79 | name: Good 80 | pixelLightCount: 2 81 | shadows: 2 82 | shadowResolution: 1 83 | shadowProjection: 1 84 | shadowCascades: 2 85 | shadowDistance: 40 86 | shadowCascade2Split: .333333343 87 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 88 | blendWeights: 2 89 | textureQuality: 0 90 | anisotropicTextures: 1 91 | antiAliasing: 0 92 | softParticles: 0 93 | softVegetation: 1 94 | realtimeReflectionProbes: 1 95 | billboardsFaceCameraPosition: 1 96 | vSyncCount: 1 97 | lodBias: 1 98 | maximumLODLevel: 0 99 | particleRaycastBudget: 256 100 | excludedTargetPlatforms: [] 101 | - serializedVersion: 2 102 | name: Beautiful 103 | pixelLightCount: 3 104 | shadows: 2 105 | shadowResolution: 2 106 | shadowProjection: 1 107 | shadowCascades: 2 108 | shadowDistance: 70 109 | shadowCascade2Split: .333333343 110 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 111 | blendWeights: 4 112 | textureQuality: 0 113 | anisotropicTextures: 2 114 | antiAliasing: 2 115 | softParticles: 1 116 | softVegetation: 1 117 | realtimeReflectionProbes: 1 118 | billboardsFaceCameraPosition: 1 119 | vSyncCount: 1 120 | lodBias: 1.5 121 | maximumLODLevel: 0 122 | particleRaycastBudget: 1024 123 | excludedTargetPlatforms: [] 124 | - serializedVersion: 2 125 | name: Fantastic 126 | pixelLightCount: 4 127 | shadows: 2 128 | shadowResolution: 2 129 | shadowProjection: 1 130 | shadowCascades: 4 131 | shadowDistance: 150 132 | shadowCascade2Split: .333333343 133 | shadowCascade4Split: {x: .0666666701, y: .200000003, z: .466666669} 134 | blendWeights: 4 135 | textureQuality: 0 136 | anisotropicTextures: 2 137 | antiAliasing: 2 138 | softParticles: 1 139 | softVegetation: 1 140 | realtimeReflectionProbes: 1 141 | billboardsFaceCameraPosition: 1 142 | vSyncCount: 1 143 | lodBias: 2 144 | maximumLODLevel: 0 145 | particleRaycastBudget: 4096 146 | excludedTargetPlatforms: [] 147 | m_PerPlatformDefaultQuality: 148 | Android: 2 149 | FlashPlayer: 3 150 | GLES Emulation: 3 151 | PS3: 3 152 | Standalone: 3 153 | Web: 3 154 | Wii: 3 155 | XBOX360: 3 156 | iPhone: 2 157 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.001 7 | Maximum Allowed Timestep: 0.01 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /VoiceChat/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | m_Enabled: 0 7 | m_TestMode: 0 8 | m_TestEventUrl: 9 | m_TestConfigUrl: 10 | CrashReportingSettings: 11 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes 12 | m_Enabled: 0 13 | m_CaptureEditorExceptions: 1 14 | UnityPurchasingSettings: 15 | m_Enabled: 0 16 | m_TestMode: 0 17 | UnityAnalyticsSettings: 18 | m_Enabled: 0 19 | m_InitializeOnStartup: 1 20 | m_TestMode: 0 21 | m_TestEventUrl: 22 | m_TestConfigUrl: 23 | UnityAdsSettings: 24 | m_Enabled: 0 25 | m_InitializeOnStartup: 1 26 | m_TestMode: 0 27 | m_EnabledPlatforms: 4294967295 28 | m_IosGameId: 29 | m_AndroidGameId: 30 | --------------------------------------------------------------------------------