From 480b9cd1ca48817788dcc17cd90346567f97ca28 Mon Sep 17 00:00:00 2001 From: Anton Franzluebbers Date: Thu, 6 Jan 2022 16:02:50 -0500 Subject: [PATCH] reorganized into a package, added a namespace, added an assemblydefinition, attempt at ci for upm branch creation --- .github/workflows/ci.yml | 19 + README.md | 30 + README.txt | 18 - TestVelGameServer/.gitignore | 4 +- .../Assets/{Scenes.meta => Samples.meta} | 2 +- .../VelNetUnity.meta} | 2 +- .../VelNetUnity/1.0.0.meta} | 2 +- .../1.0.0/Dissonance Integration.meta | 8 + .../VelAudioMixer.mixer | 0 .../VelAudioMixer.mixer.meta | 0 .../Dissonance Integration/VelCommsNetwork.cs | 94 + .../VelCommsNetwork.cs.meta | 0 .../VelNetUnity/1.0.0}/Example.meta | 2 +- .../VelNetUnity/1.0.0/Example/NetworkGUI.cs | 76 + .../1.0.0}/Example/NetworkGUI.cs.meta | 0 .../1.0.0/Example/PlayerController.cs | 258 ++ .../1.0.0}/Example/PlayerController.cs.meta | 0 .../1.0.0}/Example/PlayerPrefab.prefab | 0 .../1.0.0}/Example/PlayerPrefab.prefab.meta | 0 .../Example/TestNetworkedGameObject.prefab | 0 .../TestNetworkedGameObject.prefab.meta | 0 .../VelNetUnity/1.0.0}/Example/test.unity | 0 .../1.0.0}/Example/test.unity.meta | 0 .../Assets/VelGameServer/NetworkManager.cs | 505 --- .../Assets/VelGameServer/NetworkObject.cs | 15 - .../Assets/VelGameServer/NetworkPlayer.cs | 233 -- .../VelGameServer/Util/SyncTransform.cs | 80 - .../Packages/VelNetUnity/Editor.meta | 8 + .../Packages/VelNetUnity/Runtime.meta | 8 + .../VelNetUnity/Runtime/NetworkManager.cs | 522 +++ .../Runtime}/NetworkManager.cs.meta | 0 .../VelNetUnity/Runtime/NetworkObject.cs | 16 + .../Runtime}/NetworkObject.cs.meta | 0 .../VelNetUnity/Runtime/NetworkPlayer.cs | 219 ++ .../Runtime}/NetworkPlayer.cs.meta | 0 .../VelNetUnity/Runtime}/Util.meta | 2 +- .../VelNetUnity/Runtime/Util/SyncTransform.cs | 80 + .../Runtime}/Util/SyncTransform.cs.meta | 0 .../DissonanceIntegration/VelAudioMixer.mixer | 83 + .../VelAudioMixer.mixer.meta | 8 + .../DissonanceIntegration/VelCommsNetwork.cs | 2 +- .../VelCommsNetwork.cs.meta | 11 + .../Samples~}/Example/NetworkGUI.cs | 0 .../Samples~/Example/NetworkGUI.cs.meta | 11 + .../Samples~}/Example/PlayerController.cs | 2 +- .../Samples~/Example/PlayerController.cs.meta | 11 + .../Samples~/Example/PlayerPrefab.prefab | 136 + .../Samples~/Example/PlayerPrefab.prefab.meta | 7 + .../Example/TestNetworkedGameObject.prefab | 145 + .../TestNetworkedGameObject.prefab.meta | 7 + .../VelNetUnity/Samples~/Example/test.unity | 3431 +++++++++++++++++ .../Samples~/Example/test.unity.meta | 7 + .../Packages/VelNetUnity/VelNetUnity.asmdef | 14 + .../VelNetUnity/VelNetUnity.asmdef.meta | 7 + .../Packages/VelNetUnity/package.json | 31 + .../Packages/VelNetUnity/package.json.meta | 7 + TestVelGameServer/Packages/manifest.json | 8 +- TestVelGameServer/Packages/packages-lock.json | 26 +- .../ProjectSettings/TimelineSettings.asset | 15 + velnet_logo.png | Bin 0 -> 57760 bytes 60 files changed, 5304 insertions(+), 868 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 README.md delete mode 100644 README.txt rename TestVelGameServer/Assets/{Scenes.meta => Samples.meta} (77%) rename TestVelGameServer/Assets/{VelGameServer.meta => Samples/VelNetUnity.meta} (77%) rename TestVelGameServer/Assets/{VelGameServer/DissonanceIntegration.meta => Samples/VelNetUnity/1.0.0.meta} (77%) create mode 100644 TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration.meta rename TestVelGameServer/Assets/{VelGameServer/DissonanceIntegration => Samples/VelNetUnity/1.0.0/Dissonance Integration}/VelAudioMixer.mixer (100%) rename TestVelGameServer/Assets/{VelGameServer/DissonanceIntegration => Samples/VelNetUnity/1.0.0/Dissonance Integration}/VelAudioMixer.mixer.meta (100%) create mode 100644 TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelCommsNetwork.cs rename TestVelGameServer/Assets/{VelGameServer/DissonanceIntegration => Samples/VelNetUnity/1.0.0/Dissonance Integration}/VelCommsNetwork.cs.meta (100%) rename TestVelGameServer/Assets/{VelGameServer => Samples/VelNetUnity/1.0.0}/Example.meta (77%) create mode 100644 TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/NetworkGUI.cs rename TestVelGameServer/Assets/{VelGameServer => Samples/VelNetUnity/1.0.0}/Example/NetworkGUI.cs.meta (100%) create mode 100644 TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerController.cs rename TestVelGameServer/Assets/{VelGameServer => Samples/VelNetUnity/1.0.0}/Example/PlayerController.cs.meta (100%) rename TestVelGameServer/Assets/{VelGameServer => Samples/VelNetUnity/1.0.0}/Example/PlayerPrefab.prefab (100%) rename TestVelGameServer/Assets/{VelGameServer => Samples/VelNetUnity/1.0.0}/Example/PlayerPrefab.prefab.meta (100%) rename TestVelGameServer/Assets/{VelGameServer => Samples/VelNetUnity/1.0.0}/Example/TestNetworkedGameObject.prefab (100%) rename TestVelGameServer/Assets/{VelGameServer => Samples/VelNetUnity/1.0.0}/Example/TestNetworkedGameObject.prefab.meta (100%) rename TestVelGameServer/Assets/{VelGameServer => Samples/VelNetUnity/1.0.0}/Example/test.unity (100%) rename TestVelGameServer/Assets/{VelGameServer => Samples/VelNetUnity/1.0.0}/Example/test.unity.meta (100%) delete mode 100644 TestVelGameServer/Assets/VelGameServer/NetworkManager.cs delete mode 100644 TestVelGameServer/Assets/VelGameServer/NetworkObject.cs delete mode 100644 TestVelGameServer/Assets/VelGameServer/NetworkPlayer.cs delete mode 100644 TestVelGameServer/Assets/VelGameServer/Util/SyncTransform.cs create mode 100644 TestVelGameServer/Packages/VelNetUnity/Editor.meta create mode 100644 TestVelGameServer/Packages/VelNetUnity/Runtime.meta create mode 100644 TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkManager.cs rename TestVelGameServer/{Assets/VelGameServer => Packages/VelNetUnity/Runtime}/NetworkManager.cs.meta (100%) create mode 100644 TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs rename TestVelGameServer/{Assets/VelGameServer => Packages/VelNetUnity/Runtime}/NetworkObject.cs.meta (100%) create mode 100644 TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkPlayer.cs rename TestVelGameServer/{Assets/VelGameServer => Packages/VelNetUnity/Runtime}/NetworkPlayer.cs.meta (100%) rename TestVelGameServer/{Assets/VelGameServer => Packages/VelNetUnity/Runtime}/Util.meta (77%) create mode 100644 TestVelGameServer/Packages/VelNetUnity/Runtime/Util/SyncTransform.cs rename TestVelGameServer/{Assets/VelGameServer => Packages/VelNetUnity/Runtime}/Util/SyncTransform.cs.meta (100%) create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelAudioMixer.mixer create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelAudioMixer.mixer.meta rename TestVelGameServer/{Assets/VelGameServer => Packages/VelNetUnity/Samples~}/DissonanceIntegration/VelCommsNetwork.cs (99%) create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelCommsNetwork.cs.meta rename TestVelGameServer/{Assets/VelGameServer => Packages/VelNetUnity/Samples~}/Example/NetworkGUI.cs (100%) create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/Example/NetworkGUI.cs.meta rename TestVelGameServer/{Assets/VelGameServer => Packages/VelNetUnity/Samples~}/Example/PlayerController.cs (99%) create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerController.cs.meta create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerPrefab.prefab create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerPrefab.prefab.meta create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/Example/TestNetworkedGameObject.prefab create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/Example/TestNetworkedGameObject.prefab.meta create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/Example/test.unity create mode 100644 TestVelGameServer/Packages/VelNetUnity/Samples~/Example/test.unity.meta create mode 100644 TestVelGameServer/Packages/VelNetUnity/VelNetUnity.asmdef create mode 100644 TestVelGameServer/Packages/VelNetUnity/VelNetUnity.asmdef.meta create mode 100644 TestVelGameServer/Packages/VelNetUnity/package.json create mode 100644 TestVelGameServer/Packages/VelNetUnity/package.json.meta create mode 100644 TestVelGameServer/ProjectSettings/TimelineSettings.asset create mode 100644 velnet_logo.png diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..503cd9e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,19 @@ +name: CI +on: + push: + branches: + - main +jobs: + split-upm: + name: split upm branch + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: split upm branch + run: | + git subtree split -P "$PKG_ROOT" -b upm + git push -u origin upm + env: + PKG_ROOT: TestVelGameServer\Packages\VelNetUnity \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5b430f0 --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# VelNetUnity +Custom networking package for Unity + +![VelNet Logo](velnet_logo.png) +--- + +See [VelNetServer](https://github.com/velaboratory/VelNetServer) for description of the server. + +By contrast to the server, the Unity side is pretty complex. + +### NetworkManager +Deals with instantiating NetworkPlayers, and dealing with join, left, new master client events. Also manages the list of NetworkObjects. It maintains a list of prefabs that can be instantiated, as well as the prefab to use for players. + +### NetworkPlayer +One of these will be instantiated for each player that joins the "room". Most application communication happens by calling methods on this object. Voice comms are also handled within this object. Only one NetworkPlayer "isLocal". The others are remote. The local network player is the one that can modify it's "owned" network objects. It also has a special networkobject representing itself (setup within the prefab, not part of the networkmanager list). This is where most of the user behavior is going to go (e.g. an avatar). + +### NetworkObject +Something that can be owned by a network player, who is responsible for updating it. Only the owner network player can/should modify a network object, whether locally or in response to a received message from the local version. NetworkObjects are delineated by an session-unique id, which consists of the creator's userid + "-" + an increasing number designated by the creator. Only local NetworkPlayers should send instantiate message, which contain this id. This class should be extended to sync and send messages. Scenes are basically built from NetworkObjects. Scene's can also start with network objects. Those are known by all, and start with "-1-increasing". That should happen the same on all clients, and is done locally at the start of the networkmanager. An example of a NetworkObject is SyncTransform, which is a simple one that keeps an object's position and orientation synchronized. + +### Ownership +Ownership of objects changes regularly. Any local networkplayer can send a message to take ownership of a networkid. That client immediately assumes ownership. The message is sent to the network, and will be ordered with any other ownership messages. So, if two clients try to get ownership at the same time, both will assume ownership, but one will happen after the other. This means that the one who was first will quickly lose ownership. + +### Joining +An interesting problem is what to do when new clients join. This is partially left up to the developer. Any objects that are instantiated (or scene objects that are deleted) will be automatically handled. + +### Message Groups +Clients can manage network traffic using messaging groups. This is especially useful for audio, where you can maintain a list of people close enough to you to hear audio + + + diff --git a/README.txt b/README.txt deleted file mode 100644 index 3704a41..0000000 --- a/README.txt +++ /dev/null @@ -1,18 +0,0 @@ -See VelNet for description of the server. - -By contrast to the server, the Unity side is pretty complex. - -NetworkManager - Deals with instantiating NetworkPlayers, and dealing with join, left, new master client events. Also manages the list of NetworkObjects. It maintains a list of prefabs that can be instantiated, as well as the prefab to use for players. - -NetworkPlayer - One of these will be instantiated for each player that joins the "room". Most application communication happens by calling methods on this object. Voice comms are also handled within this object. Only one NetworkPlayer "isLocal". The others are remote. The local network player is the one that can modify it's "owned" network objects. It also has a special networkobject representing itself (setup within the prefab, not part of the networkmanager list). This is where most of the user behavior is going to go (e.g. an avatar). - -NetworkObject - Something that can be owned by a network player, who is responsible for updating it. Only the owner network player can/should modify a network object, whether locally or in response to a received message from the local version. NetworkObjects are delineated by an session-unique id, which consists of the creator's userid + "-" + an increasing number designated by the creator. Only local NetworkPlayers should send instantiate message, which contain this id. This class should be extended to sync and send messages. Scenes are basically built from NetworkObjects. Scene's can also start with network objects. Those are known by all, and start with "-1-increasing". That should happen the same on all clients, and is done locally at the start of the networkmanager. An example of a NetworkObject is SyncTransform, which is a simple one that keeps an object's position and orientation synchronized. - -Ownership of objects changes regularly. Any local networkplayer can send a message to take ownership of a networkid. That client immediately assumes ownership. The message is sent to the network, and will be ordered with any other ownership messages. So, if two clients try to get ownership at the same time, both will assume ownership, but one will happen after the other. This means that the one who was first will quickly lose ownership. - -An interesting problem is what to do when new clients join. This is partially left up to the developer. Any objects that are instantiated (or scene objects that are deleted) will be automatically handled. - -Clients can manage network traffic using messaging groups. This is especially useful for audio, where you can maintain a list of people close enough to you to hear audio - - - diff --git a/TestVelGameServer/.gitignore b/TestVelGameServer/.gitignore index 7a5cd83..4a412d2 100644 --- a/TestVelGameServer/.gitignore +++ b/TestVelGameServer/.gitignore @@ -69,4 +69,6 @@ crashlytics-build.properties # Temporary auto-generated Android Assets /[Aa]ssets/[Ss]treamingAssets/aa.meta -/[Aa]ssets/[Ss]treamingAssets/aa/* \ No newline at end of file +/[Aa]ssets/[Ss]treamingAssets/aa/* + +.idea/ diff --git a/TestVelGameServer/Assets/Scenes.meta b/TestVelGameServer/Assets/Samples.meta similarity index 77% rename from TestVelGameServer/Assets/Scenes.meta rename to TestVelGameServer/Assets/Samples.meta index 524fd07..5c27ab4 100644 --- a/TestVelGameServer/Assets/Scenes.meta +++ b/TestVelGameServer/Assets/Samples.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 867c77c74f84b41acb49da778488a75f +guid: b52a74ceb5dcd9d498e95617f4247a27 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/TestVelGameServer/Assets/VelGameServer.meta b/TestVelGameServer/Assets/Samples/VelNetUnity.meta similarity index 77% rename from TestVelGameServer/Assets/VelGameServer.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity.meta index 7596b48..1c140ce 100644 --- a/TestVelGameServer/Assets/VelGameServer.meta +++ b/TestVelGameServer/Assets/Samples/VelNetUnity.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 09c6fdabe05be4c86917b1c585ed4a40 +guid: 8b822dd2b9e99144097e61694b8dab65 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/TestVelGameServer/Assets/VelGameServer/DissonanceIntegration.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0.meta similarity index 77% rename from TestVelGameServer/Assets/VelGameServer/DissonanceIntegration.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0.meta index da5ee29..e3997f7 100644 --- a/TestVelGameServer/Assets/VelGameServer/DissonanceIntegration.meta +++ b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 21c2212b420fd48a1b3552af8d219f80 +guid: 14a35ccfe945cc54292ca4e8940b53b9 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration.meta new file mode 100644 index 0000000..a13368f --- /dev/null +++ b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c506b9118efc2de4ea5f2b2f26a52b9d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Assets/VelGameServer/DissonanceIntegration/VelAudioMixer.mixer b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelAudioMixer.mixer similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/DissonanceIntegration/VelAudioMixer.mixer rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelAudioMixer.mixer diff --git a/TestVelGameServer/Assets/VelGameServer/DissonanceIntegration/VelAudioMixer.mixer.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelAudioMixer.mixer.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/DissonanceIntegration/VelAudioMixer.mixer.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelAudioMixer.mixer.meta diff --git a/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelCommsNetwork.cs b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelCommsNetwork.cs new file mode 100644 index 0000000..a862aa6 --- /dev/null +++ b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelCommsNetwork.cs @@ -0,0 +1,94 @@ +using System; +using Dissonance; +using Dissonance.Networking; +using UnityEngine; + + +namespace VelNetUnity +{ + public class VelCommsNetwork : MonoBehaviour, ICommsNetwork + { + public ConnectionStatus Status => manager.connected ? ConnectionStatus.Connected : ConnectionStatus.Disconnected; + public NetworkMode Mode => NetworkMode.Client; + + public event Action ModeChanged; + public event Action PlayerJoined; + public event Action PlayerLeft; + public event Action VoicePacketReceived; + public event Action TextPacketReceived; + public event Action PlayerStartedSpeaking; + public event Action PlayerStoppedSpeaking; + public event Action PlayerEnteredRoom; + public event Action PlayerExitedRoom; + + ConnectionStatus _status = ConnectionStatus.Disconnected; + CodecSettings initSettings; + public string dissonanceId; + public DissonanceComms comms; + public NetworkManager manager; + + public Action> voiceQueued = delegate { }; //listen to this if you want to send voice + + public void Initialize(string playerName, Rooms rooms, PlayerChannels playerChannels, RoomChannels roomChannels, CodecSettings codecSettings) + { + dissonanceId = playerName; + initSettings = codecSettings; + comms.ResetMicrophoneCapture(); + } + + public void voiceReceived(string sender, byte[] data) + { + uint sequenceNumber = BitConverter.ToUInt32(data, 0); + VoicePacket vp = new VoicePacket(sender, ChannelPriority.Default, 1, true, new ArraySegment(data, 4, data.Length - 4), sequenceNumber); + VoicePacketReceived(vp); + } + + public void SendText(string data, ChannelType recipientType, string recipientId) + { + Debug.Log("sending text"); + } + + public void SendVoice(ArraySegment data) + { + voiceQueued(data); + } + + // Start is called before the first frame update + void Start() + { + _status = ConnectionStatus.Connected; + comms = GetComponent(); + } + + public void playerJoined(string id) + { + Debug.Log("dissonance player joined"); + PlayerJoined(id, initSettings); + RoomEvent re = new RoomEvent(); + re.Joined = true; + re.Room = "Global"; + re.PlayerName = id; + PlayerEnteredRoom(re); + } + + public void playerLeft(string id) + { + RoomEvent re = new RoomEvent(); + re.Joined = false; + re.Room = "Global"; + re.PlayerName = id; + PlayerExitedRoom(re); + PlayerLeft(id); + } + + public void playerStartedSpeaking(string id) + { + PlayerStartedSpeaking(id); + } + + public void playerStoppedSpeaking(string id) + { + PlayerStoppedSpeaking(id); + } + } +} \ No newline at end of file diff --git a/TestVelGameServer/Assets/VelGameServer/DissonanceIntegration/VelCommsNetwork.cs.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelCommsNetwork.cs.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/DissonanceIntegration/VelCommsNetwork.cs.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Dissonance Integration/VelCommsNetwork.cs.meta diff --git a/TestVelGameServer/Assets/VelGameServer/Example.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example.meta similarity index 77% rename from TestVelGameServer/Assets/VelGameServer/Example.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example.meta index 5de344a..43f3286 100644 --- a/TestVelGameServer/Assets/VelGameServer/Example.meta +++ b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2fc687ece57d64c7082cd32261ac438b +guid: 07900994db5c50c4794e338da120f31b folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/NetworkGUI.cs b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/NetworkGUI.cs new file mode 100644 index 0000000..c781ba4 --- /dev/null +++ b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/NetworkGUI.cs @@ -0,0 +1,76 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +namespace VelNetUnity +{ + public class NetworkGUI : MonoBehaviour + { + public NetworkManager networkManager; + public InputField userInput; + public InputField sendInput; + public InputField roomInput; + public Text messages; + public List messageBuffer; + public Dropdown microphones; + Dissonance.DissonanceComms comms; + + public void handleSend() + { + if (sendInput.text != "") + { + networkManager.sendTo(NetworkManager.MessageType.OTHERS, sendInput.text); + } + } + + public void handleLogin() + { + if (userInput.text != "") + { + networkManager.login(userInput.text, "nopass"); + } + } + + public void handleJoin() + { + if (roomInput.text != "") + { + networkManager.join(roomInput.text); + } + } + + // Start is called before the first frame update + void Start() + { + comms = FindObjectOfType(); + microphones.AddOptions(new List(Microphone.devices)); + networkManager.messageReceived += (m) => + { + string s = m.type + ":" + m.sender + ":" + m.text; + messageBuffer.Add(s); + messages.text = ""; + + + if (messageBuffer.Count > 10) + { + messageBuffer.RemoveAt(0); + } + + for (int i = 0; i < messageBuffer.Count; i++) + { + messages.text = messages.text + messageBuffer[i] + "\n"; + } + }; + } + + public void handleMicrophoneSelection() + { + comms.MicrophoneName = microphones.options[microphones.value].text; + } + + // Update is called once per frame + void Update() + { + } + } +} \ No newline at end of file diff --git a/TestVelGameServer/Assets/VelGameServer/Example/NetworkGUI.cs.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/NetworkGUI.cs.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Example/NetworkGUI.cs.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/NetworkGUI.cs.meta diff --git a/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerController.cs b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerController.cs new file mode 100644 index 0000000..5574949 --- /dev/null +++ b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerController.cs @@ -0,0 +1,258 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using Dissonance; +using System.Text; + +namespace VelNetUnity +{ + public class PlayerController : NetworkObject, IDissonancePlayer + { + VelCommsNetwork comms; + bool isSpeaking = false; + uint lastAudioId = 0; + + public string dissonanceID = ""; + + //required by dissonance for spatial audio + public string PlayerId => dissonanceID; + public Vector3 Position => transform.position; + public Quaternion Rotation => transform.rotation; + public NetworkPlayerType Type => owner.isLocal ? NetworkPlayerType.Local : NetworkPlayerType.Remote; + public bool IsTracking => true; + + public Vector3 targetPosition; + public Quaternion targetRotation; + + public List closePlayers = new List(); + + + public byte[] getSyncMessage() + { + float[] data = new float[7]; + for (int i = 0; i < 3; i++) + { + data[i] = transform.position[i]; + data[i + 3] = transform.rotation[i]; + } + + data[6] = transform.rotation[3]; + + byte[] toReturn = new byte[sizeof(float) * data.Length]; + Buffer.BlockCopy(data, 0, toReturn, 0, toReturn.Length); + return toReturn; + } + + public override void handleMessage(string identifier, byte[] message) + { + switch (identifier) + { + case "s": //sync message + float[] data = new float[7]; + Buffer.BlockCopy(message, 0, data, 0, message.Length); + for (int i = 0; i < 3; i++) + { + targetPosition[i] = data[i]; + targetRotation[i] = data[i + 3]; + } + + targetRotation[3] = data[6]; + break; + case "a": //audio data + { + if (isSpeaking) + { + comms.voiceReceived(dissonanceID, message); + } + + break; + } + case "d": //dissonance id (player joined) + { + if (dissonanceID == "") //I don't have this yet + { + dissonanceID = Encoding.UTF8.GetString(message); + //tell the comms network that this player joined the channel + comms.playerJoined(dissonanceID); //tell dissonance + comms.comms.TrackPlayerPosition(this); //tell dissonance to track the remote player + } + + break; + } + case "x": //speaking state + { + if (message[0] == 0) + { + comms.playerStoppedSpeaking(dissonanceID); + isSpeaking = false; + } + else + { + comms.playerStartedSpeaking(dissonanceID); + isSpeaking = true; + } + + break; + } + } + } + + // Start is called before the first frame update + void Start() + { + //handle dissonance stuff + comms = FindObjectOfType(); + if (comms != null) + { + if (owner.isLocal) + { + setDissonanceID(comms.dissonanceId); + comms.voiceQueued += sendVoiceData; + + //we also need to know when other players join, so we can send the dissonance ID again + + owner.manager.onPlayerJoined += (player) => + { + byte[] b = Encoding.UTF8.GetBytes(dissonanceID); + owner.sendMessage(this, "d", b); + }; + owner.manager.setupMessageGroup("close", closePlayers.ToArray()); + } + } + + if (owner.isLocal) + { + StartCoroutine(syncBehavior()); + } + } + + void sendVoiceData(ArraySegment data) + { + //need to send it + if (owner != null && owner.isLocal) + { + byte[] toSend = new byte[data.Count + 4]; + byte[] lastAudioIdBytes = BitConverter.GetBytes(lastAudioId++); + Buffer.BlockCopy(lastAudioIdBytes, 0, toSend, 0, 4); + Buffer.BlockCopy(data.Array, data.Offset, toSend, 4, data.Count); + owner.sendGroupMessage(this, "close", "a", toSend, false); //send voice data unreliably + } + } + + public void setDissonanceID(string id) //this sort of all initializes dissonance + { + dissonanceID = id; + byte[] b = Encoding.UTF8.GetBytes(dissonanceID); + owner.sendMessage(this, "d", b); + comms.comms.TrackPlayerPosition(this); + } + + void voiceInitialized(string id) + { + dissonanceID = id; + } + + void OnDestroy() + { + comms.playerLeft(dissonanceID); + } + + + IEnumerator syncBehavior() + { + while (true) + { + owner.sendMessage(this, "s", getSyncMessage()); + yield return new WaitForSeconds(.1f); + } + } + + // Update is called once per frame + void Update() + { + if (owner != null && owner.isLocal) + { + PlayerController[] players = FindObjectsOfType(); + bool shouldUpdate = false; + for (int i = 0; i < players.Length; i++) + { + if (players[i] == this) + { + continue; + } + + float dist = Vector3.Distance(players[i].transform.position, transform.position); + if (dist < 2 && !closePlayers.Contains(players[i].owner.userid)) + { + closePlayers.Add(players[i].owner.userid); + shouldUpdate = true; + } + else if (dist >= 2 && closePlayers.Contains(players[i].owner.userid)) + { + closePlayers.Remove(players[i].owner.userid); + shouldUpdate = true; + } + } + + if (shouldUpdate) + { + owner.manager.setupMessageGroup("close", closePlayers.ToArray()); + } + } + + + if (owner != null && !owner.isLocal) + { + transform.position = Vector3.Lerp(transform.position, targetPosition, .1f); + transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, .1f); + } + else if (owner != null && owner.isLocal) + { + //handle dissonance comms + + //if we're not speaking, and the comms say we are, send a speaking event, which will be received on other network players and sent to their comms accordingly + if (comms.comms.FindPlayer(dissonanceID).IsSpeaking != isSpeaking) //unfortunately, there does not seem to be an event for this + { + isSpeaking = !isSpeaking; + byte[] toSend = new byte[1]; + toSend[0] = isSpeaking ? (byte)1 : (byte)0; + owner.sendMessage(this, "x", toSend); + + if (!isSpeaking) + { + lastAudioId = 0; + } + } + + + Vector3 movement = new Vector3(); + movement.x += Input.GetAxis("Horizontal"); + movement.y += Input.GetAxis("Vertical"); + movement.z = 0; + transform.Translate(movement * Time.deltaTime); + + if (Input.GetKeyDown(KeyCode.Space)) + { + owner.networkInstantiate("TestNetworkedGameObject"); + } + + if (Input.GetKeyDown(KeyCode.BackQuote)) + { + foreach (KeyValuePair kvp in owner.manager.objects) + { + owner.takeOwnership(kvp.Key); + } + } + + if (Input.GetKeyDown(KeyCode.Backspace)) + { + foreach (KeyValuePair kvp in owner.manager.objects) + { + owner.networkDestroy(kvp.Key); + } + } + } + } + } +} \ No newline at end of file diff --git a/TestVelGameServer/Assets/VelGameServer/Example/PlayerController.cs.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerController.cs.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Example/PlayerController.cs.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerController.cs.meta diff --git a/TestVelGameServer/Assets/VelGameServer/Example/PlayerPrefab.prefab b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerPrefab.prefab similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Example/PlayerPrefab.prefab rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerPrefab.prefab diff --git a/TestVelGameServer/Assets/VelGameServer/Example/PlayerPrefab.prefab.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerPrefab.prefab.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Example/PlayerPrefab.prefab.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/PlayerPrefab.prefab.meta diff --git a/TestVelGameServer/Assets/VelGameServer/Example/TestNetworkedGameObject.prefab b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/TestNetworkedGameObject.prefab similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Example/TestNetworkedGameObject.prefab rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/TestNetworkedGameObject.prefab diff --git a/TestVelGameServer/Assets/VelGameServer/Example/TestNetworkedGameObject.prefab.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/TestNetworkedGameObject.prefab.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Example/TestNetworkedGameObject.prefab.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/TestNetworkedGameObject.prefab.meta diff --git a/TestVelGameServer/Assets/VelGameServer/Example/test.unity b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/test.unity similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Example/test.unity rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/test.unity diff --git a/TestVelGameServer/Assets/VelGameServer/Example/test.unity.meta b/TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/test.unity.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Example/test.unity.meta rename to TestVelGameServer/Assets/Samples/VelNetUnity/1.0.0/Example/test.unity.meta diff --git a/TestVelGameServer/Assets/VelGameServer/NetworkManager.cs b/TestVelGameServer/Assets/VelGameServer/NetworkManager.cs deleted file mode 100644 index aeab512..0000000 --- a/TestVelGameServer/Assets/VelGameServer/NetworkManager.cs +++ /dev/null @@ -1,505 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Net.Sockets; -using System.Text; -using System.Threading; -using UnityEngine; -using Dissonance; -using System.Net; - -public class NetworkManager : MonoBehaviour -{ - public enum MessageType { OTHERS=0,ALL=1,OTHERS_ORDERED=2,ALL_ORDERED=3}; - public string host; - public int port; - #region private members - private TcpClient socketConnection; - private Socket udpSocket; - public bool udpConnected = false; - IPEndPoint RemoteEndPoint; - private Thread clientReceiveThread; - private Thread clientReceiveThreadUDP; - public int userid = -1; - public string room; - int messagesReceived = 0; - - public GameObject playerPrefab; - public Dictionary players = new Dictionary(); - - public Action onJoinedRoom = delegate { }; - public Action onPlayerJoined = delegate { }; - public Action onPlayerLeft = delegate { }; - - public List prefabs = new List(); - public NetworkObject[] sceneObjects; - public List deletedSceneObjects = new List(); - public Dictionary objects = new Dictionary(); //maintains a list of all known objects on the server (ones that have ids) - NetworkPlayer masterPlayer = null; - #endregion - // Use this for initialization - public class Message - { - public int type; - public string text; - public int sender; - } - public List receivedMessages = new List(); - void Start() - { - ConnectToTcpServer(); - sceneObjects = GameObject.FindObjectsOfType(); //add all local network objects - - } - - - - private void addMessage(Message m) - { - lock (receivedMessages) - { - //Debug.Log(messagesReceived++); - receivedMessages.Add(m); - } - } - private void Update() - { - lock(receivedMessages) { //the main thread, which can do Unity stuff - foreach(Message m in receivedMessages) - { - if(m.type == 0) //when you join the server - { - this.userid = m.sender; - Debug.Log("joined server"); - - //start the udp thread - clientReceiveThreadUDP = new Thread(new ThreadStart(ListenForDataUDP)); - clientReceiveThreadUDP.IsBackground = true; - clientReceiveThreadUDP.Start(); - } - - if (m.type == 2) - { - //if this message is for me, that means I joined a new room... - if (this.userid == m.sender) - { - foreach (KeyValuePair kvp in players) - { - Destroy(kvp.Value.gameObject); - } - players.Clear(); //we clear the list, but will recreate as we get messages from people in our room - - if (m.text != "") - { - NetworkPlayer player = GameObject.Instantiate(playerPrefab).GetComponent(); - - player.isLocal = true; - player.userid = m.sender; - players.Add(userid, player); - player.room = m.text; - player.manager = this; - onJoinedRoom(player); - - - } - } - else //not for me, a player is joining or leaving - { - NetworkPlayer me = players[userid]; - - if (me.room != m.text) - { - - //we got a left message, kill it - //change ownership of all objects to master - - foreach (KeyValuePair kvp in objects) - { - if (kvp.Value.owner == players[m.sender]) //the owner is the player that left - { - if (me.isLocal && me == masterPlayer) //I'm the local master player, so can take ownership immediately - { - me.takeOwnership(kvp.Key); - } - else if (players[m.sender] == masterPlayer) //the master player left, so everyone should set the owner null (we should get a new master shortly) - { - kvp.Value.owner = null; - } - } - } - - Destroy(players[m.sender].gameObject); - players.Remove(m.sender); - } - else - { - //we got a join mesage, create it - NetworkPlayer player = GameObject.Instantiate(playerPrefab).GetComponent(); - player.isLocal = false; - player.room = m.text; - player.userid = m.sender; - player.manager = this; - players.Add(m.sender, player); - onPlayerJoined(player); - - } - } - } - if(m.type == 3) //generic message - { - - players[m.sender]?.handleMessage(m); - - } - if(m.type == 4) //change master player (this should only happen when the first player joins or if the master player leaves) - { - if (masterPlayer == null) - { - masterPlayer = players[m.sender]; - - //no master player yet, add the scene objects - - for (int i = 0; i < sceneObjects.Length; i++) - { - sceneObjects[i].networkId = -1 + "-" + i; - sceneObjects[i].owner = masterPlayer; - sceneObjects[i].isSceneObject = true; //needed for special handling when deleted - objects.Add(sceneObjects[i].networkId,sceneObjects[i]); - } - - } - else - { - masterPlayer = players[m.sender]; - } - - masterPlayer.setAsMasterPlayer(); - - //master player should take over any objects that do not have an owner - - foreach(KeyValuePair kvp in objects) - { - if (kvp.Value.owner == null) - { - kvp.Value.owner = masterPlayer; - } - } - - } - - messageReceived(m); - } - receivedMessages.Clear(); - } - } - private void OnApplicationQuit() - { - socketConnection.Close(); - } - - public Action joinedRoom = delegate { }; - public Action messageReceived = delegate { }; - public Action loggedIn = delegate { }; - public Action roomsReceived = delegate { }; - - public bool connected = false; - /// - /// Setup socket connection. - /// - private void ConnectToTcpServer() - { - try - { - clientReceiveThread = new Thread(new ThreadStart(ListenForData)); - clientReceiveThread.IsBackground = true; - clientReceiveThread.Start(); - - - - } - catch (Exception e) - { - Debug.Log("On client connect exception " + e); - } - } - void handleMessage(string s) //this parses messages from the server, and adds them to a queue to be processed on the main thread - { - Message m = new Message(); - string[] sections = s.Split(':'); - if (sections.Length > 0) - { - int type = int.Parse(sections[0]); - - switch (type) - { - case 0://logged in message - { - if(sections.Length > 1) - { - - m.type = type; - m.sender = int.Parse(sections[1]); - m.text = ""; - addMessage(m); - } - break; - } - case 1://room info message - { - - - break; - } - case 2: //joined room message - { - if(sections.Length > 2) - { - m.type = 2; - int user_id = int.Parse(sections[1]); - m.sender = user_id; - string new_room = sections[2]; - m.text = new_room; - - addMessage(m); - } - break; - } - case 3: //text message - { - if(sections.Length > 2) - { - m.type = 3; - m.sender = int.Parse(sections[1]); - m.text = sections[2]; - addMessage(m); - } - break; - } - case 4: //change master client - { - if(sections.Length > 1) - { - m.type = 4; - m.sender = int.Parse(sections[1]); - addMessage(m); - } - break; - } - - } - } - } - /// - /// Runs in background clientReceiveThread; Listens for incomming data. - /// - private void ListenForData() - { - - connected = true; - try - { - socketConnection = new TcpClient(host, port); - socketConnection.NoDelay = true; - Byte[] bytes = new Byte[1024]; - string partialMessage = ""; - while (true) - { - // Get a stream object for reading - using (NetworkStream stream = socketConnection.GetStream()) - { - int length; - // Read incomming stream into byte arrary. - while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) - { - var incommingData = new byte[length]; - Array.Copy(bytes, 0, incommingData, 0, length); - // Convert byte array to string message. - string serverMessage = Encoding.ASCII.GetString(incommingData); - string[] sections = serverMessage.Split('\n'); - if(sections.Length > 1) - { - lock(receivedMessages){ - for (int i = 0; i < sections.Length - 1; i++) - { - if (i == 0) - { - handleMessage(partialMessage + sections[0]); - partialMessage = ""; - } - else - { - handleMessage(sections[i]); - } - } - } - - } - partialMessage = partialMessage + sections[sections.Length - 1]; - } - } - } - } - - - catch (Exception socketException) - { - Debug.Log("Socket exception: " + socketException); - - } - connected = false; - } - - private void ListenForDataUDP() - { - //I don't yet have a UDP connection - try - { - var addresses = Dns.GetHostAddresses(host); - Debug.Assert(addresses.Length > 0); - RemoteEndPoint = new IPEndPoint(addresses[0], port); - - - udpSocket = new Socket(AddressFamily.InterNetwork, - SocketType.Dgram, ProtocolType.Udp); - - - udpConnected = false; - byte[] buffer = new byte[1024]; - while (true) - { - - string welcome = userid + ":0:Hello"; - byte[] data = Encoding.ASCII.GetBytes(welcome); - udpSocket.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint); - - if(udpSocket.Available == 0) - { - Thread.Sleep(100); - Debug.Log("Waiting for UDP response"); - } - else - { - break; - } - - - } - udpConnected = true; - while (true) { - int numReceived = udpSocket.Receive(buffer); - - string message = Encoding.UTF8.GetString(buffer, 0, numReceived); - - string[] sections = message.Split(':'); - if(sections[0] == "0") - { - Debug.Log("UDP connected"); - } - if(sections[0] == "3") - { - handleMessage(message); - } - } - - } catch(Exception socketException) - { - Debug.Log("Socket exception: " + socketException); - } - } - - private void SendUdpMessage(string message) - { - - if (udpSocket == null || !udpConnected) - { - return; - } - byte[] data = Encoding.UTF8.GetBytes(message); - //Debug.Log("Attempting to send: " + message); - udpSocket.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint); - } - - /// - /// Send message to server using socket connection. - /// - private void SendNetworkMessage(string clientMessage) - { - if (socketConnection == null) - { - return; - } - try - { - // Get a stream object for writing. - NetworkStream stream = socketConnection.GetStream(); - if (stream.CanWrite) - { - // Convert string message to byte array. - clientMessage = clientMessage + "\n"; //append a new line to delineate the message - byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(clientMessage); - // Write byte array to socketConnection stream. - stream.Write(clientMessageAsByteArray, 0, clientMessageAsByteArray.Length); - - } - } - catch (SocketException socketException) - { - Debug.Log("Socket exception: " + socketException); - } - } - - public void login(string username, string password) - { - SendNetworkMessage("0:" + username + ":" + password); - } - public void join(string roomname) - { - SendNetworkMessage("2:" + roomname); - } - public void leave() - { - SendNetworkMessage("2:-1"); - } - public void sendTo(MessageType type, string message, bool reliable=true) - { - if (reliable) - { - SendNetworkMessage("3:" + (int)type + ":" + message); - } - else - { - SendUdpMessage(userid + ":3:" + (int)type + ":" + message); - } - } - public void sendToGroup(string group, string message, bool reliable=true) - { - if (reliable) - { - SendNetworkMessage("4:" + group + ":" + message); - } - else - { - SendUdpMessage(userid + ":4:" + group + ":" + message); - } - } - - //changes the designated group that sendto(4) will go to - public void setupMessageGroup(string groupname, int[] userids) - { - SendNetworkMessage("5:" + groupname + ":" + String.Join(":", userids)); - } - public void deleteNetworkObject(string networkId) - { - if (objects.ContainsKey(networkId)) - { - NetworkObject obj = objects[networkId]; - if (obj.isSceneObject) - { - deletedSceneObjects.Add(networkId); - } - GameObject.Destroy(obj.gameObject); - objects.Remove(networkId); - } - - } -} \ No newline at end of file diff --git a/TestVelGameServer/Assets/VelGameServer/NetworkObject.cs b/TestVelGameServer/Assets/VelGameServer/NetworkObject.cs deleted file mode 100644 index 96b5739..0000000 --- a/TestVelGameServer/Assets/VelGameServer/NetworkObject.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; - -/// -/// This is a base class for all objects that a player can instantiated/owned -/// -public abstract class NetworkObject: MonoBehaviour -{ - public NetworkPlayer owner; - public string networkId; //this is forged from the combination of the creator's id (-1 in the case of a scene object) and an object id, so it's always unique for a room - public string prefabName; //this may be empty if it's not a prefab (scene object) - public bool isSceneObject=false; - public abstract void handleMessage(string identifier, byte[] message); -} diff --git a/TestVelGameServer/Assets/VelGameServer/NetworkPlayer.cs b/TestVelGameServer/Assets/VelGameServer/NetworkPlayer.cs deleted file mode 100644 index bc9ae80..0000000 --- a/TestVelGameServer/Assets/VelGameServer/NetworkPlayer.cs +++ /dev/null @@ -1,233 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using System.Text; -using System; - - -[RequireComponent(typeof(NetworkObject))] -public class NetworkPlayer : MonoBehaviour -{ - - public NetworkObject myObject; - public int userid; - public string username; - - public string room; - public NetworkManager manager; - - public bool isLocal = false; - - public int lastObjectId=0; //for instantiation - - - bool isMaster = false; - - void Start() - { - myObject.owner = this; - this.manager = GameObject.FindObjectOfType(); - manager.onPlayerJoined += handlePlayerJoined; - } - - // Update is called once per frame - void Update() - { - - - - } - - public void handlePlayerJoined(NetworkPlayer player) - { - //if this is the local player, go through the objects that I own, and send instantiation messages for the ones that have prefab names - if (this.isLocal) - { - foreach(KeyValuePair kvp in manager.objects) - { - if(kvp.Value.owner == this && kvp.Value.prefabName != "") - { - manager.sendTo(NetworkManager.MessageType.OTHERS, "7," + kvp.Value.networkId + "," + kvp.Value.prefabName); - - } - } - - if (isMaster) - { - //send a list of scene object ids when someone joins - sendSceneUpdate(); - } - } - } - - - public void handleMessage(NetworkManager.Message m) - { - //these are generally things that come from the "owner" and should be enacted locally, where appropriate - //we need to parse the message - - //types of messages - string[] messages = m.text.Split(';'); //messages are split by ; - for(int i = 0; i < messages.Length; i++) - { - //individual message parameters separated by comma - string[] sections = messages[i].Split(','); - - switch (sections[0]) - { - case "1": //update my object's data - { - string identifier = sections[1]; - byte[] message = Convert.FromBase64String(sections[2]); - myObject.handleMessage(identifier, message); - break; - } - case "5": //sync update for an object I may own - { - - string objectKey = sections[1]; - string identifier = sections[2]; - string syncMessage = sections[3]; - byte[] messageBytes = Convert.FromBase64String(syncMessage); - if (manager.objects.ContainsKey(objectKey)) - { - if(manager.objects[objectKey].owner == this) - { - manager.objects[objectKey].handleMessage(identifier, messageBytes); - } - } - - break; - } - case "6": //I'm trying to take ownership of an object - { - string networkId = sections[1]; - - if (manager.objects.ContainsKey(networkId)) - { - manager.objects[networkId].owner = this; - } - - break; - } - case "7": //I'm trying to instantiate an object - { - string networkId = sections[1]; - string prefabName = sections[2]; - if (manager.objects.ContainsKey(networkId)) - { - break; //we already have this one, ignore - } - NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName); - if (temp != null) - { - NetworkObject instance = GameObject.Instantiate(temp); - instance.networkId = networkId; - instance.prefabName = prefabName; - instance.owner = this; - manager.objects.Add(instance.networkId, instance); - } - - break; - } - case "8": //I'm trying to destroy a gameobject I own - { - string networkId = sections[1]; - - manager.deleteNetworkObject(networkId); - break; - } - case "9": //deleted scene objects - { - - for (int k = 1; k < sections.Length; k++) - { - manager.deleteNetworkObject(sections[k]); - } - - break; - } - } - } - - } - - public void setAsMasterPlayer() - { - isMaster = true; - //if I'm master, I'm now responsible for updating all scene objects - //FindObjectsOfType(); - } - - public void sendGroupMessage(NetworkObject obj, string group, string identifier, byte[] data, bool reliable=true) - { - if (obj == myObject) - { - manager.sendToGroup(group, "1," + identifier + "," + Convert.ToBase64String(data), reliable); - } - else - { - manager.sendToGroup(group, "5," + obj.networkId + "," + identifier + "," + Convert.ToBase64String(data), reliable); - } - } - public void sendMessage(NetworkObject obj, string identifier, byte[] data, bool reliable=true) - { - if (obj == myObject) - { - manager.sendTo(NetworkManager.MessageType.OTHERS, "1," + identifier +"," + Convert.ToBase64String(data), reliable); - } - else - { - - manager.sendTo(NetworkManager.MessageType.OTHERS, "5," + obj.networkId + "," + identifier + "," + Convert.ToBase64String(data), reliable); - } - } - - public NetworkObject networkInstantiate(string prefabName) - { - if (!isLocal) - { - return null; //must be the local player to call instantiate - } - string networkId = this.userid + "-" + lastObjectId++; - - - NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName); - if (temp != null) - { - NetworkObject instance = GameObject.Instantiate(temp); - instance.networkId = networkId; - instance.prefabName = prefabName; - instance.owner = this; - manager.objects.Add(instance.networkId, instance); - - manager.sendTo(NetworkManager.MessageType.OTHERS, "7," + networkId + "," + prefabName); //only sent to others, as I already instantiated this. Nice that it happens immediately. - return instance; - } - return null; - } - - public void networkDestroy(string networkId) - { - if (!manager.objects.ContainsKey(networkId) || manager.objects[networkId].owner != this || !isLocal) return; //must be the local owner of the object to destroy it - manager.sendTo(NetworkManager.MessageType.ALL_ORDERED, "8," + networkId); //send to all, which will make me delete as well - - } - - public void takeOwnership(string networkId) - { - if (!manager.objects.ContainsKey(networkId) || !isLocal) return; //must exist and be the the local player - - manager.objects[networkId].owner = this; //immediately successful - manager.sendTo(NetworkManager.MessageType.ALL_ORDERED, "6," + networkId); //must be ordered, so that ownership transfers are not confused. Also sent to all players, so that multiple simultaneous requests will result in the same outcome. - - } - - public void sendSceneUpdate() - { - - manager.sendTo(NetworkManager.MessageType.OTHERS, "9," + string.Join(",", manager.deletedSceneObjects)); - } - - -} diff --git a/TestVelGameServer/Assets/VelGameServer/Util/SyncTransform.cs b/TestVelGameServer/Assets/VelGameServer/Util/SyncTransform.cs deleted file mode 100644 index 77d2274..0000000 --- a/TestVelGameServer/Assets/VelGameServer/Util/SyncTransform.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; -using UnityEngine; - -/// -/// A simple class that will sync the position and rotation of a network object -/// -public class SyncTransform : NetworkObject -{ - - public Vector3 targetPosition; - public Quaternion targetRotation; - - - public byte[] getSyncMessage() - { - float[] data = new float[7]; - for(int i = 0; i < 3; i++) - { - data[i] = transform.position[i]; - data[i + 3] = transform.rotation[i]; - } - data[6] = transform.rotation[3]; - - byte[] toReturn = new byte[sizeof(float) * data.Length]; - Buffer.BlockCopy(data, 0, toReturn,0, toReturn.Length); - return toReturn; - } - - public override void handleMessage(string identifier, byte[] message) - { - switch (identifier) - { - case "s": - float[] data = new float[7]; - Buffer.BlockCopy(message, 0, data, 0, message.Length); - for (int i = 0; i < 3; i++) - { - targetPosition[i] = data[i]; - targetRotation[i] = data[i + 3]; - } - targetRotation[3] = data[6]; - break; - } - - } - - // Start is called before the first frame update - void Start() - { - StartCoroutine(syncBehavior()); - } - - IEnumerator syncBehavior() - { - while (true) - { - if (owner != null && owner.isLocal) - { - - owner.sendMessage(this, "s", getSyncMessage()); - } - yield return new WaitForSeconds(.1f); - } - } - // Update is called once per frame - void Update() - { - if (owner != null && !owner.isLocal) - { - transform.position = Vector3.Lerp(transform.position, targetPosition, .1f); - transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, .1f); - } - } - -} diff --git a/TestVelGameServer/Packages/VelNetUnity/Editor.meta b/TestVelGameServer/Packages/VelNetUnity/Editor.meta new file mode 100644 index 0000000..e34903b --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 453f243ca8f3d8b4db4a1db0d9f9d300 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime.meta b/TestVelGameServer/Packages/VelNetUnity/Runtime.meta new file mode 100644 index 0000000..bbf4f4e --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 63ae5231117a1484198ba0a8f681612b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkManager.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkManager.cs new file mode 100644 index 0000000..d75611e --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkManager.cs @@ -0,0 +1,522 @@ +using System; +using System.Collections.Generic; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using UnityEngine; +using System.Net; + +namespace VelNetUnity +{ + public class NetworkManager : MonoBehaviour + { + public enum MessageType + { + OTHERS = 0, + ALL = 1, + OTHERS_ORDERED = 2, + ALL_ORDERED = 3 + }; + + public string host; + public int port; + + #region private members + + private TcpClient socketConnection; + private Socket udpSocket; + public bool udpConnected = false; + IPEndPoint RemoteEndPoint; + private Thread clientReceiveThread; + private Thread clientReceiveThreadUDP; + public int userid = -1; + public string room; + int messagesReceived = 0; + + public GameObject playerPrefab; + public Dictionary players = new Dictionary(); + + public Action onJoinedRoom = delegate { }; + public Action onPlayerJoined = delegate { }; + public Action onPlayerLeft = delegate { }; + + public List prefabs = new List(); + public NetworkObject[] sceneObjects; + public List deletedSceneObjects = new List(); + public Dictionary objects = new Dictionary(); //maintains a list of all known objects on the server (ones that have ids) + NetworkPlayer masterPlayer = null; + + #endregion + + // Use this for initialization + public class Message + { + public int type; + public string text; + public int sender; + } + + public List receivedMessages = new List(); + + void Start() + { + ConnectToTcpServer(); + sceneObjects = FindObjectsOfType(); //add all local network objects + } + + + private void addMessage(Message m) + { + lock (receivedMessages) + { + //Debug.Log(messagesReceived++); + receivedMessages.Add(m); + } + } + + private void Update() + { + lock (receivedMessages) + { + //the main thread, which can do Unity stuff + foreach (Message m in receivedMessages) + { + if (m.type == 0) //when you join the server + { + userid = m.sender; + Debug.Log("joined server"); + + //start the udp thread + clientReceiveThreadUDP = new Thread(new ThreadStart(ListenForDataUDP)); + clientReceiveThreadUDP.IsBackground = true; + clientReceiveThreadUDP.Start(); + } + + if (m.type == 2) + { + //if this message is for me, that means I joined a new room... + if (userid == m.sender) + { + foreach (KeyValuePair kvp in players) + { + Destroy(kvp.Value.gameObject); + } + + players.Clear(); //we clear the list, but will recreate as we get messages from people in our room + + if (m.text != "") + { + NetworkPlayer player = Instantiate(playerPrefab).GetComponent(); + + player.isLocal = true; + player.userid = m.sender; + players.Add(userid, player); + player.room = m.text; + player.manager = this; + onJoinedRoom(player); + } + } + else //not for me, a player is joining or leaving + { + NetworkPlayer me = players[userid]; + + if (me.room != m.text) + { + //we got a left message, kill it + //change ownership of all objects to master + + foreach (KeyValuePair kvp in objects) + { + if (kvp.Value.owner == players[m.sender]) //the owner is the player that left + { + if (me.isLocal && me == masterPlayer) //I'm the local master player, so can take ownership immediately + { + me.takeOwnership(kvp.Key); + } + else if (players[m.sender] == masterPlayer) //the master player left, so everyone should set the owner null (we should get a new master shortly) + { + kvp.Value.owner = null; + } + } + } + + Destroy(players[m.sender].gameObject); + players.Remove(m.sender); + } + else + { + //we got a join mesage, create it + NetworkPlayer player = Instantiate(playerPrefab).GetComponent(); + player.isLocal = false; + player.room = m.text; + player.userid = m.sender; + player.manager = this; + players.Add(m.sender, player); + onPlayerJoined(player); + } + } + } + + if (m.type == 3) //generic message + { + players[m.sender]?.handleMessage(m); + } + + if (m.type == 4) //change master player (this should only happen when the first player joins or if the master player leaves) + { + if (masterPlayer == null) + { + masterPlayer = players[m.sender]; + + //no master player yet, add the scene objects + + for (int i = 0; i < sceneObjects.Length; i++) + { + sceneObjects[i].networkId = -1 + "-" + i; + sceneObjects[i].owner = masterPlayer; + sceneObjects[i].isSceneObject = true; //needed for special handling when deleted + objects.Add(sceneObjects[i].networkId, sceneObjects[i]); + } + } + else + { + masterPlayer = players[m.sender]; + } + + masterPlayer.setAsMasterPlayer(); + + //master player should take over any objects that do not have an owner + + foreach (KeyValuePair kvp in objects) + { + if (kvp.Value.owner == null) + { + kvp.Value.owner = masterPlayer; + } + } + } + + messageReceived(m); + } + + receivedMessages.Clear(); + } + } + + private void OnApplicationQuit() + { + socketConnection.Close(); + } + + public Action joinedRoom = delegate { }; + public Action messageReceived = delegate { }; + public Action loggedIn = delegate { }; + public Action roomsReceived = delegate { }; + + public bool connected = false; + + /// + /// Setup socket connection. + /// + private void ConnectToTcpServer() + { + try + { + clientReceiveThread = new Thread(new ThreadStart(ListenForData)); + clientReceiveThread.IsBackground = true; + clientReceiveThread.Start(); + } + catch (Exception e) + { + Debug.Log("On client connect exception " + e); + } + } + + void handleMessage(string s) //this parses messages from the server, and adds them to a queue to be processed on the main thread + { + Message m = new Message(); + string[] sections = s.Split(':'); + if (sections.Length > 0) + { + int type = int.Parse(sections[0]); + + switch (type) + { + case 0: //logged in message + { + if (sections.Length > 1) + { + m.type = type; + m.sender = int.Parse(sections[1]); + m.text = ""; + addMessage(m); + } + + break; + } + case 1: //room info message + { + break; + } + case 2: //joined room message + { + if (sections.Length > 2) + { + m.type = 2; + int user_id = int.Parse(sections[1]); + m.sender = user_id; + string new_room = sections[2]; + m.text = new_room; + + addMessage(m); + } + + break; + } + case 3: //text message + { + if (sections.Length > 2) + { + m.type = 3; + m.sender = int.Parse(sections[1]); + m.text = sections[2]; + addMessage(m); + } + + break; + } + case 4: //change master client + { + if (sections.Length > 1) + { + m.type = 4; + m.sender = int.Parse(sections[1]); + addMessage(m); + } + + break; + } + } + } + } + + /// + /// Runs in background clientReceiveThread; Listens for incomming data. + /// + private void ListenForData() + { + connected = true; + try + { + socketConnection = new TcpClient(host, port); + socketConnection.NoDelay = true; + Byte[] bytes = new Byte[1024]; + string partialMessage = ""; + while (true) + { + // Get a stream object for reading + using (NetworkStream stream = socketConnection.GetStream()) + { + int length; + // Read incomming stream into byte arrary. + while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) + { + var incommingData = new byte[length]; + Array.Copy(bytes, 0, incommingData, 0, length); + // Convert byte array to string message. + string serverMessage = Encoding.ASCII.GetString(incommingData); + string[] sections = serverMessage.Split('\n'); + if (sections.Length > 1) + { + lock (receivedMessages) + { + for (int i = 0; i < sections.Length - 1; i++) + { + if (i == 0) + { + handleMessage(partialMessage + sections[0]); + partialMessage = ""; + } + else + { + handleMessage(sections[i]); + } + } + } + } + + partialMessage = partialMessage + sections[sections.Length - 1]; + } + } + } + } + + + catch (Exception socketException) + { + Debug.Log("Socket exception: " + socketException); + } + + connected = false; + } + + private void ListenForDataUDP() + { + //I don't yet have a UDP connection + try + { + var addresses = Dns.GetHostAddresses(host); + Debug.Assert(addresses.Length > 0); + RemoteEndPoint = new IPEndPoint(addresses[0], port); + + + udpSocket = new Socket(AddressFamily.InterNetwork, + SocketType.Dgram, ProtocolType.Udp); + + + udpConnected = false; + byte[] buffer = new byte[1024]; + while (true) + { + string welcome = userid + ":0:Hello"; + byte[] data = Encoding.ASCII.GetBytes(welcome); + udpSocket.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint); + + if (udpSocket.Available == 0) + { + Thread.Sleep(100); + Debug.Log("Waiting for UDP response"); + } + else + { + break; + } + } + + udpConnected = true; + while (true) + { + int numReceived = udpSocket.Receive(buffer); + + string message = Encoding.UTF8.GetString(buffer, 0, numReceived); + + string[] sections = message.Split(':'); + if (sections[0] == "0") + { + Debug.Log("UDP connected"); + } + + if (sections[0] == "3") + { + handleMessage(message); + } + } + } + catch (Exception socketException) + { + Debug.Log("Socket exception: " + socketException); + } + } + + private void SendUdpMessage(string message) + { + if (udpSocket == null || !udpConnected) + { + return; + } + + byte[] data = Encoding.UTF8.GetBytes(message); + //Debug.Log("Attempting to send: " + message); + udpSocket.SendTo(data, data.Length, SocketFlags.None, RemoteEndPoint); + } + + /// + /// Send message to server using socket connection. + /// + private void SendNetworkMessage(string clientMessage) + { + if (socketConnection == null) + { + return; + } + + try + { + // Get a stream object for writing. + NetworkStream stream = socketConnection.GetStream(); + if (stream.CanWrite) + { + // Convert string message to byte array. + clientMessage = clientMessage + "\n"; //append a new line to delineate the message + byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(clientMessage); + // Write byte array to socketConnection stream. + stream.Write(clientMessageAsByteArray, 0, clientMessageAsByteArray.Length); + } + } + catch (SocketException socketException) + { + Debug.Log("Socket exception: " + socketException); + } + } + + public void login(string username, string password) + { + SendNetworkMessage("0:" + username + ":" + password); + } + + public void join(string roomname) + { + SendNetworkMessage("2:" + roomname); + } + + public void leave() + { + SendNetworkMessage("2:-1"); + } + + public void sendTo(MessageType type, string message, bool reliable = true) + { + if (reliable) + { + SendNetworkMessage("3:" + (int)type + ":" + message); + } + else + { + SendUdpMessage(userid + ":3:" + (int)type + ":" + message); + } + } + + public void sendToGroup(string group, string message, bool reliable = true) + { + if (reliable) + { + SendNetworkMessage("4:" + group + ":" + message); + } + else + { + SendUdpMessage(userid + ":4:" + group + ":" + message); + } + } + + //changes the designated group that sendto(4) will go to + public void setupMessageGroup(string groupname, int[] userids) + { + SendNetworkMessage("5:" + groupname + ":" + String.Join(":", userids)); + } + + public void deleteNetworkObject(string networkId) + { + if (objects.ContainsKey(networkId)) + { + NetworkObject obj = objects[networkId]; + if (obj.isSceneObject) + { + deletedSceneObjects.Add(networkId); + } + + Destroy(obj.gameObject); + objects.Remove(networkId); + } + } + } +} \ No newline at end of file diff --git a/TestVelGameServer/Assets/VelGameServer/NetworkManager.cs.meta b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkManager.cs.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/NetworkManager.cs.meta rename to TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkManager.cs.meta diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs new file mode 100644 index 0000000..3a43a9f --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs @@ -0,0 +1,16 @@ +using UnityEngine; + +namespace VelNetUnity +{ + /// + /// This is a base class for all objects that a player can instantiated/owned + /// + public abstract class NetworkObject : MonoBehaviour + { + public NetworkPlayer owner; + public string networkId; //this is forged from the combination of the creator's id (-1 in the case of a scene object) and an object id, so it's always unique for a room + public string prefabName; //this may be empty if it's not a prefab (scene object) + public bool isSceneObject = false; + public abstract void handleMessage(string identifier, byte[] message); + } +} \ No newline at end of file diff --git a/TestVelGameServer/Assets/VelGameServer/NetworkObject.cs.meta b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/NetworkObject.cs.meta rename to TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkObject.cs.meta diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkPlayer.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkPlayer.cs new file mode 100644 index 0000000..13d6b61 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkPlayer.cs @@ -0,0 +1,219 @@ +using System.Collections.Generic; +using UnityEngine; +using System; + + +namespace VelNetUnity +{ + [RequireComponent(typeof(NetworkObject))] + public class NetworkPlayer : MonoBehaviour + { + public NetworkObject myObject; + public int userid; + public string username; + + public string room; + public NetworkManager manager; + + public bool isLocal = false; + + public int lastObjectId = 0; //for instantiation + + + private bool isMaster = false; + + private void Start() + { + myObject.owner = this; + manager = FindObjectOfType(); + manager.onPlayerJoined += handlePlayerJoined; + } + + public void handlePlayerJoined(NetworkPlayer player) + { + //if this is the local player, go through the objects that I own, and send instantiation messages for the ones that have prefab names + if (isLocal) + { + foreach (KeyValuePair kvp in manager.objects) + { + if (kvp.Value.owner == this && kvp.Value.prefabName != "") + { + manager.sendTo(NetworkManager.MessageType.OTHERS, "7," + kvp.Value.networkId + "," + kvp.Value.prefabName); + } + } + + if (isMaster) + { + //send a list of scene object ids when someone joins + sendSceneUpdate(); + } + } + } + + + public void handleMessage(NetworkManager.Message m) + { + //these are generally things that come from the "owner" and should be enacted locally, where appropriate + //we need to parse the message + + //types of messages + string[] messages = m.text.Split(';'); //messages are split by ; + for (int i = 0; i < messages.Length; i++) + { + //individual message parameters separated by comma + string[] sections = messages[i].Split(','); + + switch (sections[0]) + { + case "1": //update my object's data + { + string identifier = sections[1]; + byte[] message = Convert.FromBase64String(sections[2]); + myObject.handleMessage(identifier, message); + break; + } + case "5": //sync update for an object I may own + { + string objectKey = sections[1]; + string identifier = sections[2]; + string syncMessage = sections[3]; + byte[] messageBytes = Convert.FromBase64String(syncMessage); + if (manager.objects.ContainsKey(objectKey)) + { + if (manager.objects[objectKey].owner == this) + { + manager.objects[objectKey].handleMessage(identifier, messageBytes); + } + } + + break; + } + case "6": //I'm trying to take ownership of an object + { + string networkId = sections[1]; + + if (manager.objects.ContainsKey(networkId)) + { + manager.objects[networkId].owner = this; + } + + break; + } + case "7": //I'm trying to instantiate an object + { + string networkId = sections[1]; + string prefabName = sections[2]; + if (manager.objects.ContainsKey(networkId)) + { + break; //we already have this one, ignore + } + + NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName); + if (temp != null) + { + NetworkObject instance = Instantiate(temp); + instance.networkId = networkId; + instance.prefabName = prefabName; + instance.owner = this; + manager.objects.Add(instance.networkId, instance); + } + + break; + } + case "8": //I'm trying to destroy a gameobject I own + { + string networkId = sections[1]; + + manager.deleteNetworkObject(networkId); + break; + } + case "9": //deleted scene objects + { + for (int k = 1; k < sections.Length; k++) + { + manager.deleteNetworkObject(sections[k]); + } + + break; + } + } + } + } + + public void setAsMasterPlayer() + { + isMaster = true; + //if I'm master, I'm now responsible for updating all scene objects + //FindObjectsOfType(); + } + + public void sendGroupMessage(NetworkObject obj, string group, string identifier, byte[] data, bool reliable = true) + { + if (obj == myObject) + { + manager.sendToGroup(group, "1," + identifier + "," + Convert.ToBase64String(data), reliable); + } + else + { + manager.sendToGroup(group, "5," + obj.networkId + "," + identifier + "," + Convert.ToBase64String(data), reliable); + } + } + + public void sendMessage(NetworkObject obj, string identifier, byte[] data, bool reliable = true) + { + if (obj == myObject) + { + manager.sendTo(NetworkManager.MessageType.OTHERS, "1," + identifier + "," + Convert.ToBase64String(data), reliable); + } + else + { + manager.sendTo(NetworkManager.MessageType.OTHERS, "5," + obj.networkId + "," + identifier + "," + Convert.ToBase64String(data), reliable); + } + } + + public NetworkObject networkInstantiate(string prefabName) + { + if (!isLocal) + { + return null; //must be the local player to call instantiate + } + + string networkId = userid + "-" + lastObjectId++; + + + NetworkObject temp = manager.prefabs.Find((prefab) => prefab.name == prefabName); + if (temp != null) + { + NetworkObject instance = Instantiate(temp); + instance.networkId = networkId; + instance.prefabName = prefabName; + instance.owner = this; + manager.objects.Add(instance.networkId, instance); + + manager.sendTo(NetworkManager.MessageType.OTHERS, "7," + networkId + "," + prefabName); //only sent to others, as I already instantiated this. Nice that it happens immediately. + return instance; + } + + return null; + } + + public void networkDestroy(string networkId) + { + if (!manager.objects.ContainsKey(networkId) || manager.objects[networkId].owner != this || !isLocal) return; //must be the local owner of the object to destroy it + manager.sendTo(NetworkManager.MessageType.ALL_ORDERED, "8," + networkId); //send to all, which will make me delete as well + } + + public void takeOwnership(string networkId) + { + if (!manager.objects.ContainsKey(networkId) || !isLocal) return; //must exist and be the the local player + + manager.objects[networkId].owner = this; //immediately successful + manager.sendTo(NetworkManager.MessageType.ALL_ORDERED, "6," + networkId); //must be ordered, so that ownership transfers are not confused. Also sent to all players, so that multiple simultaneous requests will result in the same outcome. + } + + public void sendSceneUpdate() + { + manager.sendTo(NetworkManager.MessageType.OTHERS, "9," + string.Join(",", manager.deletedSceneObjects)); + } + } +} \ No newline at end of file diff --git a/TestVelGameServer/Assets/VelGameServer/NetworkPlayer.cs.meta b/TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkPlayer.cs.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/NetworkPlayer.cs.meta rename to TestVelGameServer/Packages/VelNetUnity/Runtime/NetworkPlayer.cs.meta diff --git a/TestVelGameServer/Assets/VelGameServer/Util.meta b/TestVelGameServer/Packages/VelNetUnity/Runtime/Util.meta similarity index 77% rename from TestVelGameServer/Assets/VelGameServer/Util.meta rename to TestVelGameServer/Packages/VelNetUnity/Runtime/Util.meta index 5835bd6..4ece4ae 100644 --- a/TestVelGameServer/Assets/VelGameServer/Util.meta +++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/Util.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: feb473f59814842848dd4183ddeb6d9e +guid: cd6bc3db2c19417498a737fbb79e8c7d folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/TestVelGameServer/Packages/VelNetUnity/Runtime/Util/SyncTransform.cs b/TestVelGameServer/Packages/VelNetUnity/Runtime/Util/SyncTransform.cs new file mode 100644 index 0000000..3557b80 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Runtime/Util/SyncTransform.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections; +using UnityEngine; + + +namespace VelNetUnity +{ + /// + /// A simple class that will sync the position and rotation of a network object + /// + public class SyncTransform : NetworkObject + { + public Vector3 targetPosition; + public Quaternion targetRotation; + + + public byte[] getSyncMessage() + { + float[] data = new float[7]; + for (int i = 0; i < 3; i++) + { + data[i] = transform.position[i]; + data[i + 3] = transform.rotation[i]; + } + + data[6] = transform.rotation[3]; + + byte[] toReturn = new byte[sizeof(float) * data.Length]; + Buffer.BlockCopy(data, 0, toReturn, 0, toReturn.Length); + return toReturn; + } + + public override void handleMessage(string identifier, byte[] message) + { + switch (identifier) + { + case "s": + float[] data = new float[7]; + Buffer.BlockCopy(message, 0, data, 0, message.Length); + for (int i = 0; i < 3; i++) + { + targetPosition[i] = data[i]; + targetRotation[i] = data[i + 3]; + } + + targetRotation[3] = data[6]; + break; + } + } + + // Start is called before the first frame update + void Start() + { + StartCoroutine(syncBehavior()); + } + + IEnumerator syncBehavior() + { + while (true) + { + if (owner != null && owner.isLocal) + { + owner.sendMessage(this, "s", getSyncMessage()); + } + + yield return new WaitForSeconds(.1f); + } + } + + // Update is called once per frame + private void Update() + { + if (owner != null && !owner.isLocal) + { + transform.position = Vector3.Lerp(transform.position, targetPosition, .1f); + transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, .1f); + } + } + } +} \ No newline at end of file diff --git a/TestVelGameServer/Assets/VelGameServer/Util/SyncTransform.cs.meta b/TestVelGameServer/Packages/VelNetUnity/Runtime/Util/SyncTransform.cs.meta similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Util/SyncTransform.cs.meta rename to TestVelGameServer/Packages/VelNetUnity/Runtime/Util/SyncTransform.cs.meta diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelAudioMixer.mixer b/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelAudioMixer.mixer new file mode 100644 index 0000000..b2ae0ea --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelAudioMixer.mixer @@ -0,0 +1,83 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!244 &-1719467165466355418 +AudioMixerEffectController: + m_ObjectHideFlags: 3 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_EffectID: 6362d3ceb713f4c3fa42448a3e29217e + m_EffectName: Dissonance Echo Cancellation + m_MixLevel: a240a2d1f057e4cf9bbc59f6cfbec367 + m_Parameters: [] + m_SendTarget: {fileID: 0} + m_EnableWetMix: 0 + m_Bypass: 0 +--- !u!241 &24100000 +AudioMixerController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: VelAudioMixer + m_OutputGroup: {fileID: 0} + m_MasterGroup: {fileID: 24300002} + m_Snapshots: + - {fileID: 24500006} + m_StartSnapshot: {fileID: 24500006} + m_SuspendThreshold: -80 + m_EnableSuspend: 1 + m_UpdateMode: 1 + m_ExposedParameters: [] + m_AudioMixerGroupViews: + - guids: + - b8e40716c8c1442ab9ef14e149b2423c + name: View + m_CurrentViewIndex: 0 + m_TargetSnapshot: {fileID: 24500006} +--- !u!243 &24300002 +AudioMixerGroupController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Master + m_AudioMixer: {fileID: 24100000} + m_GroupID: b8e40716c8c1442ab9ef14e149b2423c + m_Children: [] + m_Volume: 3d9590ea0314643bd94e1616b88508ef + m_Pitch: 31f1ddadf3a5d47caab0e64b81ced2ae + m_Send: 00000000000000000000000000000000 + m_Effects: + - {fileID: 24400004} + - {fileID: -1719467165466355418} + m_UserColorIndex: 0 + m_Mute: 0 + m_Solo: 0 + m_BypassEffects: 0 +--- !u!244 &24400004 +AudioMixerEffectController: + m_ObjectHideFlags: 3 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_EffectID: f79719d1f394d4b4783ede937d403602 + m_EffectName: Attenuation + m_MixLevel: 8d97d9fd1e8d446eb9244b5dead78e90 + m_Parameters: [] + m_SendTarget: {fileID: 0} + m_EnableWetMix: 0 + m_Bypass: 0 +--- !u!245 &24500006 +AudioMixerSnapshotController: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Snapshot + m_AudioMixer: {fileID: 24100000} + m_SnapshotID: 86ea5b9fedb76448594a5ab2119e34a1 + m_FloatValues: {} + m_TransitionOverrides: {} diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelAudioMixer.mixer.meta b/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelAudioMixer.mixer.meta new file mode 100644 index 0000000..4db7f93 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelAudioMixer.mixer.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fa1da19d935e241119cdd522ceae772c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 24100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Assets/VelGameServer/DissonanceIntegration/VelCommsNetwork.cs b/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelCommsNetwork.cs similarity index 99% rename from TestVelGameServer/Assets/VelGameServer/DissonanceIntegration/VelCommsNetwork.cs rename to TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelCommsNetwork.cs index 52613c8..b6d7d8d 100644 --- a/TestVelGameServer/Assets/VelGameServer/DissonanceIntegration/VelCommsNetwork.cs +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelCommsNetwork.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using Dissonance; diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelCommsNetwork.cs.meta b/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelCommsNetwork.cs.meta new file mode 100644 index 0000000..f086eda --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/DissonanceIntegration/VelCommsNetwork.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5d2009d8e264649749c0315d48765749 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Assets/VelGameServer/Example/NetworkGUI.cs b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/NetworkGUI.cs similarity index 100% rename from TestVelGameServer/Assets/VelGameServer/Example/NetworkGUI.cs rename to TestVelGameServer/Packages/VelNetUnity/Samples~/Example/NetworkGUI.cs diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/NetworkGUI.cs.meta b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/NetworkGUI.cs.meta new file mode 100644 index 0000000..c4289bb --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/NetworkGUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7a7db5bc792cd471dbd8039664359eee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Assets/VelGameServer/Example/PlayerController.cs b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerController.cs similarity index 99% rename from TestVelGameServer/Assets/VelGameServer/Example/PlayerController.cs rename to TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerController.cs index 3646aa6..0cfce96 100644 --- a/TestVelGameServer/Assets/VelGameServer/Example/PlayerController.cs +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerController.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using UnityEngine; diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerController.cs.meta b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerController.cs.meta new file mode 100644 index 0000000..1c49a76 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 89e3af759df774692a566a166b4bf69b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerPrefab.prefab b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerPrefab.prefab new file mode 100644 index 0000000..1c3683f --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerPrefab.prefab @@ -0,0 +1,136 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &6139051692386484099 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3076416102083120807} + - component: {fileID: 8527011532923434593} + - component: {fileID: 6854617867369839} + - component: {fileID: 5845716565458182149} + - component: {fileID: 5713671764962751473} + - component: {fileID: -4404668399269848200} + m_Layer: 0 + m_Name: PlayerPrefab + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &3076416102083120807 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6139051692386484099} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &8527011532923434593 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6139051692386484099} + m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &6854617867369839 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6139051692386484099} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!65 &5845716565458182149 +BoxCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6139051692386484099} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Size: {x: 1, y: 1, z: 1} + m_Center: {x: 0, y: 0, z: 0} +--- !u!114 &5713671764962751473 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6139051692386484099} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d8d3b6de660834e3e898725928251405, type: 3} + m_Name: + m_EditorClassIdentifier: + myObject: {fileID: -4404668399269848200} + userid: 0 + username: + room: + manager: {fileID: 0} + isLocal: 0 + lastObjectId: 0 + commsNetwork: {fileID: 0} + dissonanceID: +--- !u!114 &-4404668399269848200 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6139051692386484099} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 89e3af759df774692a566a166b4bf69b, type: 3} + m_Name: + m_EditorClassIdentifier: + owner: {fileID: 5713671764962751473} + networkId: + targetPosition: {x: 0, y: 0, z: 0} + targetRotation: {x: 0, y: 0, z: 0, w: 0} diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerPrefab.prefab.meta b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerPrefab.prefab.meta new file mode 100644 index 0000000..7899882 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/PlayerPrefab.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d4158ab9c4a204cdbba28d3273fc1fb3 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/TestNetworkedGameObject.prefab b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/TestNetworkedGameObject.prefab new file mode 100644 index 0000000..bac19d3 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/TestNetworkedGameObject.prefab @@ -0,0 +1,145 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &8565720275311462453 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8565720275311462455} + - component: {fileID: 8565720275311462452} + m_Layer: 0 + m_Name: TestNetworkedGameObject + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8565720275311462455 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8565720275311462453} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 8565720276181857624} + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &8565720275311462452 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8565720275311462453} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3f1f9b0bbd93a484a987c51f1107ebe5, type: 3} + m_Name: + m_EditorClassIdentifier: + owner: {fileID: 0} + networkId: + targetPosition: {x: 0, y: 0, z: 0} + targetRotation: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &8565720276181857625 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8565720276181857624} + - component: {fileID: 8565720276181857605} + - component: {fileID: 8565720276181857626} + - component: {fileID: 8565720276181857627} + m_Layer: 0 + m_Name: Sphere + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8565720276181857624 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8565720276181857625} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 8565720275311462455} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!33 &8565720276181857605 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8565720276181857625} + m_Mesh: {fileID: 10207, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &8565720276181857626 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8565720276181857625} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!135 &8565720276181857627 +SphereCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8565720276181857625} + m_Material: {fileID: 0} + m_IsTrigger: 0 + m_Enabled: 1 + serializedVersion: 2 + m_Radius: 0.5 + m_Center: {x: 0, y: 0, z: 0} diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/TestNetworkedGameObject.prefab.meta b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/TestNetworkedGameObject.prefab.meta new file mode 100644 index 0000000..0743d13 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/TestNetworkedGameObject.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6e4a023f70e01405e8b249a4488fe319 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/test.unity b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/test.unity new file mode 100644 index 0000000..7e44ef7 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/test.unity @@ -0,0 +1,3431 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0.44657874, g: 0.49641275, b: 0.5748172, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 512 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 256 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 1 + m_PVRDenoiserTypeDirect: 1 + m_PVRDenoiserTypeIndirect: 1 + m_PVRDenoiserTypeAO: 1 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 1 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &2034436 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2034439} + - component: {fileID: 2034438} + - component: {fileID: 2034437} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &2034437 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2034436} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 2 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: User Name +--- !u!222 &2034438 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2034436} + m_CullTransparentMesh: 1 +--- !u!224 &2034439 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2034436} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 626742070} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &117638563 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 117638565} + - component: {fileID: 117638567} + - component: {fileID: 117638566} + - component: {fileID: 117638564} + m_Layer: 5 + m_Name: Dropdown + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &117638564 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117638563} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0d0b652f32a2cc243917e4028fa0f046, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 117638566} + m_Template: {fileID: 927188573} + m_CaptionText: {fileID: 138032021} + m_CaptionImage: {fileID: 0} + m_ItemText: {fileID: 720503450} + m_ItemImage: {fileID: 0} + m_Value: 0 + m_Options: + m_Options: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 244561621} + m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp + m_MethodName: handleMicrophoneSelection + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 + m_AlphaFadeSpeed: 0.15 +--- !u!224 &117638565 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117638563} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 138032023} + - {fileID: 1557879931} + - {fileID: 927188573} + m_Father: {fileID: 244561620} + m_RootOrder: 7 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 98, y: 138} + m_SizeDelta: {x: 160, y: 38.7538} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &117638566 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117638563} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &117638567 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 117638563} + m_CullTransparentMesh: 1 +--- !u!1 &138032020 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 138032023} + - component: {fileID: 138032022} + - component: {fileID: 138032021} + m_Layer: 5 + m_Name: Label + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &138032021 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138032020} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: +--- !u!222 &138032022 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138032020} + m_CullTransparentMesh: 1 +--- !u!224 &138032023 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 138032020} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 117638565} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: -7.5, y: -0.5} + m_SizeDelta: {x: -35, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &162005663 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 162005664} + - component: {fileID: 162005666} + - component: {fileID: 162005665} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &162005664 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 162005663} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 711524767} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &162005665 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 162005663} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 2 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Room Name +--- !u!222 &162005666 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 162005663} + m_CullTransparentMesh: 1 +--- !u!1 &244561616 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 244561620} + - component: {fileID: 244561619} + - component: {fileID: 244561618} + - component: {fileID: 244561617} + - component: {fileID: 244561621} + m_Layer: 5 + m_Name: NetworkGUI + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &244561617 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 244561616} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 +--- !u!114 &244561618 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 244561616} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 0 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 800, y: 600} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 + m_PresetInfoIsWorld: 0 +--- !u!223 &244561619 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 244561616} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 0 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 0 + m_TargetDisplay: 0 +--- !u!224 &244561620 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 244561616} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 0, y: 0, z: 0} + m_Children: + - {fileID: 1278634767} + - {fileID: 711524767} + - {fileID: 1894247853} + - {fileID: 626742070} + - {fileID: 1760805525} + - {fileID: 945446556} + - {fileID: 1843597586} + - {fileID: 117638565} + m_Father: {fileID: 0} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 0} +--- !u!114 &244561621 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 244561616} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 7a7db5bc792cd471dbd8039664359eee, type: 3} + m_Name: + m_EditorClassIdentifier: + networkManager: {fileID: 1099803616} + userInput: {fileID: 626742069} + sendInput: {fileID: 945446555} + roomInput: {fileID: 711524768} + messages: {fileID: 1894247854} + messageBuffer: [] + microphones: {fileID: 117638564} +--- !u!1 &440509381 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 440509384} + - component: {fileID: 440509383} + - component: {fileID: 440509382} + m_Layer: 0 + m_Name: EventSystem + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &440509382 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 440509381} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalAxis: Horizontal + m_VerticalAxis: Vertical + m_SubmitButton: Submit + m_CancelButton: Cancel + m_InputActionsPerSecond: 10 + m_RepeatDelay: 0.5 + m_ForceModuleActive: 0 +--- !u!114 &440509383 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 440509381} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_FirstSelected: {fileID: 0} + m_sendNavigationEvents: 1 + m_DragThreshold: 10 +--- !u!4 &440509384 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 440509381} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &615558651 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 615558652} + - component: {fileID: 615558654} + - component: {fileID: 615558653} + m_Layer: 5 + m_Name: Item Checkmark + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &615558652 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 615558651} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1047954372} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 0, y: 0.5} + m_AnchoredPosition: {x: 10, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &615558653 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 615558651} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10901, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &615558654 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 615558651} + m_CullTransparentMesh: 1 +--- !u!1 &626742068 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 626742070} + - component: {fileID: 626742072} + - component: {fileID: 626742071} + - component: {fileID: 626742069} + m_Layer: 5 + m_Name: UserInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &626742069 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 626742068} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 626742071} + m_TextComponent: {fileID: 1560686266} + m_Placeholder: {fileID: 2034437} + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 0 + m_HideMobileInput: 0 + m_CharacterValidation: 0 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_ShouldActivateOnSelect: 1 +--- !u!224 &626742070 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 626742068} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2034439} + - {fileID: 1560686264} + m_Father: {fileID: 244561620} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 242.09998, y: 51} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &626742071 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 626742068} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &626742072 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 626742068} + m_CullTransparentMesh: 1 +--- !u!1 &652307109 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 652307111} + - component: {fileID: 652307110} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &652307110 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 652307109} + m_Enabled: 1 + serializedVersion: 10 + m_Type: 1 + m_Shape: 0 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_InnerSpotAngle: 21.80208 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_CullingMatrixOverride: + e00: 1 + e01: 0 + e02: 0 + e03: 0 + e10: 0 + e11: 1 + e12: 0 + e13: 0 + e20: 0 + e21: 0 + e22: 1 + e23: 0 + e30: 0 + e31: 0 + e32: 0 + e33: 1 + m_UseCullingMatrixOverride: 0 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingLayerMask: 1 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} + m_UseBoundingSphereOverride: 0 + m_UseViewFrustumForShadowCasterCull: 1 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &652307111 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 652307109} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &711524766 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 711524767} + - component: {fileID: 711524770} + - component: {fileID: 711524769} + - component: {fileID: 711524768} + m_Layer: 5 + m_Name: RoomInput + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &711524767 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 711524766} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 162005664} + - {fileID: 1484033256} + m_Father: {fileID: 244561620} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 240.09998, y: 15.5} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &711524768 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 711524766} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 711524769} + m_TextComponent: {fileID: 1484033257} + m_Placeholder: {fileID: 162005665} + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 0 + m_HideMobileInput: 0 + m_CharacterValidation: 0 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_ShouldActivateOnSelect: 1 +--- !u!114 &711524769 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 711524766} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &711524770 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 711524766} + m_CullTransparentMesh: 1 +--- !u!1 &720503449 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 720503452} + - component: {fileID: 720503451} + - component: {fileID: 720503450} + m_Layer: 5 + m_Name: Item Label + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &720503450 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 720503449} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 3 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Option A +--- !u!222 &720503451 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 720503449} + m_CullTransparentMesh: 1 +--- !u!224 &720503452 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 720503449} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1047954372} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 5, y: -0.5} + m_SizeDelta: {x: -30, y: -3} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &903768653 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 903768657} + - component: {fileID: 903768656} + - component: {fileID: 903768655} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &903768655 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 903768653} + m_Enabled: 1 +--- !u!20 &903768656 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 903768653} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &903768657 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 903768653} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &912887455 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 912887456} + - component: {fileID: 912887459} + - component: {fileID: 912887458} + - component: {fileID: 912887457} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &912887456 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 912887455} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1055818112} + m_Father: {fileID: 927188573} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -18, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &912887457 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 912887455} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &912887458 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 912887455} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10917, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &912887459 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 912887455} + m_CullTransparentMesh: 1 +--- !u!1 &927188572 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 927188573} + - component: {fileID: 927188576} + - component: {fileID: 927188575} + - component: {fileID: 927188574} + m_Layer: 5 + m_Name: Template + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &927188573 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 927188572} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 912887456} + - {fileID: 1154194182} + m_Father: {fileID: 117638565} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0} + m_AnchoredPosition: {x: 0, y: 2} + m_SizeDelta: {x: 0, y: 150} + m_Pivot: {x: 0.5, y: 1} +--- !u!114 &927188574 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 927188572} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 1055818112} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 2 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 1 + m_Viewport: {fileID: 912887456} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 1154194183} + m_HorizontalScrollbarVisibility: 0 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: 0 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &927188575 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 927188572} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &927188576 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 927188572} + m_CullTransparentMesh: 1 +--- !u!1 &945446554 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 945446556} + - component: {fileID: 945446558} + - component: {fileID: 945446557} + - component: {fileID: 945446555} + m_Layer: 5 + m_Name: Message + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &945446555 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945446554} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 945446557} + m_TextComponent: {fileID: 1235343403} + m_Placeholder: {fileID: 1954037270} + m_ContentType: 0 + m_InputType: 0 + m_AsteriskChar: 42 + m_KeyboardType: 0 + m_LineType: 0 + m_HideMobileInput: 0 + m_CharacterValidation: 0 + m_CharacterLimit: 0 + m_OnEndEdit: + m_PersistentCalls: + m_Calls: [] + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] + m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_CustomCaretColor: 0 + m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} + m_Text: + m_CaretBlinkRate: 0.85 + m_CaretWidth: 1 + m_ReadOnly: 0 + m_ShouldActivateOnSelect: 1 +--- !u!224 &945446556 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945446554} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1954037272} + - {fileID: 1235343401} + m_Father: {fileID: 244561620} + m_RootOrder: 5 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 112.91498, y: 88} + m_SizeDelta: {x: 215.83, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &945446557 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945446554} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &945446558 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 945446554} + m_CullTransparentMesh: 1 +--- !u!1 &1047954371 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1047954372} + - component: {fileID: 1047954373} + m_Layer: 5 + m_Name: Item + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1047954372 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1047954371} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2144436500} + - {fileID: 615558652} + - {fileID: 720503452} + m_Father: {fileID: 1055818112} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1047954373 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1047954371} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 9085046f02f69544eb97fd06b6048fe2, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2144436501} + toggleTransition: 1 + graphic: {fileID: 615558653} + m_Group: {fileID: 0} + onValueChanged: + m_PersistentCalls: + m_Calls: [] + m_IsOn: 1 +--- !u!1 &1055818111 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1055818112} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1055818112 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1055818111} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1047954372} + m_Father: {fileID: 912887456} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 28} + m_Pivot: {x: 0.5, y: 1} +--- !u!1 &1099803612 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1099803615} + - component: {fileID: 1099803616} + m_Layer: 0 + m_Name: NetworkManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1099803615 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1099803612} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1099803616 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1099803612} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 03a4d4e1a7fd74c7ab2eccca4ce168db, type: 3} + m_Name: + m_EditorClassIdentifier: + host: neko.ugavel.com + port: 3290 + udpConnected: 0 + userid: -1 + room: + playerPrefab: {fileID: 6139051692386484099, guid: d4158ab9c4a204cdbba28d3273fc1fb3, type: 3} + prefabs: + - {fileID: 8565720275311462452, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + sceneObjects: [] + deletedSceneObjects: [] + connected: 0 +--- !u!1 &1154194181 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1154194182} + - component: {fileID: 1154194185} + - component: {fileID: 1154194184} + - component: {fileID: 1154194183} + m_Layer: 5 + m_Name: Scrollbar + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1154194182 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1154194181} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1679565284} + m_Father: {fileID: 927188573} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &1154194183 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1154194181} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 2033163678} + m_HandleRect: {fileID: 2033163677} + m_Direction: 2 + m_Value: 0 + m_Size: 0.2 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &1154194184 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1154194181} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1154194185 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1154194181} + m_CullTransparentMesh: 1 +--- !u!1 &1235343400 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1235343401} + - component: {fileID: 1235343402} + - component: {fileID: 1235343403} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1235343401 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1235343400} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 945446556} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1235343402 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1235343400} + m_CullTransparentMesh: 1 +--- !u!114 &1235343403 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1235343400} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 1 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: +--- !u!1 &1278634766 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1278634767} + - component: {fileID: 1278634770} + - component: {fileID: 1278634769} + - component: {fileID: 1278634768} + m_Layer: 5 + m_Name: JoinRoom + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1278634767 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1278634766} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1295274441} + m_Father: {fileID: 244561620} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 80, y: 15.5} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1278634768 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1278634766} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1278634769} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 244561621} + m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp + m_MethodName: handleJoin + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1278634769 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1278634766} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1278634770 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1278634766} + m_CullTransparentMesh: 1 +--- !u!1 &1295274440 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1295274441} + - component: {fileID: 1295274443} + - component: {fileID: 1295274442} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1295274441 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1295274440} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1278634767} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1295274442 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1295274440} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Join Room +--- !u!222 &1295274443 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1295274440} + m_CullTransparentMesh: 1 +--- !u!1 &1434745018 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1434745020} + - component: {fileID: 1434745021} + - component: {fileID: 1434745019} + - component: {fileID: 1434745022} + - component: {fileID: 1434745023} + m_Layer: 0 + m_Name: Dissonance + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1434745019 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1434745018} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5d2009d8e264649749c0315d48765749, type: 3} + m_Name: + m_EditorClassIdentifier: + dissonanceId: + comms: {fileID: 1434745021} + manager: {fileID: 1099803616} +--- !u!4 &1434745020 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1434745018} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 818.5, y: 223, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1434745021 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1434745018} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 8cb4dc319de88dc4cb76c47aafb46b1c, type: 3} + m_Name: + m_EditorClassIdentifier: + _lastPrefabError: + _isMuted: 0 + _isDeafened: 0 + _oneMinusBaseRemoteVoiceVolume: 0 + _playbackPrefab: {fileID: 0} + _playbackPrefab2: {fileID: 1041743830464418, guid: 1d5da08daf134aa41a83590aea0e4caa, type: 3} + _micName: + _playerPriority: 0 + _tokens: + _tokens: [] +--- !u!114 &1434745022 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1434745018} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6a066ddbf125f9546bcadc947418566b, type: 3} + m_Name: + m_EditorClassIdentifier: + _tokens: + _tokens: [] + _channelTypeExpanded: 1 + _metadataExpanded: 1 + _activationModeExpanded: 1 + _tokensExpanded: 1 + _ampExpanded: 0 + _activationFaderSettings: + _volume: 1 + _fadeInTicks: 0 + _fadeOutTicks: 1500000 + _triggerFaderSettings: + _volume: 1 + _fadeInTicks: 7500000 + _fadeOutTicks: 11500000 + _broadcastPosition: 1 + _channelType: 0 + _inputName: + _mode: 1 + _muted: 0 + _playerId: + _useTrigger: 0 + _roomName: Global + _priority: 0 +--- !u!114 &1434745023 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1434745018} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3737438748cf23f448d18cd2c6192e95, type: 3} + m_Name: + m_EditorClassIdentifier: + _tokens: + _tokens: [] + _roomName: Global + _useTrigger: 0 +--- !u!1 &1484033255 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1484033256} + - component: {fileID: 1484033258} + - component: {fileID: 1484033257} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1484033256 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1484033255} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 711524767} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1484033257 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1484033255} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 1 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: +--- !u!222 &1484033258 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1484033255} + m_CullTransparentMesh: 1 +--- !u!1 &1557879930 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1557879931} + - component: {fileID: 1557879933} + - component: {fileID: 1557879932} + m_Layer: 5 + m_Name: Arrow + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1557879931 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557879930} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 117638565} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0.5} + m_AnchorMax: {x: 1, y: 0.5} + m_AnchoredPosition: {x: -15, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1557879932 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557879930} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10915, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1557879933 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1557879930} + m_CullTransparentMesh: 1 +--- !u!1 &1560686263 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1560686264} + - component: {fileID: 1560686265} + - component: {fileID: 1560686266} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1560686264 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1560686263} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 626742070} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1560686265 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1560686263} + m_CullTransparentMesh: 1 +--- !u!114 &1560686266 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1560686263} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 0 + m_HorizontalOverflow: 1 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: +--- !u!1 &1679565283 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1679565284} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1679565284 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1679565283} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2033163677} + m_Father: {fileID: 1154194182} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &1760805524 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1760805525} + - component: {fileID: 1760805528} + - component: {fileID: 1760805527} + - component: {fileID: 1760805526} + m_Layer: 5 + m_Name: JoinServer + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1760805525 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1760805524} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2118429759} + m_Father: {fileID: 244561620} + m_RootOrder: 4 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 82, y: 51} + m_SizeDelta: {x: 160, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1760805526 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1760805524} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1760805527} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 244561621} + m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp + m_MethodName: handleLogin + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1760805527 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1760805524} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1760805528 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1760805524} + m_CullTransparentMesh: 1 +--- !u!1 &1843597585 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1843597586} + - component: {fileID: 1843597589} + - component: {fileID: 1843597588} + - component: {fileID: 1843597587} + m_Layer: 5 + m_Name: Send + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1843597586 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1843597585} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1852007163} + m_Father: {fileID: 244561620} + m_RootOrder: 6 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 273.05, y: 88} + m_SizeDelta: {x: 94.1, y: 30} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1843597587 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1843597585} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1843597588} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 244561621} + m_TargetAssemblyTypeName: NetworkGUI, Assembly-CSharp + m_MethodName: handleSend + m_Mode: 1 + m_Arguments: + m_ObjectArgument: {fileID: 0} + m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &1843597588 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1843597585} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1843597589 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1843597585} + m_CullTransparentMesh: 1 +--- !u!1 &1852007162 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1852007163} + - component: {fileID: 1852007165} + - component: {fileID: 1852007164} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1852007163 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1852007162} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1843597586} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1852007164 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1852007162} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Send +--- !u!222 &1852007165 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1852007162} + m_CullTransparentMesh: 1 +--- !u!1 &1894247852 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1894247853} + - component: {fileID: 1894247855} + - component: {fileID: 1894247854} + m_Layer: 5 + m_Name: Received + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1894247853 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1894247852} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 244561620} + m_RootOrder: 2 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 162.54999, y: 16.098999} + m_SizeDelta: {x: 315.1, y: -47.802124} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1894247854 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1894247852} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: New Text +--- !u!222 &1894247855 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1894247852} + m_CullTransparentMesh: 1 +--- !u!1 &1954037269 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1954037272} + - component: {fileID: 1954037271} + - component: {fileID: 1954037270} + m_Layer: 5 + m_Name: Placeholder + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &1954037270 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1954037269} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 2 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 0 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Enter text... +--- !u!222 &1954037271 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1954037269} + m_CullTransparentMesh: 1 +--- !u!224 &1954037272 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1954037269} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 945446556} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: -0.5} + m_SizeDelta: {x: -20, y: -13} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &2033163676 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2033163677} + - component: {fileID: 2033163679} + - component: {fileID: 2033163678} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2033163677 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2033163676} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1679565284} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 0.2} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2033163678 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2033163676} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2033163679 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2033163676} + m_CullTransparentMesh: 1 +--- !u!1 &2118429758 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2118429759} + - component: {fileID: 2118429761} + - component: {fileID: 2118429760} + m_Layer: 5 + m_Name: Text + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2118429759 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2118429758} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1760805525} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2118429760 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2118429758} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_FontData: + m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} + m_FontSize: 14 + m_FontStyle: 0 + m_BestFit: 0 + m_MinSize: 10 + m_MaxSize: 40 + m_Alignment: 4 + m_AlignByGeometry: 0 + m_RichText: 1 + m_HorizontalOverflow: 0 + m_VerticalOverflow: 0 + m_LineSpacing: 1 + m_Text: Join Server +--- !u!222 &2118429761 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2118429758} + m_CullTransparentMesh: 1 +--- !u!1 &2144436499 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2144436500} + - component: {fileID: 2144436502} + - component: {fileID: 2144436501} + m_Layer: 5 + m_Name: Item Background + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2144436500 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2144436499} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1047954372} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &2144436501 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2144436499} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &2144436502 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2144436499} + m_CullTransparentMesh: 1 +--- !u!1001 &8565720276829121781 +PrefabInstance: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Modification: + m_TransformParent: {fileID: 0} + m_Modifications: + - target: {fileID: 8565720275311462453, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_Name + value: TestNetworkedGameObject + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_RootOrder + value: 6 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalPosition.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalPosition.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalPosition.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalRotation.w + value: 1 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalRotation.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalRotation.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalRotation.z + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalEulerAnglesHint.x + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalEulerAnglesHint.y + value: 0 + objectReference: {fileID: 0} + - target: {fileID: 8565720275311462455, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} + propertyPath: m_LocalEulerAnglesHint.z + value: 0 + objectReference: {fileID: 0} + m_RemovedComponents: [] + m_SourcePrefab: {fileID: 100100000, guid: 6e4a023f70e01405e8b249a4488fe319, type: 3} diff --git a/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/test.unity.meta b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/test.unity.meta new file mode 100644 index 0000000..775a312 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/Samples~/Example/test.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e4e43899246c941c78acfc59ce2f664a +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Packages/VelNetUnity/VelNetUnity.asmdef b/TestVelGameServer/Packages/VelNetUnity/VelNetUnity.asmdef new file mode 100644 index 0000000..3422459 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/VelNetUnity.asmdef @@ -0,0 +1,14 @@ +{ + "name": "VelNetUnity", + "rootNamespace": "VelNetUnity", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/TestVelGameServer/Packages/VelNetUnity/VelNetUnity.asmdef.meta b/TestVelGameServer/Packages/VelNetUnity/VelNetUnity.asmdef.meta new file mode 100644 index 0000000..5203378 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/VelNetUnity.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1e55e2c4387020247a1ae212bbcbd381 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Packages/VelNetUnity/package.json b/TestVelGameServer/Packages/VelNetUnity/package.json new file mode 100644 index 0000000..b3016a0 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/package.json @@ -0,0 +1,31 @@ +{ + "name": "edu.uga.engr.vel.velnetunity", + "displayName": "VelNetUnity", + "version": "1.0.0", + "unity": "2019.1", + "description": "A custom networking library for Unity.", + "keywords": [ + "networking", + "self-hosted" + ], + "author": { + "name": "Kyle Johnsen", + "email": "kjohnsen@uga.edu", + "url": "https://vel.engr.uga.edu" + }, + "samples": [ + { + "displayName": "Dissonance Integration", + "description": "Includes support for Dissonance Voice, available separately from the Unity Asset Store.", + "path": "Samples~/DissonanceIntegration" + }, + { + "displayName": "Example", + "description": "Example Scene", + "path": "Samples~/Example" + } + ], + "dependencies": { + } + } + \ No newline at end of file diff --git a/TestVelGameServer/Packages/VelNetUnity/package.json.meta b/TestVelGameServer/Packages/VelNetUnity/package.json.meta new file mode 100644 index 0000000..6b49770 --- /dev/null +++ b/TestVelGameServer/Packages/VelNetUnity/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 525b0bfd38079f24f86b406a8da0b3c7 +PackageManifestImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestVelGameServer/Packages/manifest.json b/TestVelGameServer/Packages/manifest.json index 269f819..960f904 100644 --- a/TestVelGameServer/Packages/manifest.json +++ b/TestVelGameServer/Packages/manifest.json @@ -1,10 +1,10 @@ { "dependencies": { - "com.unity.collab-proxy": "1.7.1", + "com.unity.collab-proxy": "1.15.7", "com.unity.ide.rider": "2.0.7", - "com.unity.ide.visualstudio": "2.0.11", - "com.unity.ide.vscode": "1.2.3", - "com.unity.test-framework": "1.1.27", + "com.unity.ide.visualstudio": "2.0.12", + "com.unity.ide.vscode": "1.2.4", + "com.unity.test-framework": "1.1.30", "com.unity.textmeshpro": "3.0.6", "com.unity.timeline": "1.4.8", "com.unity.ugui": "1.0.0", diff --git a/TestVelGameServer/Packages/packages-lock.json b/TestVelGameServer/Packages/packages-lock.json index 6f39b82..29bc8f6 100644 --- a/TestVelGameServer/Packages/packages-lock.json +++ b/TestVelGameServer/Packages/packages-lock.json @@ -1,11 +1,12 @@ { "dependencies": { "com.unity.collab-proxy": { - "version": "1.7.1", + "version": "1.15.7", "depth": 0, "source": "registry", "dependencies": { - "com.unity.nuget.newtonsoft-json": "2.0.0" + "com.unity.nuget.newtonsoft-json": "2.0.0", + "com.unity.services.core": "1.0.1" }, "url": "https://packages.unity.com" }, @@ -26,7 +27,7 @@ "url": "https://packages.unity.com" }, "com.unity.ide.visualstudio": { - "version": "2.0.11", + "version": "2.0.12", "depth": 0, "source": "registry", "dependencies": { @@ -35,7 +36,7 @@ "url": "https://packages.unity.com" }, "com.unity.ide.vscode": { - "version": "1.2.3", + "version": "1.2.4", "depth": 0, "source": "registry", "dependencies": {}, @@ -48,8 +49,17 @@ "dependencies": {}, "url": "https://packages.unity.com" }, + "com.unity.services.core": { + "version": "1.0.1", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0" + }, + "url": "https://packages.unity.com" + }, "com.unity.test-framework": { - "version": "1.1.27", + "version": "1.1.30", "depth": 0, "source": "registry", "dependencies": { @@ -89,6 +99,12 @@ "com.unity.modules.imgui": "1.0.0" } }, + "edu.uga.engr.vel.velnetunity": { + "version": "file:VelNetUnity", + "depth": 0, + "source": "embedded", + "dependencies": {} + }, "com.unity.modules.ai": { "version": "1.0.0", "depth": 0, diff --git a/TestVelGameServer/ProjectSettings/TimelineSettings.asset b/TestVelGameServer/ProjectSettings/TimelineSettings.asset new file mode 100644 index 0000000..b4fbdb0 --- /dev/null +++ b/TestVelGameServer/ProjectSettings/TimelineSettings.asset @@ -0,0 +1,15 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 61 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a287be6c49135cd4f9b2b8666c39d999, type: 3} + m_Name: + m_EditorClassIdentifier: + assetDefaultFramerate: 60 diff --git a/velnet_logo.png b/velnet_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..6b4b16df9dda209bb5b95e557a302982acec5c16 GIT binary patch literal 57760 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