├── .gitignore ├── Assets ├── Netgo.meta ├── Netgo │ ├── Application.meta │ ├── Application │ │ ├── CustomEvent.meta │ │ ├── CustomEvent │ │ │ ├── NGCustomEvent.cs │ │ │ └── NGCustomEvent.cs.meta │ │ ├── NGIncomingEvent.cs │ │ ├── NGIncomingEvent.cs.meta │ │ ├── NGInterface.cs │ │ ├── NGInterface.cs.meta │ │ ├── NGMessageProcessor.cs │ │ ├── NGMessageProcessor.cs.meta │ │ ├── NGPlayer.cs │ │ ├── NGPlayer.cs.meta │ │ ├── NGResourceManager.cs │ │ ├── NGResourceManager.cs.meta │ │ ├── NGRoom.cs │ │ ├── NGRoom.cs.meta │ │ ├── RPC.meta │ │ ├── RPC │ │ │ ├── NGRPC.cs │ │ │ └── NGRPC.cs.meta │ │ ├── ViewSynchronizer.meta │ │ └── ViewSynchronizer │ │ │ ├── NGView.cs │ │ │ ├── NGView.cs.meta │ │ │ ├── NGViewComponent.cs │ │ │ ├── NGViewComponent.cs.meta │ │ │ ├── NGViewContainer.cs │ │ │ ├── NGViewContainer.cs.meta │ │ │ ├── NGViewDataTransmitter.cs │ │ │ ├── NGViewDataTransmitter.cs.meta │ │ │ ├── NGViewStream.cs │ │ │ ├── NGViewStream.cs.meta │ │ │ ├── NGViewUtils.cs │ │ │ └── NGViewUtils.cs.meta │ ├── Examples.meta │ ├── Examples │ │ ├── CubeSync.meta │ │ └── CubeSync │ │ │ ├── DemoCubeScene.unity │ │ │ ├── DemoCubeScene.unity.meta │ │ │ ├── DemoLobbyScene.unity │ │ │ ├── DemoLobbyScene.unity.meta │ │ │ ├── Resources.meta │ │ │ ├── Resources │ │ │ ├── MyCube.prefab │ │ │ └── MyCube.prefab.meta │ │ │ ├── Scripts.meta │ │ │ └── Scripts │ │ │ ├── CubeController.cs │ │ │ ├── CubeController.cs.meta │ │ │ ├── CubeInstantiator.cs │ │ │ ├── CubeInstantiator.cs.meta │ │ │ ├── CubeNGIncomingEventHandler.cs │ │ │ ├── CubeNGIncomingEventHandler.cs.meta │ │ │ ├── CubeViewComponent.cs │ │ │ ├── CubeViewComponent.cs.meta │ │ │ ├── GUIUtils.cs │ │ │ ├── GUIUtils.cs.meta │ │ │ ├── LobbyMenu.cs │ │ │ ├── LobbyMenu.cs.meta │ │ │ ├── TouchEventCatcher.cs │ │ │ └── TouchEventCatcher.cs.meta │ ├── Library.meta │ ├── Library │ │ ├── NGBuffer.cs │ │ ├── NGBuffer.cs.meta │ │ ├── NGLogger.cs │ │ ├── NGLogger.cs.meta │ │ ├── NGMessageCodec.cs │ │ ├── NGMessageCodec.cs.meta │ │ ├── NGMessagePart.cs │ │ ├── NGMessagePart.cs.meta │ │ ├── NGProtobufConverter.cs │ │ ├── NGProtobufConverter.cs.meta │ │ ├── NgMessage.cs │ │ └── NgMessage.cs.meta │ ├── Network.meta │ └── Network │ │ ├── NGISocket.cs │ │ ├── NGISocket.cs.meta │ │ ├── NGMessageReceiver.cs │ │ ├── NGMessageReceiver.cs.meta │ │ ├── NGNetwork.cs │ │ ├── NGNetwork.cs.meta │ │ ├── NGNetworkIncomingEvent.cs │ │ ├── NGNetworkIncomingEvent.cs.meta │ │ ├── NGSocket.cs │ │ ├── NGSocket.cs.meta │ │ ├── NGUDPSocket.cs │ │ └── NGUDPSocket.cs.meta ├── Plugins.meta └── Plugins │ ├── Google.Protobuf.dll │ └── Google.Protobuf.dll.meta ├── LICENSE ├── README.md └── README ├── netgo-client-rpc.gif └── netgo_client_readme_viewsync.gif /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Bb]uilds/ 6 | [Ss]treamingAssets/ 7 | Assets/AssetStoreTools* 8 | Assets/Plugins/Editor 9 | 10 | # Visual Studio cache directory 11 | .vs/ 12 | 13 | 14 | Assets/abprofeb 15 | Assets/StreamingAssets 16 | Assets/StreamingAssets.meta 17 | Assets/abprofeb.meta 18 | .idea 19 | 20 | # Autogenerated VS/MD/Consulo solution and project files 21 | ExportedObj/ 22 | .consulo/ 23 | *.csproj 24 | *.unityproj 25 | *.sln 26 | *.suo 27 | *.tmp 28 | *.user 29 | *.userprefs 30 | *.pidb 31 | *.booproj 32 | *.svd 33 | *.pdb 34 | *.opendb 35 | *.asset 36 | # Unity3D generated meta files 37 | *.pidb.meta 38 | *.pdb.meta 39 | 40 | # Unity3D Generated File On Crash Reports 41 | sysinfo.txt 42 | 43 | # Builds 44 | *.apk 45 | 46 | *.log 47 | *.txt 48 | 49 | -------------------------------------------------------------------------------- /Assets/Netgo.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 12860f10345b0465395af285fabb195d 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Netgo/Application.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c4e1d01538b7c451ca38e469b6ea6617 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/CustomEvent.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0602a51f6bc154596a5828bf735f807a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/CustomEvent/NGCustomEvent.cs: -------------------------------------------------------------------------------- 1 | using Netgo.Library; 2 | 3 | using Google.Protobuf; 4 | using Netgo.Network; 5 | 6 | namespace Netgo.Client 7 | { 8 | public class NGCustomEvent 9 | { 10 | public static void SendCustomEvent(uint eventid, uint[] targetpeerids, NGAny[] customdata) 11 | { 12 | SendMessage ce = new SendMessage(); 13 | ce.MsgType = MessageType.CustomEvent; 14 | 15 | ce.CeParams = new CustomEventParams(); 16 | ce.CeParams.EventID = eventid; 17 | 18 | ce.CeParams.TargetPeerIds.AddRange(NGProtobufConverter.Array2RepeatedField(targetpeerids)); 19 | ce.CeParams.CustomData.AddRange(NGProtobufConverter.Array2RepeatedField(customdata)); 20 | 21 | var buf = NGMessageCodec.Encode(ce.ToByteArray()); 22 | NGNetwork.Socket.Send(buf); 23 | } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /Assets/Netgo/Application/CustomEvent/NGCustomEvent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 307c7fcc868ad43faab2c7e6aed24c3a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGIncomingEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Netgo.Library; 4 | 5 | namespace Netgo.Client 6 | { 7 | public class NGEvent 8 | { 9 | 10 | 11 | public delegate void onGreatedRoom(); 12 | public static onGreatedRoom OnCreatedRoom; 13 | 14 | public delegate void onGreateRoomFailed(string errmsg); 15 | public static onGreateRoomFailed OnCreateRoomFailed; 16 | 17 | public delegate void onJoinedRoom(); 18 | public static onJoinedRoom OnJoinedRoom; 19 | 20 | public delegate void onJoinRoomFailed(); 21 | public static onJoinRoomFailed OnJoinRoomFailed; 22 | 23 | public delegate void onLeftRoom(); 24 | public static onLeftRoom OnLeftRoom; 25 | 26 | public delegate void onOtherPlayerEnteredRoom(NGPlayer player); 27 | public static onOtherPlayerLeftRoom OnOtherPlayerEnteredRoom; 28 | 29 | public delegate void onOtherPlayerLeftRoom(NGPlayer player); 30 | public static onOtherPlayerLeftRoom OnOtherPlayerLeftRoom; 31 | 32 | public delegate void onCustomEvent(uint eventID, NGAny[] data); 33 | public static onCustomEvent OnCustomEvent; 34 | } 35 | 36 | 37 | public interface NGIRoomEvent 38 | { 39 | void OnGreatedRoom(); 40 | void OnGreateRoomFailed(string errmsg); 41 | void OnJoinedRoom(); 42 | void OnJoinRoomFailed(); 43 | void OnLeftRoom(); 44 | } 45 | 46 | public interface NGIPlayerEvent 47 | { 48 | void OnOtherPlayerEnteredRoom(NGPlayer player); 49 | void OnOtherPlayerLeftRoom(NGPlayer player); 50 | } 51 | 52 | public interface NGICustomEvent 53 | { 54 | void OnCustomEvent(uint eventID, NGAny[] data); 55 | } 56 | 57 | public class NGIncomingEvent : MonoBehaviour, NGIRoomEvent, NGIPlayerEvent, NGICustomEvent 58 | { 59 | public virtual void OnGreatedRoom() { } 60 | public virtual void OnGreateRoomFailed(string errmsg) { NGLogger.LogDebug("Create room failed " + errmsg); } 61 | public virtual void OnJoinedRoom() { NGLogger.LogDebug("On Joined Room. "); } 62 | public virtual void OnJoinRoomFailed() { NGLogger.LogDebug("Join room failed "); } 63 | public virtual void OnLeftRoom() { } 64 | 65 | public virtual void OnOtherPlayerEnteredRoom(NGPlayer player) { } 66 | public virtual void OnOtherPlayerLeftRoom(NGPlayer player) { } 67 | 68 | public virtual void OnCustomEvent(uint eventID, NGAny[] data) { } 69 | 70 | public void OnEnable() 71 | { 72 | NGEvent.OnCreatedRoom += this.OnGreatedRoom; 73 | NGEvent.OnCreateRoomFailed += this.OnGreateRoomFailed; 74 | NGEvent.OnJoinedRoom += this.OnJoinedRoom; 75 | NGEvent.OnJoinRoomFailed += this.OnJoinRoomFailed; 76 | NGEvent.OnLeftRoom += this.OnLeftRoom; 77 | 78 | NGEvent.OnOtherPlayerEnteredRoom += this.OnOtherPlayerEnteredRoom; 79 | NGEvent.OnOtherPlayerLeftRoom += this.OnOtherPlayerLeftRoom; 80 | 81 | NGEvent.OnCustomEvent += this.OnCustomEvent; 82 | } 83 | 84 | public void OnDisable() 85 | { 86 | NGEvent.OnCreatedRoom -= this.OnGreatedRoom; 87 | NGEvent.OnCreateRoomFailed -= this.OnGreateRoomFailed; 88 | NGEvent.OnJoinedRoom -= this.OnJoinedRoom; 89 | NGEvent.OnJoinRoomFailed -= this.OnJoinRoomFailed; 90 | NGEvent.OnLeftRoom -= this.OnLeftRoom; 91 | 92 | NGEvent.OnOtherPlayerEnteredRoom -= this.OnOtherPlayerEnteredRoom; 93 | NGEvent.OnOtherPlayerLeftRoom -= this.OnOtherPlayerLeftRoom; 94 | 95 | NGEvent.OnCustomEvent -= this.OnCustomEvent; 96 | 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGIncomingEvent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da3429619f8c34fb59e451999b492238 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGInterface.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace Netgo.Client 3 | { 4 | 5 | using System.Collections; 6 | using System.Collections.Generic; 7 | using UnityEngine; 8 | using System.Net.Sockets; 9 | using Netgo.Library; 10 | using Google.Protobuf; 11 | using System.Net; 12 | using Google.Protobuf.WellKnownTypes; 13 | 14 | using Netgo.Network; 15 | 16 | 17 | public class NGInterface 18 | { 19 | public NGNetwork mNetwork; 20 | private NGMessageReceiver mReceiver; 21 | private NGRPC mRPC; 22 | private static NGRoom mRoom = new NGRoom(); 23 | 24 | public enum State 25 | { 26 | NetworkConnected, 27 | NetworkDisconnected, 28 | } 29 | 30 | public static NGRoom CurrentRoom() 31 | { 32 | return mRoom; 33 | } 34 | 35 | 36 | 37 | // public NGGameClient(IPEndPoint serverAddress, ProtocolType type) 38 | // { 39 | // mSocket = new NGSocket(mNetwork.Type); 40 | // mSocket.Connect(serverAddress); 41 | // mRPC = new NGRPC(mSocket); 42 | // } 43 | //https://github.com/protocolbuffers/protobuf/issues/993 44 | 45 | public static void JoinOrCreateRoom(string roomid,uint maxnumber) 46 | { 47 | mRoom.JoinOrCreateRoom(roomid,maxnumber); 48 | } 49 | 50 | public static void CreateRoom(string roomid, uint maxnumber) 51 | { 52 | mRoom.CreateRoom(roomid, maxnumber); 53 | } 54 | 55 | public static void JoinRoom(string roomid) 56 | { 57 | mRoom.JoinRoom(roomid); 58 | } 59 | 60 | public static void LeaveRoom() 61 | { 62 | mRoom.LeaveRoom(); 63 | } 64 | 65 | public static void SubscribeMsgChannels(uint[] channelids) 66 | { 67 | mRoom.SubscribeMsgChannels(channelids); 68 | } 69 | 70 | public static void UnsubscribeMsgChannels(uint[] channelids) 71 | { 72 | mRoom.UnsubscribeMsgChannels(channelids); 73 | } 74 | 75 | public static void Instantiate(string prefabname, Vector3 position, Quaternion rotation, uint[] viewids) 76 | { 77 | mRoom.Instantiate(prefabname, position, rotation, viewids); 78 | } 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGInterface.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2292d090037a44d1da801d2f090e58e2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGMessageProcessor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections; 3 | using System.IO; 4 | //https://stackoverflow.com/questions/2522376/how-to-choose-between-protobuf-csharp-port-and-protobuf-net 5 | using Google.Protobuf; 6 | using Netgo.Library; 7 | 8 | using Google.Protobuf.WellKnownTypes; 9 | using UnityEngine; 10 | using Netgo.Network; 11 | 12 | 13 | namespace Netgo.Client 14 | { 15 | public class NGMessageProcessor : MonoBehaviour 16 | { 17 | 18 | 19 | private void Start() 20 | { 21 | //mSocket = NGGameClient.mSocket; 22 | this.gameObject.AddComponent(); 23 | NGMessageReceiver.Instance.MessageProcessor = ProcessRecieveData; 24 | 25 | } 26 | public static T ReadMessage(Stream stream) where T : IMessage, new() 27 | { 28 | T message = new T(); 29 | message.MergeFrom(stream); 30 | return message; 31 | } 32 | 33 | private void ProcessRecieveData(byte[] data) 34 | { 35 | //NGLogger.LogInfo("Receive a message"); 36 | Stream stream = new MemoryStream(data); 37 | 38 | ReceiveMessage message = ReadMessage(stream); 39 | switch (message.ReceiveMsgType) 40 | { 41 | case ReceiveMessageType.ResponseSocketStatus: 42 | switch (message.RssMsg.SStatus) 43 | { 44 | case SocketStatus.Connected: 45 | NGNetwork.Status = SocketStatus.Connected; 46 | NGNetworkEvent.OnConnected(); 47 | break; 48 | } 49 | break; 50 | case ReceiveMessageType.ResponseOperation: 51 | 52 | ResponseOperationMessage rmsg = message.RoMsg; 53 | NGInterface.CurrentRoom().ResponseProcessor(rmsg); 54 | break; 55 | 56 | case ReceiveMessageType.Forward: 57 | 58 | ForwardMessage fmsg = message.FMsg; 59 | uint peerId = fmsg.PeerId; 60 | switch (fmsg.MsgType) 61 | { 62 | case MessageType.JoinRoom: 63 | var jrParams = fmsg.JrfParams; 64 | NGPlayer newplayer = new NGPlayer(false, peerId); 65 | NGInterface.CurrentRoom().AddPlayer(newplayer); 66 | NGEvent.OnOtherPlayerEnteredRoom(newplayer); 67 | break; 68 | 69 | case MessageType.JoinOrCreateRoom: 70 | var jocParams = fmsg.JocrfParams; 71 | NGPlayer player = new NGPlayer(false, peerId); 72 | NGInterface.CurrentRoom().AddPlayer(player); 73 | NGEvent.OnOtherPlayerEnteredRoom(player); 74 | break; 75 | 76 | case MessageType.LeaveRoom: 77 | var lParams = fmsg.LrfParams; 78 | NGLogger.LogDebug("LeaveRoom" + peerId); 79 | 80 | var leaveplayer = NGInterface.CurrentRoom().GetNGPlayer(peerId); 81 | NGEvent.OnOtherPlayerLeftRoom(leaveplayer); 82 | Destroy(leaveplayer.GO); 83 | NGInterface.CurrentRoom().RemovePlayer(peerId); 84 | 85 | break; 86 | 87 | case MessageType.Rpc: 88 | var rpcparams = fmsg.RfParams; 89 | NGAny[] objs = NGProtobufConverter.RepeatedField2Array(rpcparams.Parameters); 90 | NGRPC.ExcuteRPC(rpcparams.ViewID, rpcparams.MethodName, objs); 91 | break; 92 | 93 | case MessageType.Instantiation: 94 | var i = fmsg.IfParams; 95 | var ids = NGProtobufConverter.RepeatedField2Array(i.ViewIDs); 96 | NGInterface.CurrentRoom().Instantiate(peerId, false, ids, i.PrefabName, i.Position, i.Rotation); 97 | break; 98 | 99 | case MessageType.ViewSync: 100 | var viewsyncparams = fmsg.VsfParams; 101 | var viewParams = viewsyncparams.VsdParams; 102 | NGViewContainer container = new NGViewContainer(); 103 | container.DeserializeAll(viewParams); 104 | break; 105 | 106 | case MessageType.CustomEvent: 107 | var ceParams = fmsg.CeParams; 108 | NGEvent.OnCustomEvent(ceParams.EventID, NGProtobufConverter.RepeatedField2Array(ceParams.CustomData)); 109 | break; 110 | 111 | } 112 | break; 113 | } 114 | } 115 | 116 | 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGMessageProcessor.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b79300c0c9c484c0b81c4f2ba3c3712a 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGPlayer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | namespace Netgo.Client 4 | { 5 | public class NGPlayer 6 | { 7 | public uint mPeerId; 8 | public bool IsLocal; 9 | public GameObject GO; 10 | 11 | public NGPlayer(bool islocal = false,uint peerid = 0) 12 | { 13 | GO = new GameObject(); 14 | mPeerId = peerid; 15 | IsLocal = islocal; 16 | } 17 | 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGPlayer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f9498afc0bed406c9a4f5413d7e9cc6 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGResourceManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | namespace Netgo.Client 5 | { 6 | public class NGResourceManager 7 | { 8 | public Dictionary ResourceBuffer = new Dictionary(); 9 | public NGResourceManager() 10 | { 11 | } 12 | 13 | public GameObject InstantiatePrefab(string prefabname,Vector3 position,Quaternion rotation) 14 | { 15 | GameObject prefabresouce = null; 16 | if(ResourceBuffer.ContainsKey(prefabname)) 17 | { 18 | prefabresouce = ResourceBuffer[prefabname]; 19 | } 20 | else 21 | { 22 | prefabresouce = (GameObject)Resources.Load(prefabname, typeof(GameObject)); 23 | ResourceBuffer.Add(prefabname, prefabresouce); 24 | } 25 | 26 | GameObject rv = GameObject.Instantiate(prefabresouce,position, rotation); 27 | return rv; 28 | } 29 | 30 | public void Destory(GameObject go) 31 | { 32 | GameObject.Destroy(go); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGResourceManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9231851361db4470f82ac675b92a4679 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGRoom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Netgo.Library; 5 | using UnityEngine; 6 | using Netgo.Network; 7 | using Google.Protobuf; 8 | namespace Netgo.Client 9 | { 10 | public class NGRoom 11 | { 12 | enum ResponseMessageInfo 13 | { 14 | Success = 1, 15 | //CreateRoomSuccess status 16 | CreateRoomSuccess = 2, 17 | //CreateRoomAlreadyExist the room is exist already. 18 | CreateRoomAlreadyExist = 3, 19 | //JoinRoomSuccess status 4 20 | JoinRoomSuccess = 4, 21 | //JoinRoomNotExist the room is not exist. 22 | JoinRoomNotExist = 5, 23 | //JoinRoomAlreadyInRoom already in the room. 24 | JoinRoomAlreadyInRoom = 6, 25 | //JoinRoomFull the room is full already. 26 | JoinRoomFull = 7, 27 | //LeaveRoomSuccess leave a room success. 28 | LeaveRoomSuccess = 8 29 | } 30 | 31 | 32 | 33 | public NGRoom() 34 | { 35 | } 36 | 37 | public Dictionary ID2OtherPlayers = new Dictionary(); 38 | public string RoomName; 39 | public NGPlayer LocalPlayer = null; 40 | 41 | public NGPlayer GetNGPlayer(uint peerid) 42 | { 43 | NGPlayer rv = null; 44 | 45 | if (!ID2OtherPlayers.TryGetValue(peerid, out rv)) 46 | { 47 | NGLogger.LogWarning("NGPlayer with ID" + peerid.ToString() + " cannot be found."); 48 | } 49 | 50 | return rv; 51 | } 52 | 53 | public void AddPlayer(NGPlayer player) 54 | { 55 | ID2OtherPlayers.Add(player.mPeerId, player); 56 | } 57 | 58 | public void RemovePlayer(uint peerid) 59 | { 60 | ID2OtherPlayers.Remove(peerid); 61 | } 62 | 63 | public void ClearPlayers() 64 | { 65 | ID2OtherPlayers.Clear(); 66 | } 67 | 68 | public GameObject Instantiate(uint peerid, bool isLocal, UInt32[] viewids, string prefabname, Vector3 position = default, Quaternion rotation = default) 69 | { 70 | NGResourceManager manager = new NGResourceManager(); 71 | var go = manager.InstantiatePrefab(prefabname, position, rotation); 72 | NGView[] views = NGViewUtils.GetViews(go); 73 | //NGLogger.LogDebug(views.Length.ToString()); 74 | if (isLocal) 75 | { 76 | uint i = 1; 77 | uint[] ids = new uint[views.Length]; 78 | foreach (var var in views) 79 | { 80 | var.PlayerID = peerid; 81 | var.ViewID = peerid * 1000 + i; 82 | ids[i - 1] = var.ViewID; 83 | i++; 84 | NGViewContainer.RegisterView(var); 85 | } 86 | LocalPlayer.GO = go; 87 | Instantiate(prefabname, position, rotation, ids); 88 | } 89 | else 90 | { 91 | for (int i = 0; i < views.Length; i++) 92 | { 93 | //NGLogger.LogDebug("Print View ID" + views[i].ViewID); 94 | views[i].ViewID = viewids[i]; 95 | views[i].PlayerID = peerid; 96 | NGViewContainer.RegisterView(views[i]); 97 | } 98 | var player = NGInterface.CurrentRoom().GetNGPlayer(peerid); 99 | player.GO = go; 100 | 101 | } 102 | 103 | return go; 104 | } 105 | 106 | public void ResponseProcessor(ResponseOperationMessage rmsg) 107 | { 108 | switch (rmsg.MsgType) 109 | { 110 | case MessageType.CreateRoom: 111 | var crParams = rmsg.CrrParams; 112 | switch (crParams.ReturnValue) 113 | { 114 | case (uint)ResponseMessageInfo.CreateRoomSuccess: 115 | LocalPlayer = new NGPlayer(true, crParams.PeerId); 116 | NGEvent.OnCreatedRoom(); 117 | break; 118 | case (uint)ResponseMessageInfo.CreateRoomAlreadyExist: 119 | NGEvent.OnCreateRoomFailed(crParams.Message); 120 | break; 121 | } 122 | break; 123 | 124 | case MessageType.JoinRoom: 125 | 126 | var jrrParams = rmsg.JrrParams; 127 | 128 | switch (jrrParams.ReturnValue) 129 | { 130 | case (uint)ResponseMessageInfo.JoinRoomSuccess: 131 | NGLogger.LogDebug("JoinRoomSuccess responsee"); 132 | LocalPlayer = new NGPlayer(true, jrrParams.PeerId); 133 | NGEvent.OnJoinedRoom(); 134 | break; 135 | case (uint)ResponseMessageInfo.JoinRoomAlreadyInRoom: 136 | NGEvent.OnJoinRoomFailed(); 137 | break; 138 | case (uint)ResponseMessageInfo.JoinRoomFull: 139 | NGEvent.OnJoinRoomFailed(); 140 | break; 141 | default: 142 | NGLogger.LogError("The return value from JoinRoom or JoinOrCreateRoom" + jrrParams.ReturnValue + " cannot be identified."); 143 | break; 144 | } 145 | break; 146 | case MessageType.LeaveRoom: 147 | var lrParams = rmsg.LrrParams; 148 | switch (lrParams.ReturnValue) 149 | { 150 | case (uint)ResponseMessageInfo.LeaveRoomSuccess: 151 | 152 | NGEvent.OnLeftRoom(); 153 | break; 154 | } 155 | break; 156 | } 157 | } 158 | 159 | public void JoinOrCreateRoom(string roomid, uint maxnumber) 160 | { 161 | SendMessage creatroom = new SendMessage(); 162 | creatroom.MsgType = MessageType.JoinOrCreateRoom; 163 | 164 | creatroom.JocrParams = new JoinOrCreateRoomParams(); 165 | creatroom.JocrParams.RoomId = roomid; 166 | creatroom.JocrParams.MaxNumber = maxnumber; 167 | 168 | var buf = NGMessageCodec.Encode(creatroom.ToByteArray()); 169 | NGNetwork.Socket.Send(buf); 170 | 171 | this.RoomName = roomid; 172 | } 173 | public void CreateRoom(string roomid, uint maxnumber) 174 | { 175 | SendMessage creatroom = new SendMessage(); 176 | creatroom.MsgType = MessageType.CreateRoom; 177 | creatroom.CrParams = new CreateRoomParams(); 178 | creatroom.CrParams.RoomId = roomid; 179 | creatroom.CrParams.MaxNumber = maxnumber; 180 | 181 | var buf = NGMessageCodec.Encode(creatroom.ToByteArray()); 182 | NGNetwork.Socket.Send(buf); 183 | 184 | this.RoomName = roomid; 185 | } 186 | 187 | public void JoinRoom(string roomid) 188 | { 189 | SendMessage joinroom = new SendMessage(); 190 | joinroom.MsgType = MessageType.JoinRoom; 191 | joinroom.JrParams = new JoinRoomParams(); 192 | joinroom.JrParams.RoomId = roomid; 193 | 194 | var buf = NGMessageCodec.Encode(joinroom.ToByteArray()); 195 | NGNetwork.Socket.Send(buf); 196 | 197 | this.RoomName = roomid; 198 | } 199 | 200 | public void LeaveRoom() 201 | { 202 | SendMessage leaveroom = new SendMessage(); 203 | leaveroom.MsgType = MessageType.LeaveRoom; 204 | 205 | var buf = NGMessageCodec.Encode(leaveroom.ToByteArray()); 206 | NGNetwork.Socket.Send(buf); 207 | 208 | NGInterface.CurrentRoom().ClearPlayers(); 209 | } 210 | 211 | public void SubscribeMsgChannels(uint[] channelids) 212 | { 213 | SendMessage submsg = new SendMessage(); 214 | submsg.MsgType = MessageType.SubscribeMsgChannels; 215 | submsg.SmcParams.Channelids.AddRange(channelids); 216 | 217 | var buf = NGMessageCodec.Encode(submsg.ToByteArray()); 218 | NGNetwork.Socket.Send(buf); 219 | } 220 | 221 | public void UnsubscribeMsgChannels(uint[] channelids) 222 | { 223 | SendMessage unsubmsg = new SendMessage(); 224 | unsubmsg.MsgType = MessageType.UnSubscribeMsgChannels; 225 | unsubmsg.UsmcParams.Channelids.AddRange(channelids); 226 | 227 | var buf = NGMessageCodec.Encode(unsubmsg.ToByteArray()); 228 | NGNetwork.Socket.Send(buf); 229 | } 230 | 231 | public void Instantiate(string prefabname, Vector3 position, Quaternion rotation, uint[] viewids) 232 | { 233 | SendMessage i = new SendMessage(); 234 | i.MsgType = MessageType.Instantiation; 235 | 236 | i.IParams = new InstantiationParams(); 237 | i.IParams.PrefabName = prefabname; 238 | i.IParams.Position = position; 239 | i.IParams.Rotation = rotation; 240 | i.IParams.ViewIDs.AddRange(NGProtobufConverter.Array2RepeatedField(viewids)); 241 | 242 | var buf = NGMessageCodec.Encode(i.ToByteArray()); 243 | 244 | NGNetwork.Socket.Send(buf); 245 | } 246 | 247 | 248 | } 249 | } 250 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/NGRoom.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fd7dc12c297414b859f990f654df796f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/RPC.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed32269855d1f4122b9c18ae4510a031 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/RPC/NGRPC.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System; 5 | using Google.Protobuf; 6 | using Netgo.Library; 7 | 8 | using System.Linq; 9 | using SType = System.Type; 10 | using Netgo.Client; 11 | using Netgo.Network; 12 | 13 | //public class 14 | //https://blog.csdn.net/zhong_chongfeng/article/details/79644701 15 | public class NGRPCMethod : Attribute 16 | { 17 | 18 | } 19 | 20 | 21 | public class NGRPC 22 | { 23 | 24 | public static Dictionary name2Method = new Dictionary(); 25 | 26 | 27 | public void CollectAllRpcFuncs() 28 | { 29 | Assembly[] assemblies = System.AppDomain.CurrentDomain.GetAssemblies(); 30 | 31 | List methods = new List(); 32 | foreach (var assembly in assemblies) 33 | { 34 | var methodsinass = assembly.GetTypes().SelectMany(x => x.GetMethods()) 35 | .Where(y => y.GetCustomAttributes() 36 | .OfType().Any()).ToArray(); 37 | 38 | methods.AddRange(methodsinass); 39 | foreach (var method in methodsinass) 40 | { 41 | if (name2Method.ContainsKey(method.Name)) 42 | { 43 | NGLogger.LogError("Error happens when collecting RFC methods."); 44 | } 45 | else 46 | { 47 | name2Method.Add(method.Name, method); 48 | } 49 | } 50 | } 51 | } 52 | //Send RPC to server 53 | public static void SendRPC(uint viewID, string methodname, RPCTarget target, params NGAny[] parameters) 54 | { 55 | SendMessage message = new SendMessage(); 56 | message.MsgType = MessageType.Rpc; 57 | message.RpcParams = new RPCParams(); 58 | message.RpcParams.MethodName = methodname; 59 | message.RpcParams.Target = target; 60 | message.RpcParams.ViewID = viewID; 61 | message.RpcParams.Parameters.AddRange(parameters); 62 | 63 | var buf = NGMessageCodec.Encode(message.ToByteArray()); 64 | NGNetwork.Socket.Send(buf); 65 | } 66 | //Excute RPC from server 67 | public static void ExcuteRPC(uint viewID, string methodname, params NGAny[] parameters) 68 | { 69 | NGViewContainer container = new NGViewContainer(); 70 | NGView view = container.GetViewByID(viewID); 71 | 72 | List components = view.ViewComponents; 73 | 74 | 75 | foreach (var item in components) 76 | { 77 | SType type = item.GetType(); 78 | BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; 79 | MethodInfo[] methods = type.GetMethods(flags); 80 | 81 | foreach (var method in methods) 82 | { 83 | if (method.Name.Equals(methodname)) 84 | { 85 | method.Invoke(item, new object[1] { parameters }); 86 | return; 87 | } 88 | } 89 | 90 | } 91 | 92 | 93 | 94 | // SType type = view.GetType(); 95 | // BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly; 96 | // MethodInfo[] methods = type.GetMethods(flags); 97 | 98 | // foreach (var method in methods) 99 | // { 100 | // if (method.Name.Equals(methodname)) 101 | // { 102 | // method.Invoke(null, parameters); 103 | // break; 104 | // } 105 | // } 106 | 107 | } 108 | } 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/RPC/NGRPC.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d1f1e2264807842aabdf4c461364341d 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4f71691c2252f487db4f85b1284a28e9 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using Netgo.Library; 5 | 6 | namespace Netgo.Client 7 | { 8 | public interface INGSerialize 9 | { 10 | void SerializeViewComponent(NGViewStream stream); 11 | void DeserializeViewComponent(NGViewStream stream); 12 | } 13 | 14 | public class NGView : MonoBehaviour 15 | { 16 | public List ViewComponents; 17 | public UInt32 ViewID; 18 | public uint PlayerID; 19 | public void Start() 20 | { 21 | //IsMine = true; 22 | // NGViewContainer.RegisterView(this); 23 | } 24 | 25 | public bool IsMine 26 | { 27 | get 28 | { 29 | bool rv = (PlayerID == NGInterface.CurrentRoom().LocalPlayer.mPeerId); 30 | Locally = rv; 31 | return rv; 32 | } 33 | 34 | } 35 | 36 | public bool Locally; 37 | 38 | public ViewSyncDataParams Serialize() 39 | { 40 | NGViewStream stream = new NGViewStream(); 41 | foreach (var component in ViewComponents) 42 | { 43 | var synccomponent = component as INGSerialize; 44 | if (synccomponent != null) 45 | { 46 | synccomponent.SerializeViewComponent(stream); 47 | } 48 | 49 | } 50 | 51 | ViewSyncDataParams param = new ViewSyncDataParams(); 52 | param.ViewID = ViewID; 53 | param.ViewSyncData.AddRange(stream.mSendStream); 54 | 55 | return param; 56 | } 57 | 58 | public void Deserialization(NGViewStream stream) 59 | { 60 | foreach (var component in ViewComponents) 61 | { 62 | var synccomponent = component as INGSerialize; 63 | if (synccomponent != null) 64 | { 65 | synccomponent.DeserializeViewComponent(stream); 66 | } 67 | 68 | } 69 | } 70 | 71 | private void OnDestroy() { 72 | NGViewContainer.UnRegisterView(ViewID); 73 | } 74 | 75 | 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4efec96951ce748e48ad1809724bf64e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewComponent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Netgo.Library; 4 | 5 | namespace Netgo.Client 6 | { 7 | public class NGViewComponent : MonoBehaviour, INGSerialize 8 | { 9 | public bool IsSyncPosition; 10 | public bool IsSyncRotation; 11 | public void SerializeViewComponent(NGViewStream stream) 12 | { 13 | if (IsSyncPosition) 14 | { 15 | stream.Send(this.transform.position); 16 | } 17 | if (IsSyncRotation) 18 | { 19 | stream.Send(this.transform.rotation); 20 | } 21 | 22 | } 23 | public void DeserializeViewComponent(NGViewStream stream) 24 | { 25 | if (IsSyncPosition) 26 | { 27 | NGLogger.LogInfo("position"); 28 | this.transform.position = (NGVector3)stream.Receive(); 29 | } 30 | 31 | if (IsSyncRotation) 32 | { 33 | NGLogger.LogInfo("IsSyncRotation"); 34 | this.transform.rotation = (NGQuaternion)stream.Receive(); 35 | } 36 | 37 | 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8889938db1bac430fa5d8bf00506cf5b 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Netgo.Library; 4 | 5 | using Google.Protobuf.Collections; 6 | 7 | namespace Netgo.Client 8 | { 9 | public class NGViewContainer 10 | { 11 | public static Dictionary ID2Views = new Dictionary(); 12 | 13 | public ViewSyncParams SerializeAll() 14 | { 15 | ViewSyncParams paramss = new ViewSyncParams(); 16 | foreach (var view in ID2Views.Values) 17 | { 18 | ViewSyncDataParams param = view.Serialize(); 19 | paramss.VsdParams.Add(param); 20 | } 21 | 22 | return paramss; 23 | } 24 | 25 | public void DeserializeAll(RepeatedField vsdparams) 26 | { 27 | if (ID2Views.Count == 0) 28 | return; 29 | foreach (var val in vsdparams) 30 | { 31 | NGViewStream stream = new NGViewStream(); 32 | stream.mReceiveStream = NGProtobufConverter.RepeatedField2List(val.ViewSyncData); 33 | //NGLogger.LogDebug(val.ViewID.ToString()); 34 | ID2Views[val.ViewID].Deserialization(stream); 35 | } 36 | 37 | } 38 | 39 | public static void RegisterView(NGView newview) 40 | { 41 | if (!ID2Views.ContainsKey(newview.ViewID)) 42 | { 43 | ID2Views.Add(newview.ViewID, newview); 44 | } 45 | 46 | } 47 | 48 | public static void UnRegisterView(UInt32 viewid) 49 | { 50 | ID2Views.Remove(viewid); 51 | } 52 | 53 | public NGView GetViewByID(uint viewid) 54 | { 55 | return ID2Views[viewid]; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewContainer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0553c464db6bb483aaad429642722da8 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewDataTransmitter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Netgo.Library; 3 | using UnityEngine; 4 | using Google.Protobuf; 5 | 6 | using Google.Protobuf.WellKnownTypes; 7 | using Netgo.Network; 8 | namespace Netgo.Client 9 | { 10 | public class NGViewDataTransmitter : MonoBehaviour 11 | { 12 | public static NGViewDataTransmitter Instance; 13 | //NGSocket mSocket; 14 | NGViewContainer _container; 15 | 16 | //send how many times in one second. 17 | private float mTransimitFrequency = 10; 18 | 19 | private void Awake() 20 | { 21 | if (Instance == null) 22 | { 23 | Instance = this; 24 | } 25 | 26 | mCurTime = 0; 27 | _container = new NGViewContainer(); 28 | //mSocket = NGGameClient.mSocket; 29 | } 30 | 31 | // millonseconds 32 | public float TransmitInterval 33 | { 34 | get 35 | { 36 | return 1 / mTransimitFrequency; 37 | } 38 | } 39 | public float mCurTime; 40 | 41 | //https://www.cnblogs.com/hobinly/p/7157481.html 42 | //https://developers.google.com/protocol-buffers/docs/techniques?csw=1#streaming 43 | //https://stackoverflow.com/questions/48558451/using-protobuf-codedinputstream-to-read-from-byte 44 | private void LateUpdate() 45 | { 46 | if (!NGNetwork.IsConnected) 47 | { 48 | return; 49 | } 50 | mCurTime += Time.deltaTime; 51 | if (mCurTime > TransmitInterval) 52 | { 53 | mCurTime = 0; 54 | ViewSyncParams paramss = _container.SerializeAll(); 55 | 56 | if (paramss.VsdParams.Count == 0) 57 | { 58 | return; 59 | } 60 | 61 | SendMessage viewsyncmsg = new SendMessage(); 62 | viewsyncmsg.MsgType = MessageType.ViewSync; 63 | viewsyncmsg.VsParams = paramss; 64 | 65 | var buf = NGMessageCodec.Encode(viewsyncmsg.ToByteArray()); 66 | 67 | 68 | NGNetwork.Socket.Send(buf); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewDataTransmitter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0e6d37710029421396ca150396103b5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewStream.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using Netgo.Library; 5 | 6 | 7 | namespace Netgo.Client 8 | { 9 | public class NGViewStream 10 | { 11 | public List mSendStream; 12 | public List mReceiveStream; 13 | public NGVector3 ngv; 14 | public NGQuaternion ngq; 15 | 16 | public int Intvalue; 17 | 18 | public NGViewStream() 19 | { 20 | mSendStream = new List(); 21 | mReceiveStream = new List(); 22 | 23 | ngv = new NGVector3(); 24 | ngq = new NGQuaternion(); 25 | 26 | } 27 | 28 | public void Send(object any) 29 | { 30 | if (any is UInt32) 31 | { 32 | mSendStream.Add(new NGAny((UInt32)any)); 33 | } 34 | else if (any is Vector3) 35 | { 36 | mSendStream.Add(new NGAny((Vector3)any)); 37 | } 38 | else if (any is Quaternion) 39 | { 40 | mSendStream.Add(new NGAny((Quaternion)any)); 41 | } 42 | } 43 | 44 | public object Receive() 45 | { 46 | if (mReceiveStream.Count > 0) 47 | { 48 | NGAny ngany = mReceiveStream[0]; 49 | mReceiveStream.RemoveAt(0); 50 | switch (ngany.NgTypeCase) 51 | 52 | { 53 | case NGAny.NgTypeOneofCase.NgUint32: 54 | return ngany.NgUint32; 55 | case NGAny.NgTypeOneofCase.NgVector3: 56 | return ngany.NgVector3; 57 | case NGAny.NgTypeOneofCase.NgQuaternion: 58 | return ngany.NgQuaternion; 59 | } 60 | } 61 | 62 | return null; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewStream.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 600de78b8605f45fc80d0f509fcdb52f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewUtils.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Netgo.Client 4 | { 5 | public class NGViewUtils 6 | { 7 | public static NGView[] GetViews(GameObject go) 8 | { 9 | return go.GetComponentsInChildren(); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /Assets/Netgo/Application/ViewSynchronizer/NGViewUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d662aa7b148443608999e00017ed3593 3 | timeCreated: 1575778669 -------------------------------------------------------------------------------- /Assets/Netgo/Examples.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 744763845c2fa437898ccf2567176d4f 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5ebe468bde51d4125a6c19e497301af8 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/DemoCubeScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 24 | m_AmbientEquatorColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 25 | m_AmbientGroundColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &4 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 10 58 | m_Resolution: 1 59 | m_BakeResolution: 50 60 | m_AtlasSize: 1024 61 | m_AO: 1 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_Padding: 2 66 | m_LightmapParameters: {fileID: 0} 67 | m_LightmapsBakeMode: 1 68 | m_TextureCompression: 0 69 | m_FinalGather: 0 70 | m_FinalGatherFiltering: 1 71 | m_FinalGatherRayCount: 256 72 | m_ReflectionCompression: 2 73 | m_MixedBakeMode: 1 74 | m_BakeBackend: 0 75 | m_PVRSampling: 1 76 | m_PVRDirectSampleCount: 32 77 | m_PVRSampleCount: 500 78 | m_PVRBounces: 2 79 | m_PVRFilterTypeDirect: 0 80 | m_PVRFilterTypeIndirect: 0 81 | m_PVRFilterTypeAO: 0 82 | m_PVRFilteringMode: 0 83 | m_PVRCulling: 1 84 | m_PVRFilteringGaussRadiusDirect: 1 85 | m_PVRFilteringGaussRadiusIndirect: 5 86 | m_PVRFilteringGaussRadiusAO: 2 87 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 88 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 89 | m_PVRFilteringAtrousPositionSigmaAO: 1 90 | m_ShowResolutionOverlay: 1 91 | m_LightingDataAsset: {fileID: 0} 92 | m_UseShadowmask: 0 93 | --- !u!1 &7 94 | GameObject: 95 | m_ObjectHideFlags: 0 96 | m_CorrespondingSourceObject: {fileID: 0} 97 | m_PrefabInstance: {fileID: 0} 98 | m_PrefabAsset: {fileID: 0} 99 | serializedVersion: 6 100 | m_Component: 101 | - component: {fileID: 13} 102 | - component: {fileID: 27} 103 | m_Layer: 0 104 | m_Name: Scripts 105 | m_TagString: MainCamera 106 | m_Icon: {fileID: 0} 107 | m_NavMeshLayer: 0 108 | m_StaticEditorFlags: 0 109 | m_IsActive: 1 110 | --- !u!1 &10 111 | GameObject: 112 | m_ObjectHideFlags: 0 113 | m_CorrespondingSourceObject: {fileID: 0} 114 | m_PrefabInstance: {fileID: 0} 115 | m_PrefabAsset: {fileID: 0} 116 | serializedVersion: 6 117 | m_Component: 118 | - component: {fileID: 16} 119 | - component: {fileID: 17} 120 | - component: {fileID: 22} 121 | - component: {fileID: 24} 122 | - component: {fileID: 21} 123 | - component: {fileID: 11} 124 | m_Layer: 0 125 | m_Name: Main Camera 126 | m_TagString: MainCamera 127 | m_Icon: {fileID: 0} 128 | m_NavMeshLayer: 0 129 | m_StaticEditorFlags: 0 130 | m_IsActive: 1 131 | --- !u!114 &11 132 | MonoBehaviour: 133 | m_ObjectHideFlags: 0 134 | m_CorrespondingSourceObject: {fileID: 0} 135 | m_PrefabInstance: {fileID: 0} 136 | m_PrefabAsset: {fileID: 0} 137 | m_GameObject: {fileID: 10} 138 | m_Enabled: 1 139 | m_EditorHideFlags: 0 140 | m_Script: {fileID: 11500000, guid: b57250053890f45eeb46285e59ce03eb, type: 3} 141 | m_Name: 142 | m_EditorClassIdentifier: 143 | eventReceiverMask: 144 | serializedVersion: 2 145 | m_Bits: 4294967295 146 | --- !u!4 &13 147 | Transform: 148 | m_ObjectHideFlags: 0 149 | m_CorrespondingSourceObject: {fileID: 0} 150 | m_PrefabInstance: {fileID: 0} 151 | m_PrefabAsset: {fileID: 0} 152 | m_GameObject: {fileID: 7} 153 | m_LocalRotation: {x: 0.1645267, y: 0, z: 0, w: 0.98637265} 154 | m_LocalPosition: {x: 0, y: 4.9474916, z: -0.105620384} 155 | m_LocalScale: {x: 1, y: 1, z: 1} 156 | m_Children: [] 157 | m_Father: {fileID: 0} 158 | m_RootOrder: 1 159 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 160 | --- !u!4 &16 161 | Transform: 162 | m_ObjectHideFlags: 0 163 | m_CorrespondingSourceObject: {fileID: 0} 164 | m_PrefabInstance: {fileID: 0} 165 | m_PrefabAsset: {fileID: 0} 166 | m_GameObject: {fileID: 10} 167 | m_LocalRotation: {x: -0.0104176905, y: -0, z: -0, w: 0.99994576} 168 | m_LocalPosition: {x: -0.01, y: 2.56, z: -14.47} 169 | m_LocalScale: {x: 1, y: 1, z: 1} 170 | m_Children: [] 171 | m_Father: {fileID: 0} 172 | m_RootOrder: 0 173 | m_LocalEulerAnglesHint: {x: -1.194, y: 0, z: 0} 174 | --- !u!20 &17 175 | Camera: 176 | m_ObjectHideFlags: 0 177 | m_CorrespondingSourceObject: {fileID: 0} 178 | m_PrefabInstance: {fileID: 0} 179 | m_PrefabAsset: {fileID: 0} 180 | m_GameObject: {fileID: 10} 181 | m_Enabled: 1 182 | serializedVersion: 2 183 | m_ClearFlags: 1 184 | m_BackGroundColor: {r: 0.54509807, g: 0.5411765, b: 0.69411767, a: 0} 185 | m_projectionMatrixMode: 1 186 | m_SensorSize: {x: 36, y: 24} 187 | m_LensShift: {x: 0, y: 0} 188 | m_GateFitMode: 2 189 | m_FocalLength: 50 190 | m_NormalizedViewPortRect: 191 | serializedVersion: 2 192 | x: 0 193 | y: 0 194 | width: 1 195 | height: 1 196 | near clip plane: 0.3 197 | far clip plane: 1000 198 | field of view: 60 199 | orthographic: 0 200 | orthographic size: 100 201 | m_Depth: -1 202 | m_CullingMask: 203 | serializedVersion: 2 204 | m_Bits: 4294967295 205 | m_RenderingPath: -1 206 | m_TargetTexture: {fileID: 0} 207 | m_TargetDisplay: 0 208 | m_TargetEye: 3 209 | m_HDR: 0 210 | m_AllowMSAA: 1 211 | m_AllowDynamicResolution: 0 212 | m_ForceIntoRT: 0 213 | m_OcclusionCulling: 1 214 | m_StereoConvergence: 10 215 | m_StereoSeparation: 0.022 216 | --- !u!81 &21 217 | AudioListener: 218 | m_ObjectHideFlags: 0 219 | m_CorrespondingSourceObject: {fileID: 0} 220 | m_PrefabInstance: {fileID: 0} 221 | m_PrefabAsset: {fileID: 0} 222 | m_GameObject: {fileID: 10} 223 | m_Enabled: 1 224 | --- !u!92 &22 225 | Behaviour: 226 | m_ObjectHideFlags: 0 227 | m_CorrespondingSourceObject: {fileID: 0} 228 | m_PrefabInstance: {fileID: 0} 229 | m_PrefabAsset: {fileID: 0} 230 | m_GameObject: {fileID: 10} 231 | m_Enabled: 1 232 | --- !u!124 &24 233 | Behaviour: 234 | m_ObjectHideFlags: 0 235 | m_CorrespondingSourceObject: {fileID: 0} 236 | m_PrefabInstance: {fileID: 0} 237 | m_PrefabAsset: {fileID: 0} 238 | m_GameObject: {fileID: 10} 239 | m_Enabled: 1 240 | --- !u!114 &27 241 | MonoBehaviour: 242 | m_ObjectHideFlags: 0 243 | m_CorrespondingSourceObject: {fileID: 0} 244 | m_PrefabInstance: {fileID: 0} 245 | m_PrefabAsset: {fileID: 0} 246 | m_GameObject: {fileID: 7} 247 | m_Enabled: 1 248 | m_EditorHideFlags: 0 249 | m_Script: {fileID: 11500000, guid: 31d56c35722d75a4591577d224c275af, type: 3} 250 | m_Name: 251 | m_EditorClassIdentifier: 252 | mMyCubePrefab: {fileID: 400000, guid: 1f910c5dace334ed189bc9a29d1fb063, type: 3} 253 | --- !u!196 &30 254 | NavMeshSettings: 255 | serializedVersion: 2 256 | m_ObjectHideFlags: 0 257 | m_BuildSettings: 258 | serializedVersion: 2 259 | agentTypeID: 0 260 | agentRadius: 0.5 261 | agentHeight: 2 262 | agentSlope: 45 263 | agentClimb: 0.4 264 | ledgeDropHeight: 0 265 | maxJumpAcrossDistance: 0 266 | minRegionArea: 2 267 | manualCellSize: 0 268 | cellSize: 0.16666666 269 | manualTileSize: 0 270 | tileSize: 256 271 | accuratePlacement: 0 272 | debug: 273 | m_Flags: 0 274 | m_NavMeshData: {fileID: 0} 275 | --- !u!1 &1284860447 276 | GameObject: 277 | m_ObjectHideFlags: 0 278 | m_CorrespondingSourceObject: {fileID: 0} 279 | m_PrefabInstance: {fileID: 0} 280 | m_PrefabAsset: {fileID: 0} 281 | serializedVersion: 6 282 | m_Component: 283 | - component: {fileID: 1284860451} 284 | - component: {fileID: 1284860450} 285 | - component: {fileID: 1284860449} 286 | - component: {fileID: 1284860448} 287 | - component: {fileID: 1284860452} 288 | m_Layer: 0 289 | m_Name: Cube 290 | m_TagString: Untagged 291 | m_Icon: {fileID: 0} 292 | m_NavMeshLayer: 0 293 | m_StaticEditorFlags: 0 294 | m_IsActive: 1 295 | --- !u!65 &1284860448 296 | BoxCollider: 297 | m_ObjectHideFlags: 0 298 | m_CorrespondingSourceObject: {fileID: 0} 299 | m_PrefabInstance: {fileID: 0} 300 | m_PrefabAsset: {fileID: 0} 301 | m_GameObject: {fileID: 1284860447} 302 | m_Material: {fileID: 0} 303 | m_IsTrigger: 0 304 | m_Enabled: 1 305 | serializedVersion: 2 306 | m_Size: {x: 1, y: 1, z: 1} 307 | m_Center: {x: 0, y: 0, z: 0} 308 | --- !u!23 &1284860449 309 | MeshRenderer: 310 | m_ObjectHideFlags: 0 311 | m_CorrespondingSourceObject: {fileID: 0} 312 | m_PrefabInstance: {fileID: 0} 313 | m_PrefabAsset: {fileID: 0} 314 | m_GameObject: {fileID: 1284860447} 315 | m_Enabled: 1 316 | m_CastShadows: 1 317 | m_ReceiveShadows: 1 318 | m_DynamicOccludee: 1 319 | m_MotionVectors: 1 320 | m_LightProbeUsage: 1 321 | m_ReflectionProbeUsage: 1 322 | m_RenderingLayerMask: 1 323 | m_RendererPriority: 0 324 | m_Materials: 325 | - {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} 326 | m_StaticBatchInfo: 327 | firstSubMesh: 0 328 | subMeshCount: 0 329 | m_StaticBatchRoot: {fileID: 0} 330 | m_ProbeAnchor: {fileID: 0} 331 | m_LightProbeVolumeOverride: {fileID: 0} 332 | m_ScaleInLightmap: 1 333 | m_PreserveUVs: 0 334 | m_IgnoreNormalsForChartDetection: 0 335 | m_ImportantGI: 0 336 | m_StitchLightmapSeams: 0 337 | m_SelectedEditorRenderState: 3 338 | m_MinimumChartSize: 4 339 | m_AutoUVMaxDistance: 0.5 340 | m_AutoUVMaxAngle: 89 341 | m_LightmapParameters: {fileID: 0} 342 | m_SortingLayerID: 0 343 | m_SortingLayer: 0 344 | m_SortingOrder: 0 345 | --- !u!33 &1284860450 346 | MeshFilter: 347 | m_ObjectHideFlags: 0 348 | m_CorrespondingSourceObject: {fileID: 0} 349 | m_PrefabInstance: {fileID: 0} 350 | m_PrefabAsset: {fileID: 0} 351 | m_GameObject: {fileID: 1284860447} 352 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 353 | --- !u!4 &1284860451 354 | Transform: 355 | m_ObjectHideFlags: 0 356 | m_CorrespondingSourceObject: {fileID: 0} 357 | m_PrefabInstance: {fileID: 0} 358 | m_PrefabAsset: {fileID: 0} 359 | m_GameObject: {fileID: 1284860447} 360 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 361 | m_LocalPosition: {x: 0, y: 0, z: 0} 362 | m_LocalScale: {x: 6, y: 0.1, z: 10} 363 | m_Children: [] 364 | m_Father: {fileID: 0} 365 | m_RootOrder: 2 366 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 367 | --- !u!114 &1284860452 368 | MonoBehaviour: 369 | m_ObjectHideFlags: 0 370 | m_CorrespondingSourceObject: {fileID: 0} 371 | m_PrefabInstance: {fileID: 0} 372 | m_PrefabAsset: {fileID: 0} 373 | m_GameObject: {fileID: 1284860447} 374 | m_Enabled: 1 375 | m_EditorHideFlags: 0 376 | m_Script: {fileID: 11500000, guid: 125fb8fc715ea4961946165c5334a723, type: 3} 377 | m_Name: 378 | m_EditorClassIdentifier: 379 | mLocalCube: {fileID: 0} 380 | mNeedMove: 0 381 | --- !u!1 &1340855967 382 | GameObject: 383 | m_ObjectHideFlags: 0 384 | m_CorrespondingSourceObject: {fileID: 0} 385 | m_PrefabInstance: {fileID: 0} 386 | m_PrefabAsset: {fileID: 0} 387 | serializedVersion: 6 388 | m_Component: 389 | - component: {fileID: 1340855969} 390 | - component: {fileID: 1340855968} 391 | m_Layer: 0 392 | m_Name: Directional Light 393 | m_TagString: Untagged 394 | m_Icon: {fileID: 0} 395 | m_NavMeshLayer: 0 396 | m_StaticEditorFlags: 0 397 | m_IsActive: 1 398 | --- !u!108 &1340855968 399 | Light: 400 | m_ObjectHideFlags: 0 401 | m_CorrespondingSourceObject: {fileID: 0} 402 | m_PrefabInstance: {fileID: 0} 403 | m_PrefabAsset: {fileID: 0} 404 | m_GameObject: {fileID: 1340855967} 405 | m_Enabled: 1 406 | serializedVersion: 8 407 | m_Type: 1 408 | m_Color: {r: 1, g: 1, b: 1, a: 1} 409 | m_Intensity: 1 410 | m_Range: 10 411 | m_SpotAngle: 30 412 | m_CookieSize: 10 413 | m_Shadows: 414 | m_Type: 0 415 | m_Resolution: -1 416 | m_CustomResolution: -1 417 | m_Strength: 1 418 | m_Bias: 0.05 419 | m_NormalBias: 0.4 420 | m_NearPlane: 0.2 421 | m_Cookie: {fileID: 0} 422 | m_DrawHalo: 0 423 | m_Flare: {fileID: 0} 424 | m_RenderMode: 0 425 | m_CullingMask: 426 | serializedVersion: 2 427 | m_Bits: 4294967295 428 | m_Lightmapping: 4 429 | m_LightShadowCasterMode: 0 430 | m_AreaSize: {x: 1, y: 1} 431 | m_BounceIntensity: 1 432 | m_ColorTemperature: 6570 433 | m_UseColorTemperature: 0 434 | m_ShadowRadius: 0 435 | m_ShadowAngle: 0 436 | --- !u!4 &1340855969 437 | Transform: 438 | m_ObjectHideFlags: 0 439 | m_CorrespondingSourceObject: {fileID: 0} 440 | m_PrefabInstance: {fileID: 0} 441 | m_PrefabAsset: {fileID: 0} 442 | m_GameObject: {fileID: 1340855967} 443 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 444 | m_LocalPosition: {x: 6.0298085, y: 1.9067528, z: -1.1911881} 445 | m_LocalScale: {x: 1, y: 1, z: 1} 446 | m_Children: [] 447 | m_Father: {fileID: 0} 448 | m_RootOrder: 3 449 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 450 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/DemoCubeScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b2b4086771d6a0e4cab81261c6e6c4f9 3 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/DemoLobbyScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 24 | m_AmbientEquatorColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 25 | m_AmbientGroundColor: {r: 0.2, g: 0.2, b: 0.2, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &4 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 10 58 | m_Resolution: 1 59 | m_BakeResolution: 50 60 | m_AtlasSize: 1024 61 | m_AO: 1 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_Padding: 2 66 | m_LightmapParameters: {fileID: 0} 67 | m_LightmapsBakeMode: 1 68 | m_TextureCompression: 0 69 | m_FinalGather: 0 70 | m_FinalGatherFiltering: 1 71 | m_FinalGatherRayCount: 256 72 | m_ReflectionCompression: 2 73 | m_MixedBakeMode: 1 74 | m_BakeBackend: 0 75 | m_PVRSampling: 1 76 | m_PVRDirectSampleCount: 32 77 | m_PVRSampleCount: 500 78 | m_PVRBounces: 2 79 | m_PVRFilterTypeDirect: 0 80 | m_PVRFilterTypeIndirect: 0 81 | m_PVRFilterTypeAO: 0 82 | m_PVRFilteringMode: 0 83 | m_PVRCulling: 1 84 | m_PVRFilteringGaussRadiusDirect: 1 85 | m_PVRFilteringGaussRadiusIndirect: 5 86 | m_PVRFilteringGaussRadiusAO: 2 87 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 88 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 89 | m_PVRFilteringAtrousPositionSigmaAO: 1 90 | m_ShowResolutionOverlay: 1 91 | m_LightingDataAsset: {fileID: 0} 92 | m_UseShadowmask: 0 93 | --- !u!1 &10 94 | GameObject: 95 | m_ObjectHideFlags: 0 96 | m_CorrespondingSourceObject: {fileID: 0} 97 | m_PrefabInstance: {fileID: 0} 98 | m_PrefabAsset: {fileID: 0} 99 | serializedVersion: 6 100 | m_Component: 101 | - component: {fileID: 16} 102 | - component: {fileID: 17} 103 | - component: {fileID: 22} 104 | - component: {fileID: 24} 105 | - component: {fileID: 21} 106 | m_Layer: 0 107 | m_Name: Main Camera 108 | m_TagString: MainCamera 109 | m_Icon: {fileID: 0} 110 | m_NavMeshLayer: 0 111 | m_StaticEditorFlags: 0 112 | m_IsActive: 1 113 | --- !u!4 &16 114 | Transform: 115 | m_ObjectHideFlags: 0 116 | m_CorrespondingSourceObject: {fileID: 0} 117 | m_PrefabInstance: {fileID: 0} 118 | m_PrefabAsset: {fileID: 0} 119 | m_GameObject: {fileID: 10} 120 | m_LocalRotation: {x: 0.20937958, y: 0, z: 0, w: 0.97783446} 121 | m_LocalPosition: {x: 0, y: 4.9474916, z: -10} 122 | m_LocalScale: {x: 1, y: 1, z: 1} 123 | m_Children: [] 124 | m_Father: {fileID: 0} 125 | m_RootOrder: 0 126 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 127 | --- !u!20 &17 128 | Camera: 129 | m_ObjectHideFlags: 0 130 | m_CorrespondingSourceObject: {fileID: 0} 131 | m_PrefabInstance: {fileID: 0} 132 | m_PrefabAsset: {fileID: 0} 133 | m_GameObject: {fileID: 10} 134 | m_Enabled: 1 135 | serializedVersion: 2 136 | m_ClearFlags: 2 137 | m_BackGroundColor: {r: 0.043137256, g: 0.043137256, b: 0.043137256, a: 0.9411765} 138 | m_projectionMatrixMode: 1 139 | m_SensorSize: {x: 36, y: 24} 140 | m_LensShift: {x: 0, y: 0} 141 | m_GateFitMode: 2 142 | m_FocalLength: 50 143 | m_NormalizedViewPortRect: 144 | serializedVersion: 2 145 | x: 0 146 | y: 0 147 | width: 1 148 | height: 1 149 | near clip plane: 0.3 150 | far clip plane: 1000 151 | field of view: 60 152 | orthographic: 0 153 | orthographic size: 100 154 | m_Depth: -1 155 | m_CullingMask: 156 | serializedVersion: 2 157 | m_Bits: 4294967295 158 | m_RenderingPath: -1 159 | m_TargetTexture: {fileID: 0} 160 | m_TargetDisplay: 0 161 | m_TargetEye: 3 162 | m_HDR: 0 163 | m_AllowMSAA: 1 164 | m_AllowDynamicResolution: 0 165 | m_ForceIntoRT: 0 166 | m_OcclusionCulling: 1 167 | m_StereoConvergence: 10 168 | m_StereoSeparation: 0.022 169 | --- !u!81 &21 170 | AudioListener: 171 | m_ObjectHideFlags: 0 172 | m_CorrespondingSourceObject: {fileID: 0} 173 | m_PrefabInstance: {fileID: 0} 174 | m_PrefabAsset: {fileID: 0} 175 | m_GameObject: {fileID: 10} 176 | m_Enabled: 1 177 | --- !u!92 &22 178 | Behaviour: 179 | m_ObjectHideFlags: 0 180 | m_CorrespondingSourceObject: {fileID: 0} 181 | m_PrefabInstance: {fileID: 0} 182 | m_PrefabAsset: {fileID: 0} 183 | m_GameObject: {fileID: 10} 184 | m_Enabled: 1 185 | --- !u!124 &24 186 | Behaviour: 187 | m_ObjectHideFlags: 0 188 | m_CorrespondingSourceObject: {fileID: 0} 189 | m_PrefabInstance: {fileID: 0} 190 | m_PrefabAsset: {fileID: 0} 191 | m_GameObject: {fileID: 10} 192 | m_Enabled: 1 193 | --- !u!196 &30 194 | NavMeshSettings: 195 | serializedVersion: 2 196 | m_ObjectHideFlags: 0 197 | m_BuildSettings: 198 | serializedVersion: 2 199 | agentTypeID: 0 200 | agentRadius: 0.5 201 | agentHeight: 2 202 | agentSlope: 45 203 | agentClimb: 0.4 204 | ledgeDropHeight: 0 205 | maxJumpAcrossDistance: 0 206 | minRegionArea: 2 207 | manualCellSize: 0 208 | cellSize: 0.16666666 209 | manualTileSize: 0 210 | tileSize: 256 211 | accuratePlacement: 0 212 | debug: 213 | m_Flags: 0 214 | m_NavMeshData: {fileID: 0} 215 | --- !u!1 &1361576477 216 | GameObject: 217 | m_ObjectHideFlags: 0 218 | m_CorrespondingSourceObject: {fileID: 0} 219 | m_PrefabInstance: {fileID: 0} 220 | m_PrefabAsset: {fileID: 0} 221 | serializedVersion: 6 222 | m_Component: 223 | - component: {fileID: 1361576479} 224 | - component: {fileID: 1361576478} 225 | m_Layer: 0 226 | m_Name: MenuScripts 227 | m_TagString: Untagged 228 | m_Icon: {fileID: 0} 229 | m_NavMeshLayer: 0 230 | m_StaticEditorFlags: 0 231 | m_IsActive: 1 232 | --- !u!114 &1361576478 233 | MonoBehaviour: 234 | m_ObjectHideFlags: 0 235 | m_CorrespondingSourceObject: {fileID: 0} 236 | m_PrefabInstance: {fileID: 0} 237 | m_PrefabAsset: {fileID: 0} 238 | m_GameObject: {fileID: 1361576477} 239 | m_Enabled: 1 240 | m_EditorHideFlags: 0 241 | m_Script: {fileID: 11500000, guid: a02ce27e88b39fa428538620fe0335e3, type: 3} 242 | m_Name: 243 | m_EditorClassIdentifier: 244 | Skin: {fileID: 0} 245 | WidthAndHeight: {x: 600, y: 400} 246 | --- !u!4 &1361576479 247 | Transform: 248 | m_ObjectHideFlags: 0 249 | m_CorrespondingSourceObject: {fileID: 0} 250 | m_PrefabInstance: {fileID: 0} 251 | m_PrefabAsset: {fileID: 0} 252 | m_GameObject: {fileID: 1361576477} 253 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 254 | m_LocalPosition: {x: -0.01764524, y: 4.5084667, z: -9.118713} 255 | m_LocalScale: {x: 1, y: 1, z: 1} 256 | m_Children: [] 257 | m_Father: {fileID: 0} 258 | m_RootOrder: 2 259 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 260 | --- !u!1 &1565804093 261 | GameObject: 262 | m_ObjectHideFlags: 0 263 | m_CorrespondingSourceObject: {fileID: 0} 264 | m_PrefabInstance: {fileID: 0} 265 | m_PrefabAsset: {fileID: 0} 266 | serializedVersion: 6 267 | m_Component: 268 | - component: {fileID: 1565804097} 269 | - component: {fileID: 1565804096} 270 | - component: {fileID: 1565804095} 271 | - component: {fileID: 1565804094} 272 | - component: {fileID: 1565804098} 273 | m_Layer: 0 274 | m_Name: NetgoScripts 275 | m_TagString: Untagged 276 | m_Icon: {fileID: 0} 277 | m_NavMeshLayer: 0 278 | m_StaticEditorFlags: 0 279 | m_IsActive: 1 280 | --- !u!114 &1565804094 281 | MonoBehaviour: 282 | m_ObjectHideFlags: 0 283 | m_CorrespondingSourceObject: {fileID: 0} 284 | m_PrefabInstance: {fileID: 0} 285 | m_PrefabAsset: {fileID: 0} 286 | m_GameObject: {fileID: 1565804093} 287 | m_Enabled: 1 288 | m_EditorHideFlags: 0 289 | m_Script: {fileID: 11500000, guid: b79300c0c9c484c0b81c4f2ba3c3712a, type: 3} 290 | m_Name: 291 | m_EditorClassIdentifier: 292 | --- !u!114 &1565804095 293 | MonoBehaviour: 294 | m_ObjectHideFlags: 0 295 | m_CorrespondingSourceObject: {fileID: 0} 296 | m_PrefabInstance: {fileID: 0} 297 | m_PrefabAsset: {fileID: 0} 298 | m_GameObject: {fileID: 1565804093} 299 | m_Enabled: 1 300 | m_EditorHideFlags: 0 301 | m_Script: {fileID: 11500000, guid: 6f431c2404e1346fa8eba2aa7de59801, type: 3} 302 | m_Name: 303 | m_EditorClassIdentifier: 304 | Address: 192.168.0.104 305 | Port: 8686 306 | Type: 0 307 | --- !u!114 &1565804096 308 | MonoBehaviour: 309 | m_ObjectHideFlags: 0 310 | m_CorrespondingSourceObject: {fileID: 0} 311 | m_PrefabInstance: {fileID: 0} 312 | m_PrefabAsset: {fileID: 0} 313 | m_GameObject: {fileID: 1565804093} 314 | m_Enabled: 1 315 | m_EditorHideFlags: 0 316 | m_Script: {fileID: 11500000, guid: e0e6d37710029421396ca150396103b5, type: 3} 317 | m_Name: 318 | m_EditorClassIdentifier: 319 | mCurTime: 0 320 | --- !u!4 &1565804097 321 | Transform: 322 | m_ObjectHideFlags: 0 323 | m_CorrespondingSourceObject: {fileID: 0} 324 | m_PrefabInstance: {fileID: 0} 325 | m_PrefabAsset: {fileID: 0} 326 | m_GameObject: {fileID: 1565804093} 327 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 328 | m_LocalPosition: {x: -0.01764524, y: 4.5084667, z: -9.118713} 329 | m_LocalScale: {x: 1, y: 1, z: 1} 330 | m_Children: [] 331 | m_Father: {fileID: 0} 332 | m_RootOrder: 1 333 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 334 | --- !u!114 &1565804098 335 | MonoBehaviour: 336 | m_ObjectHideFlags: 0 337 | m_CorrespondingSourceObject: {fileID: 0} 338 | m_PrefabInstance: {fileID: 0} 339 | m_PrefabAsset: {fileID: 0} 340 | m_GameObject: {fileID: 1565804093} 341 | m_Enabled: 1 342 | m_EditorHideFlags: 0 343 | m_Script: {fileID: 11500000, guid: e834b5e44479941b996bd4edd6528a24, type: 3} 344 | m_Name: 345 | m_EditorClassIdentifier: 346 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/DemoLobbyScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d127e961917b252458a9910af185709e 3 | labels: 4 | - ExitGames 5 | - PUN 6 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 671da94411d0648c3bf984410d2bd1f6 3 | folderAsset: yes 4 | timeCreated: 1539049880 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Resources/MyCube.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &100000 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | serializedVersion: 6 10 | m_Component: 11 | - component: {fileID: 400000} 12 | - component: {fileID: 3300000} 13 | - component: {fileID: 6500000} 14 | - component: {fileID: 2300000} 15 | - component: {fileID: 2766474866119271245} 16 | - component: {fileID: 1101594507} 17 | - component: {fileID: 6075083264458551261} 18 | m_Layer: 0 19 | m_Name: ColoredCube 20 | m_TagString: Untagged 21 | m_Icon: {fileID: 0} 22 | m_NavMeshLayer: 0 23 | m_StaticEditorFlags: 0 24 | m_IsActive: 1 25 | --- !u!4 &400000 26 | Transform: 27 | m_ObjectHideFlags: 0 28 | m_CorrespondingSourceObject: {fileID: 0} 29 | m_PrefabInstance: {fileID: 0} 30 | m_PrefabAsset: {fileID: 0} 31 | m_GameObject: {fileID: 100000} 32 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 33 | m_LocalPosition: {x: 0, y: 0, z: 0} 34 | m_LocalScale: {x: 1, y: 1, z: 1} 35 | m_Children: [] 36 | m_Father: {fileID: 0} 37 | m_RootOrder: 0 38 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 39 | --- !u!33 &3300000 40 | MeshFilter: 41 | m_ObjectHideFlags: 0 42 | m_CorrespondingSourceObject: {fileID: 0} 43 | m_PrefabInstance: {fileID: 0} 44 | m_PrefabAsset: {fileID: 0} 45 | m_GameObject: {fileID: 100000} 46 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 47 | --- !u!65 &6500000 48 | BoxCollider: 49 | m_ObjectHideFlags: 0 50 | m_CorrespondingSourceObject: {fileID: 0} 51 | m_PrefabInstance: {fileID: 0} 52 | m_PrefabAsset: {fileID: 0} 53 | m_GameObject: {fileID: 100000} 54 | m_Material: {fileID: 0} 55 | m_IsTrigger: 0 56 | m_Enabled: 1 57 | serializedVersion: 2 58 | m_Size: {x: 1, y: 1, z: 1} 59 | m_Center: {x: 0, y: 0, z: 0} 60 | --- !u!23 &2300000 61 | MeshRenderer: 62 | m_ObjectHideFlags: 0 63 | m_CorrespondingSourceObject: {fileID: 0} 64 | m_PrefabInstance: {fileID: 0} 65 | m_PrefabAsset: {fileID: 0} 66 | m_GameObject: {fileID: 100000} 67 | m_Enabled: 1 68 | m_CastShadows: 1 69 | m_ReceiveShadows: 1 70 | m_DynamicOccludee: 1 71 | m_MotionVectors: 1 72 | m_LightProbeUsage: 0 73 | m_ReflectionProbeUsage: 1 74 | m_RenderingLayerMask: 1 75 | m_RendererPriority: 0 76 | m_Materials: 77 | - {fileID: 10302, guid: 0000000000000000f000000000000000, type: 0} 78 | m_StaticBatchInfo: 79 | firstSubMesh: 0 80 | subMeshCount: 0 81 | m_StaticBatchRoot: {fileID: 0} 82 | m_ProbeAnchor: {fileID: 0} 83 | m_LightProbeVolumeOverride: {fileID: 0} 84 | m_ScaleInLightmap: 1 85 | m_PreserveUVs: 0 86 | m_IgnoreNormalsForChartDetection: 0 87 | m_ImportantGI: 0 88 | m_StitchLightmapSeams: 0 89 | m_SelectedEditorRenderState: 3 90 | m_MinimumChartSize: 4 91 | m_AutoUVMaxDistance: 0.5 92 | m_AutoUVMaxAngle: 89 93 | m_LightmapParameters: {fileID: 0} 94 | m_SortingLayerID: 0 95 | m_SortingLayer: 0 96 | m_SortingOrder: 0 97 | --- !u!114 &2766474866119271245 98 | MonoBehaviour: 99 | m_ObjectHideFlags: 0 100 | m_CorrespondingSourceObject: {fileID: 0} 101 | m_PrefabInstance: {fileID: 0} 102 | m_PrefabAsset: {fileID: 0} 103 | m_GameObject: {fileID: 100000} 104 | m_Enabled: 1 105 | m_EditorHideFlags: 0 106 | m_Script: {fileID: 11500000, guid: cf3a2ed0c467a433a8c5af4b56076069, type: 3} 107 | m_Name: 108 | m_EditorClassIdentifier: 109 | --- !u!114 &1101594507 110 | MonoBehaviour: 111 | m_ObjectHideFlags: 0 112 | m_CorrespondingSourceObject: {fileID: 0} 113 | m_PrefabInstance: {fileID: 0} 114 | m_PrefabAsset: {fileID: 0} 115 | m_GameObject: {fileID: 100000} 116 | m_Enabled: 1 117 | m_EditorHideFlags: 0 118 | m_Script: {fileID: 11500000, guid: 4efec96951ce748e48ad1809724bf64e, type: 3} 119 | m_Name: 120 | m_EditorClassIdentifier: 121 | ViewComponents: 122 | - {fileID: 2766474866119271245} 123 | ViewID: 0 124 | PlayerID: 0 125 | Locally: 0 126 | --- !u!54 &6075083264458551261 127 | Rigidbody: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | m_GameObject: {fileID: 100000} 133 | serializedVersion: 2 134 | m_Mass: 1 135 | m_Drag: 0 136 | m_AngularDrag: 0.05 137 | m_UseGravity: 1 138 | m_IsKinematic: 0 139 | m_Interpolate: 0 140 | m_Constraints: 122 141 | m_CollisionDetection: 0 142 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Resources/MyCube.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f910c5dace334ed189bc9a29d1fb063 3 | PrefabImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 554d078f80ba74e56a63b28081b884e3 3 | folderAsset: yes 4 | timeCreated: 1539049880 5 | licenseType: Pro 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/CubeController.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------- 2 | // TNet 3 3 | // Copyright © 2012-2018 Tasharen Entertainment Inc 4 | //------------------------------------------------- 5 | 6 | using UnityEngine; 7 | using Netgo.Client; 8 | using Netgo.Library; 9 | using System.Collections; 10 | using UnityEngine.SceneManagement; 11 | 12 | [ExecuteInEditMode] 13 | public class CubeController : MonoBehaviour 14 | { 15 | 16 | public GameObject mLocalCube; 17 | 18 | public static CubeController Instance; 19 | 20 | private void Awake() 21 | { 22 | if (Instance == null) 23 | { 24 | Instance = this; 25 | } 26 | mCurY = 0.55f; 27 | } 28 | public static double mMapLeftX = -3f; 29 | public static double mMapRightX = 3f; 30 | 31 | public static double mMapLeftZ = -5f; 32 | public static double mMapRightZ = 5f; 33 | 34 | public static float mCurX, mCurY, mCurZ; 35 | 36 | public double GetRandomNumberInRange(double minNumber, double maxNumber) 37 | { 38 | return new System.Random().NextDouble() * (maxNumber - minNumber) + minNumber; 39 | } 40 | public int GetRandomRotationY() 41 | { 42 | return new System.Random().Next(0, 360); 43 | } 44 | public void UpdatePosition() 45 | { 46 | mCurX = (float)GetRandomNumberInRange(mMapLeftX, mMapRightX); 47 | mCurZ = (float)GetRandomNumberInRange(mMapLeftZ, mMapRightZ); 48 | 49 | if (mLocalCube != null) 50 | mLocalCube.transform.position = new Vector3(mCurX, mCurY, mCurZ); 51 | } 52 | public void UpdateRotation() 53 | { 54 | Vector3 rotation = new Vector3(0, GetRandomRotationY(), 0); 55 | 56 | if (mLocalCube != null) 57 | mLocalCube.transform.localEulerAngles = new Vector3(0, GetRandomRotationY(), 0); 58 | } 59 | public bool mNeedMove = false; 60 | public IEnumerator Move() 61 | { 62 | while (mNeedMove) 63 | { 64 | yield return new WaitForSeconds(2); 65 | UpdatePosition(); 66 | yield return new WaitForSeconds(2); 67 | UpdateRotation(); 68 | } 69 | } 70 | public void OnGUI() 71 | { 72 | float rectwidth = 200f; 73 | float rectheight = 300f; 74 | 75 | Rect rect = new Rect(Screen.width * 0.02f, Screen.height * 0.02f, rectwidth, rectheight); 76 | 77 | 78 | GUI.color = Color.black; 79 | GUI.Box(GUIUtils.ProcessRect(rect, 8f), ""); 80 | GUI.color = Color.white; 81 | 82 | float buttonwidth = rectwidth; 83 | float buttonheight = 50; 84 | GUILayoutOption[] buttonoptions = { GUILayout.Width(buttonwidth), GUILayout.Height(buttonheight) }; 85 | 86 | float buttonspace = 15; 87 | 88 | GUILayout.BeginArea(rect); 89 | { 90 | GUILayout.Space(5); 91 | 92 | if (GUILayout.Button("Back to Lobby", buttonoptions)) 93 | { 94 | NGInterface.LeaveRoom(); 95 | SceneManager.LoadScene(LobbyMenu.LobbySceneName); 96 | } 97 | 98 | GUILayout.Space(buttonspace); 99 | 100 | if (GUILayout.Button("Move", buttonoptions)) 101 | { 102 | mNeedMove = true; 103 | StartCoroutine(Move()); 104 | 105 | } 106 | 107 | GUILayout.Space(buttonspace); 108 | 109 | if (GUILayout.Button("Stop", buttonoptions)) 110 | { 111 | mNeedMove = false; 112 | } 113 | 114 | GUILayout.Space(buttonspace); 115 | 116 | if (GUILayout.Button("Jump", buttonoptions)) 117 | { 118 | if (mLocalCube != null) 119 | { 120 | var curposition = mLocalCube.transform.position; 121 | mLocalCube.transform.position = new Vector3(curposition.x, curposition.y * 10, curposition.z); 122 | } 123 | } 124 | } 125 | GUILayout.EndArea(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/CubeController.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 125fb8fc715ea4961946165c5334a723 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/CubeInstantiator.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Part of: netgo-unity-client 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using UnityEngine; 8 | using UnityEngine.SceneManagement; 9 | using Netgo.Client; 10 | using Netgo.Network; 11 | 12 | public class CubeInstantiator : MonoBehaviour 13 | { 14 | public Transform mMyCubePrefab; 15 | 16 | public void Start() 17 | { 18 | if (!NGNetwork.IsConnected) 19 | { 20 | SceneManager.LoadScene(LobbyMenu.LobbySceneName); 21 | return; 22 | } 23 | var go = NGInterface.CurrentRoom().Instantiate(NGInterface.CurrentRoom().LocalPlayer.mPeerId, true, null, this.mMyCubePrefab.name, transform.position, Quaternion.identity); 24 | CubeController.Instance.mLocalCube = go; 25 | 26 | } 27 | public void OnLeftRoom() 28 | { 29 | Debug.LogError("OnLeftRoom (local)"); 30 | 31 | // back to main menu 32 | SceneManager.LoadScene(LobbyMenu.LobbySceneName); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/CubeInstantiator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 31d56c35722d75a4591577d224c275af 3 | labels: 4 | - ExitGames 5 | - PUN 6 | MonoImporter: 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/CubeNGIncomingEventHandler.cs: -------------------------------------------------------------------------------- 1 | using Netgo.Library; 2 | using UnityEngine.SceneManagement; 3 | using Netgo.Client; 4 | public class CubeNGIncomingEventHandler : NGIncomingEvent 5 | { 6 | public override void OnJoinedRoom() 7 | { 8 | NGLogger.LogInfo("OnJoinedRoom"); 9 | SceneManager.LoadScene(LobbyMenu.CubeSceneName); 10 | } 11 | 12 | public override void OnGreatedRoom() 13 | { 14 | NGLogger.LogInfo("OnCreatedRoom"); 15 | SceneManager.LoadScene(LobbyMenu.CubeSceneName); 16 | } 17 | 18 | public override void OnLeftRoom() 19 | { 20 | NGLogger.LogInfo("onLeftroom"); 21 | } 22 | 23 | public override void OnOtherPlayerEnteredRoom(NGPlayer player) 24 | { 25 | NGLogger.LogInfo("OnOtherPlayerEnteredRoom" + player.mPeerId); 26 | } 27 | 28 | public override void OnOtherPlayerLeftRoom(NGPlayer player) 29 | { 30 | NGLogger.LogInfo("OnOtherPlayerLeftRoom" + player.mPeerId); 31 | } 32 | 33 | 34 | 35 | } -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/CubeNGIncomingEventHandler.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e834b5e44479941b996bd4edd6528a24 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/CubeViewComponent.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------- 2 | // TNet 3 3 | // Copyright © 2012-2018 Tasharen Entertainment Inc 4 | //------------------------------------------------- 5 | 6 | using UnityEngine; 7 | using Netgo.Client; 8 | using Netgo.Library; 9 | 10 | 11 | /// 12 | /// This simple script shows how to change the color of an object on all connected clients. 13 | /// You can see it used in Example 1. 14 | /// 15 | 16 | 17 | [RequireComponent(typeof(Renderer))] 18 | [ExecuteInEditMode] 19 | public class CubeViewComponent : NGIncomingEvent, INGSerialize 20 | { 21 | Material mMat; 22 | 23 | NGView view; 24 | Vector3 mTarget; 25 | 26 | void Awake() 27 | { 28 | mMat = GetComponent().material; 29 | view = this.gameObject.GetComponent(); 30 | } 31 | 32 | bool changed = true; 33 | Vector3 scale1 = new Vector3(2, 2, 2); 34 | Vector3 scale2 = new Vector3(1, 1, 1); 35 | void OnClick() 36 | { 37 | if (!view.IsMine) 38 | { 39 | Vector3 scale; 40 | if (changed) 41 | { 42 | scale = scale1; 43 | } 44 | else 45 | { 46 | scale = scale2; 47 | } 48 | changed = !changed; 49 | NGCustomEvent.SendCustomEvent(SyncEventID, new uint[] { view.PlayerID }, new NGAny[1] { scale }); 50 | } 51 | else 52 | { 53 | Color color = Color.red; 54 | if (mMat.color == Color.red) 55 | { 56 | color = Color.green; 57 | } 58 | else if (mMat.color == Color.green) 59 | { 60 | color = Color.blue; 61 | } 62 | 63 | NGAny colorany = new NGAny(color); 64 | NGRPC.SendRPC(view.ViewID, "OnColor", RPCTarget.All, new NGAny[1] { colorany }); 65 | } 66 | 67 | } 68 | 69 | /******************************************** 70 | /* RPC sync 71 | *********************************************/ 72 | 73 | [NGRPCMethod] 74 | public void OnColor(NGAny[] c) 75 | { 76 | mMat.color = c[0].NgColor; 77 | } 78 | /******************************************** 79 | /* Event communicate 80 | ********************************************/ 81 | const uint SyncEventID = 1; 82 | public override void OnCustomEvent(uint eventID, NGAny[] data) 83 | { 84 | if (!view.IsMine) 85 | { 86 | return; 87 | } 88 | switch (eventID) 89 | { 90 | case SyncEventID: 91 | this.transform.localScale = data[0].NgVector3; 92 | break; 93 | } 94 | } 95 | /******************************************** 96 | /* View Sync 97 | *********************************************/ 98 | private Vector3 mCorrentPosition = Vector3.zero; 99 | private Quaternion mCorrentRotation = Quaternion.identity; 100 | public void SerializeViewComponent(NGViewStream stream) 101 | { 102 | stream.Send(this.transform.position); 103 | stream.Send(this.transform.rotation); 104 | } 105 | public void DeserializeViewComponent(NGViewStream stream) 106 | { 107 | mCorrentPosition = (NGVector3)stream.Receive(); 108 | mCorrentRotation = (NGQuaternion)stream.Receive(); 109 | } 110 | void Update() 111 | { 112 | if (!view.IsMine) 113 | { 114 | transform.position = mCorrentPosition;//Vector3.Lerp(transform.position, mCorrentPosition, Time.deltaTime * 5); 115 | transform.rotation = mCorrentRotation;//Quaternion.Lerp(transform.rotation, mCorrentRotation, Time.deltaTime * 5); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/CubeViewComponent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cf3a2ed0c467a433a8c5af4b56076069 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/GUIUtils.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | public class GUIUtils 3 | { 4 | static public Rect ProcessRect(Rect rect, float distance) 5 | { 6 | Rect r = rect; 7 | r.xMin -= distance; 8 | r.xMax += distance; 9 | r.yMin -= distance; 10 | r.yMax += distance; 11 | return r; 12 | } 13 | } -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/GUIUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 56c53c8a4d89f47eaaa2f30f4d547280 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/LobbyMenu.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Part of: netgo-unity-client 4 | // 5 | // -------------------------------------------------------------------------------------------------------------------- 6 | 7 | using System; 8 | using UnityEngine; 9 | using UnityEngine.SceneManagement; 10 | using Random = UnityEngine.Random; 11 | using Netgo.Client; 12 | using Netgo.Library; 13 | 14 | [ExecuteInEditMode] 15 | public class LobbyMenu : MonoBehaviour 16 | { 17 | public GUISkin Skin; 18 | public Vector2 WidthAndHeight = new Vector2(600, 400); 19 | private string roomName = "myRoom"; 20 | 21 | private Vector2 scrollPos = Vector2.zero; 22 | 23 | private bool connectFailed = false; 24 | 25 | public static readonly string LobbySceneName = "DemoLobbyScene"; 26 | 27 | public static readonly string CubeSceneName = "DemoCubeScene"; 28 | 29 | private string errorDialog; 30 | private double timeToClearDialog; 31 | 32 | public string ErrorDialog 33 | { 34 | get { return this.errorDialog; } 35 | private set 36 | { 37 | this.errorDialog = value; 38 | if (!string.IsNullOrEmpty(value)) 39 | { 40 | this.timeToClearDialog = Time.time + 4.0f; 41 | } 42 | } 43 | } 44 | public void OnGUI() 45 | { 46 | DrawLobbyMenu(); 47 | } 48 | 49 | 50 | string mRoomName = "MyRoomName"; 51 | uint mRoomCapacity = 10; 52 | string mMessage = ""; 53 | 54 | 55 | 56 | void DrawLobbyMenu() 57 | { 58 | float rectwidth = 500f; 59 | float rectheight = 900f; 60 | 61 | Rect rect = new Rect(Screen.width / 2 - rectwidth / 2, 62 | Screen.height / 2 - 100f, rectwidth, rectheight); 63 | 64 | // Show a half-transparent box around the upcoming UI 65 | GUI.color = new Color(0f, 0f, 0f, 1f); 66 | GUI.Box(GUIUtils.ProcessRect(rect, 8f), ""); 67 | GUI.color = Color.white; 68 | 69 | 70 | float buttonwidth = rectwidth; 71 | float buttonheight = 80; 72 | GUILayoutOption[] buttonoptions = { GUILayout.Width(buttonwidth), GUILayout.Height(buttonheight) }; 73 | 74 | float textwidth = 270; 75 | float textheight = 60; 76 | GUILayoutOption[] textoptions = { GUILayout.Width(textwidth), GUILayout.Height(textheight) }; 77 | 78 | 79 | GUILayout.BeginArea(rect); 80 | { 81 | GUILayout.Space(20); 82 | 83 | GUILayout.BeginHorizontal(); 84 | GUILayout.Label("Room Name:"); 85 | mRoomName = GUILayout.TextField(mRoomName, textoptions); 86 | GUILayout.EndHorizontal(); 87 | 88 | GUILayout.BeginHorizontal(); 89 | GUILayout.Label("Room Capacity:"); 90 | string roomcapacity = "10"; 91 | roomcapacity = GUILayout.TextField(roomcapacity, textoptions); 92 | GUILayout.EndHorizontal(); 93 | 94 | GUILayout.Space(30); 95 | 96 | if (!uint.TryParse(roomcapacity, out mRoomCapacity)) 97 | { 98 | NGLogger.LogError("The Room Capacity cannot be parsed to uint"); 99 | } 100 | if (GUILayout.Button("Join Or Create Room", buttonoptions)) 101 | { 102 | NGInterface.JoinOrCreateRoom(mRoomName, mRoomCapacity); 103 | } 104 | GUILayout.Space(5); 105 | if (GUILayout.Button("Create Room", buttonoptions)) 106 | { 107 | NGInterface.CreateRoom(mRoomName, mRoomCapacity); 108 | } 109 | GUILayout.Space(5); 110 | 111 | // GUILayout.BeginHorizontal(); 112 | // GUILayout.Space((rectwidth - buttonwidth) / 2); 113 | if (GUILayout.Button("Join Room", buttonoptions)) 114 | { 115 | NGInterface.JoinRoom(mRoomName); 116 | } 117 | //GUILayout.EndHorizontal(); 118 | 119 | GUI.backgroundColor = Color.white; 120 | 121 | if (!string.IsNullOrEmpty(mMessage)) GUILayout.Label(mMessage); 122 | } 123 | GUILayout.EndArea(); 124 | 125 | 126 | } 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | } 135 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/LobbyMenu.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a02ce27e88b39fa428538620fe0335e3 3 | labels: 4 | - ExitGames 5 | - PUN 6 | MonoImporter: 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/TouchEventCatcher.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------- 2 | // TNet 3 3 | // Copyright © 2012-2018 Tasharen Entertainment Inc 4 | //------------------------------------------------- 5 | 6 | using UnityEngine; 7 | using Netgo.Library; 8 | 9 | 10 | /// 11 | /// Very simple event manager script that sends out basic touch and mouse-based notifications using NGUI's syntax. 12 | /// 13 | 14 | [RequireComponent(typeof(Camera))] 15 | public class TouchEventCatcher : MonoBehaviour 16 | { 17 | public LayerMask eventReceiverMask = -1; 18 | 19 | Camera mCam; 20 | void Awake() { mCam = GetComponent(); } 21 | void Update() 22 | { 23 | // Touch notifications 24 | if (Input.touchCount > 0) 25 | { 26 | Touch touch = Input.GetTouch(0); 27 | if (touch.phase != TouchPhase.Began && 28 | touch.phase != TouchPhase.Moved && 29 | touch.phase != TouchPhase.Stationary) 30 | { 31 | SendOnClick(touch.position); 32 | } 33 | } 34 | else 35 | { 36 | if (Input.GetMouseButtonUp(0)) 37 | { 38 | NGLogger.LogDebug("on Click"); 39 | SendOnClick(Input.mousePosition); 40 | } 41 | } 42 | } 43 | void SendOnClick(Vector2 pos) 44 | { 45 | GameObject go = GetGameObjectShootedByRay(pos); 46 | if (go != null) 47 | go.SendMessage("OnClick", SendMessageOptions.DontRequireReceiver); 48 | 49 | } 50 | GameObject GetGameObjectShootedByRay(Vector3 pos) 51 | { 52 | RaycastHit hit; 53 | if (Physics.Raycast(mCam.ScreenPointToRay(pos), out hit, 300f, eventReceiverMask)) 54 | { 55 | return hit.collider.gameObject; 56 | } 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Assets/Netgo/Examples/CubeSync/Scripts/TouchEventCatcher.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b57250053890f45eeb46285e59ce03eb 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Library.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2545c49ee970441cfaf4fcf0c6d73777 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGBuffer.cs: -------------------------------------------------------------------------------- 1 | namespace Netgo.Library 2 | { 3 | using System; 4 | public class NGBuffer 5 | { 6 | private byte[] mBuffer; 7 | 8 | public byte[] Bytes 9 | { 10 | get { return mBuffer; } 11 | } 12 | 13 | public NGBuffer(byte[] buffer,int size) 14 | { 15 | mBuffer = new byte[size]; 16 | Buffer.BlockCopy(buffer, 0, mBuffer, 0, size); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGBuffer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9b8cce01dd6694edeb1261aeaabf7c88 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Netgo.Library 5 | { 6 | public class NGLogger 7 | { 8 | public static void LogError(string message) 9 | { 10 | Debug.LogError(message); 11 | } 12 | 13 | public static void LogWarning(string message) 14 | { 15 | Debug.LogWarning(message); 16 | } 17 | 18 | public static void LogInfo(string message) 19 | { 20 | Debug.Log(message); 21 | } 22 | 23 | public static void LogDebug(string message) 24 | { 25 | Debug.Log("NGDebug Info: " +message); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGLogger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a90c66999fd1f40789f8e551fbd049fd 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGMessageCodec.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Collections.Generic; 4 | namespace Netgo.Library 5 | { 6 | //https://blog.csdn.net/qq_29639547/article/details/76212128 7 | public class NGMessageCodec 8 | { 9 | public static byte[] Encode(byte[] data) 10 | { 11 | byte[] result = new byte[data.Length + 4]; 12 | 13 | MemoryStream ms = new MemoryStream(); 14 | //little end 15 | //https://stackoverflow.com/questions/1540251/binarywriter-endian-issue 16 | BinaryWriter br = new BinaryWriter(ms); 17 | br.Write(data.Length); 18 | br.Write(data); 19 | 20 | Buffer.BlockCopy(ms.ToArray(), 0, result, 0, (int)ms.Length); 21 | br.Close(); 22 | ms.Close(); 23 | return result; 24 | } 25 | 26 | public static byte[] Decode(ref List cache) 27 | { 28 | if (cache.Count < 4) 29 | { 30 | return null; 31 | } 32 | 33 | MemoryStream ms = new MemoryStream(cache.ToArray()); 34 | BinaryReader br = new BinaryReader(ms); 35 | UInt32 len = br.ReadUInt32(); 36 | if (len > ms.Length - ms.Position) 37 | { 38 | return null; 39 | } 40 | 41 | byte[] result = br.ReadBytes((int)len); 42 | cache.Clear(); 43 | cache.AddRange(br.ReadBytes((int)ms.Length - (int)ms.Position)); 44 | 45 | return result; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGMessageCodec.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c145aa1b76a1543a499bcb3ad9322d90 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGMessagePart.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Google.Protobuf.WellKnownTypes; 3 | using pb = global::Google.Protobuf; 4 | using UnityEngine; 5 | 6 | namespace Netgo.Library 7 | { 8 | public sealed partial class NGVector3 9 | { 10 | NGVector3(float x, float y, float z) 11 | { 12 | X = x; 13 | Y = y; 14 | Z = z; 15 | } 16 | /// 17 | /// Automatic conversion from NGVector3 to Vector3 18 | /// 19 | /// 20 | /// 21 | public static implicit operator Vector3(NGVector3 rValue) 22 | { 23 | return new Vector3(rValue.X, rValue.Y, rValue.Z); 24 | } 25 | 26 | /// 27 | /// Automatic conversion from Vector3 to NGVector3 28 | /// 29 | /// 30 | /// 31 | public static implicit operator NGVector3(Vector3 rValue) 32 | { 33 | return new NGVector3(rValue.x, rValue.y, rValue.z); 34 | } 35 | } 36 | 37 | public sealed partial class NGQuaternion 38 | { 39 | NGQuaternion(float x, float y, float z, float w) 40 | { 41 | X = x; 42 | Y = y; 43 | X = z; 44 | W = w; 45 | } 46 | /// 47 | /// Automatic conversion from NGQuaternion to Quaternion 48 | /// 49 | /// 50 | /// 51 | public static implicit operator Quaternion(NGQuaternion rValue) 52 | { 53 | return new Quaternion(rValue.X, rValue.Y, rValue.Z, rValue.W); 54 | } 55 | 56 | /// 57 | /// Automatic conversion from Quaternion to NGQuaternion 58 | /// 59 | /// 60 | /// 61 | public static implicit operator NGQuaternion(Quaternion rValue) 62 | { 63 | return new NGQuaternion(rValue.x, rValue.y, rValue.z, rValue.w); 64 | } 65 | 66 | } 67 | 68 | public sealed partial class NGColor 69 | { 70 | NGColor(float r, float g, float b, float a) 71 | { 72 | R = r; 73 | G = g; 74 | B = b; 75 | A = a; 76 | } 77 | /// 78 | /// Automatic conversion from NGQuaternion to Quaternion 79 | /// 80 | /// 81 | /// 82 | public static implicit operator Color(NGColor rValue) 83 | { 84 | return new Color(rValue.R, rValue.G, rValue.B, rValue.A); 85 | } 86 | 87 | /// 88 | /// Automatic conversion from Quaternion to NGQuaternion 89 | /// 90 | /// 91 | /// 92 | public static implicit operator NGColor(Color rValue) 93 | { 94 | return new NGColor(rValue.r, rValue.g, rValue.b, rValue.a); 95 | } 96 | 97 | } 98 | 99 | 100 | 101 | public sealed partial class NGAny 102 | { 103 | 104 | public NGAny(double val) 105 | { 106 | this.NgDouble = val; 107 | } 108 | public NGAny(float val) 109 | { 110 | this.NgFloat = val; 111 | } 112 | public NGAny(Int32 val) 113 | { 114 | this.NgInt32 = val; 115 | } 116 | public NGAny(Int64 val) 117 | { 118 | this.NgInt64 = val; 119 | } 120 | 121 | public NGAny(UInt32 val) 122 | { 123 | this.NgUint32 = val; 124 | } 125 | public NGAny(UInt64 val) 126 | { 127 | this.NgUint64 = val; 128 | } 129 | 130 | public NGAny(bool val) 131 | { 132 | this.NgBool = val; 133 | } 134 | public NGAny(string val) 135 | { 136 | this.NgString = val; 137 | } 138 | public NGAny(pb::ByteString val) 139 | { 140 | this.NgBytes = val; 141 | } 142 | public NGAny(Vector3 val) 143 | { 144 | this.NgVector3 = val; 145 | } 146 | 147 | public NGAny(Quaternion val) 148 | { 149 | this.NgQuaternion = val; 150 | } 151 | 152 | public NGAny(Color color) 153 | { 154 | this.NgColor = color; 155 | } 156 | 157 | 158 | public static implicit operator NGAny(double obj) 159 | { 160 | return new NGAny(obj); 161 | } 162 | public static implicit operator double?(NGAny obj) 163 | { 164 | if (obj.NgTypeCase != NgTypeOneofCase.NgDouble) 165 | { 166 | NGLogger.LogError("NGAny cannot be casted to double."); 167 | return null; 168 | } 169 | return obj.NgDouble; 170 | } 171 | public static implicit operator NGAny(float obj) 172 | { 173 | return new NGAny(obj); 174 | } 175 | 176 | public static implicit operator float?(NGAny obj) 177 | { 178 | if (obj.NgTypeCase != NgTypeOneofCase.NgFloat) 179 | { 180 | NGLogger.LogError("NGAny cannot be casted to float."); 181 | return null; 182 | } 183 | return obj.NgFloat; 184 | } 185 | public static implicit operator NGAny(Int32 obj) 186 | { 187 | return new NGAny(obj); 188 | } 189 | public static implicit operator Int32?(NGAny obj) 190 | { 191 | if (obj.NgTypeCase != NgTypeOneofCase.NgInt32) 192 | { 193 | NGLogger.LogError("NGAny cannot be casted to Int32."); 194 | return null; 195 | } 196 | return obj.NgInt32; 197 | } 198 | 199 | public static implicit operator NGAny(Int64 obj) 200 | { 201 | return new NGAny(obj); 202 | } 203 | public static implicit operator Int64?(NGAny obj) 204 | { 205 | if (obj.NgTypeCase != NgTypeOneofCase.NgInt64) 206 | { 207 | NGLogger.LogError("NGAny cannot be casted to Int64."); 208 | return null; 209 | } 210 | return obj.NgInt64; 211 | } 212 | 213 | public static implicit operator NGAny(UInt32 obj) 214 | { 215 | return new NGAny(obj); 216 | } 217 | 218 | 219 | public static implicit operator UInt32?(NGAny obj) 220 | { 221 | if (obj.NgTypeCase != NgTypeOneofCase.NgUint32) 222 | { 223 | NGLogger.LogError("NGAny cannot be casted to UInt32."); 224 | return null; 225 | } 226 | return obj.NgUint32; 227 | } 228 | public static implicit operator NGAny(UInt64 obj) 229 | { 230 | return new NGAny(obj); 231 | } 232 | 233 | public static implicit operator UInt64?(NGAny obj) 234 | { 235 | if (obj.NgTypeCase != NgTypeOneofCase.NgUint64) 236 | { 237 | NGLogger.LogError("NGAny cannot be casted to UInt64."); 238 | return null; 239 | } 240 | return obj.NgUint64; 241 | } 242 | 243 | public static implicit operator NGAny(bool obj) 244 | { 245 | return new NGAny(obj); 246 | } 247 | 248 | public static implicit operator bool?(NGAny obj) 249 | { 250 | if (obj.NgTypeCase != NgTypeOneofCase.NgBool) 251 | { 252 | NGLogger.LogError("NGAny cannot be casted to bool."); 253 | return null; 254 | } 255 | return obj.NgBool; 256 | } 257 | 258 | public static implicit operator NGAny(string obj) 259 | { 260 | return new NGAny(obj); 261 | } 262 | 263 | 264 | public static implicit operator string(NGAny obj) 265 | { 266 | if (obj.NgTypeCase != NgTypeOneofCase.NgString) 267 | { 268 | NGLogger.LogError("NGAny cannot be casted to string."); 269 | return null; 270 | } 271 | return obj.NgString; 272 | } 273 | 274 | 275 | public static implicit operator NGAny(pb::ByteString obj) 276 | { 277 | return new NGAny(obj); 278 | } 279 | 280 | 281 | public static implicit operator pb::ByteString(NGAny obj) 282 | { 283 | if (obj.NgTypeCase != NgTypeOneofCase.NgBytes) 284 | { 285 | NGLogger.LogError("NGAny cannot be casted to ByteString."); 286 | return null; 287 | } 288 | return obj.NgBytes; 289 | } 290 | 291 | public static implicit operator NGAny(Vector3 obj) 292 | { 293 | return new NGAny(obj); 294 | } 295 | 296 | public static implicit operator Vector3?(NGAny obj) 297 | { 298 | if (obj.NgTypeCase != NgTypeOneofCase.NgVector3) 299 | { 300 | NGLogger.LogError("NGAny cannot be casted to Vector3."); 301 | return null; 302 | } 303 | return obj.NgVector3; 304 | } 305 | 306 | public static implicit operator NGAny(Quaternion obj) 307 | { 308 | return new NGAny(obj); 309 | } 310 | 311 | public static implicit operator Quaternion?(NGAny obj) 312 | { 313 | if (obj.NgTypeCase != NgTypeOneofCase.NgQuaternion) 314 | { 315 | NGLogger.LogError("NGAny cannot be casted to Quaternion."); 316 | return null; 317 | } 318 | return obj.NgQuaternion; 319 | } 320 | public static implicit operator NGAny(Color obj) 321 | { 322 | return new NGAny(obj); 323 | } 324 | 325 | public static implicit operator Color?(NGAny obj) 326 | { 327 | if (obj.NgTypeCase != NgTypeOneofCase.NgColor) 328 | { 329 | NGLogger.LogError("NGAny cannot be casted to Color."); 330 | return null; 331 | } 332 | return obj.NgColor; 333 | } 334 | 335 | // public static explicit operator NGAny(object obj) 336 | // { 337 | // if (obj is double) 338 | // { 339 | // return new NGAny((double)obj); 340 | // } 341 | // else if (obj is float) 342 | // { 343 | // return new NGAny((float)obj); 344 | // } 345 | // else if (obj is Int32) 346 | // { 347 | // return new NGAny((Int32)obj); 348 | // } 349 | // else if (obj is Int64) 350 | // { 351 | // return new NGAny((Int64)obj); 352 | // } 353 | // else if (obj is UInt32) 354 | // { 355 | // return new NGAny((UInt32)obj); 356 | // } 357 | // else if (obj is UInt64) 358 | // { 359 | // return new NGAny((UInt64)obj); 360 | // } 361 | // else if (obj is bool) 362 | // { 363 | // return new NGAny((bool)obj); 364 | // } 365 | // else if (obj is string) 366 | // { 367 | // return new NGAny((string)obj); 368 | // } 369 | // else if (obj is pb::ByteString) 370 | // { 371 | // return new NGAny((pb::ByteString)obj); 372 | // } 373 | // else if (obj is Vector3) 374 | // { 375 | // return new NGAny((Vector3)obj); 376 | // } 377 | // else if (obj is Quaternion) 378 | // { 379 | // return new NGAny((Quaternion)obj); 380 | // } 381 | // else 382 | // { 383 | // NGLogger.LogError("The type" + obj.GetType() + " is not supported"); 384 | // return null; 385 | // } 386 | // } 387 | 388 | 389 | } 390 | 391 | 392 | } 393 | -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGMessagePart.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a475169fdcff54eb9a14c9c6c99773a2 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGProtobufConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Google.Protobuf.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace Netgo.Library 6 | { 7 | public class NGProtobufConverter 8 | { 9 | public static List RepeatedField2List(RepeatedField rf) 10 | { 11 | List rv = new List(); 12 | foreach(var val in rf) 13 | { 14 | rv.Add(val); 15 | } 16 | return rv; 17 | } 18 | 19 | public static T[] RepeatedField2Array(RepeatedField rf) 20 | { 21 | T[] rv = new T[rf.Count]; 22 | for (int idx = 0; idx < rf.Count; idx++) 23 | { 24 | rv[idx] = rf[idx]; 25 | } 26 | return rv; 27 | } 28 | 29 | public static RepeatedField Array2RepeatedField(T [] objs) 30 | { 31 | RepeatedField rv = new RepeatedField(); 32 | foreach(var value in objs) 33 | { 34 | rv.Add(value); 35 | } 36 | return rv; 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Assets/Netgo/Library/NGProtobufConverter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5edd54fde2df740bba33bf40ff03a1ca 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Library/NgMessage.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 892a916b4d1fe4fa4ab889c9adfa4bc5 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Network.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bb0ace1ad71024349a06c76b848733d7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGISocket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | namespace Netgo.Network 4 | { 5 | public interface NGISocket 6 | { 7 | void Connect(IPEndPoint endPoint); 8 | 9 | void Receive(); 10 | void OnReceiveResult(IAsyncResult result); 11 | 12 | void Send(byte[] data); 13 | void OnSendResult(IAsyncResult result); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGISocket.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 97af45d271f9d4a0f92c1300096b9488 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGMessageReceiver.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections; 3 | using System.IO; 4 | //https://stackoverflow.com/questions/2522376/how-to-choose-between-protobuf-csharp-port-and-protobuf-net 5 | using Google.Protobuf; 6 | using Netgo.Library; 7 | 8 | using Google.Protobuf.WellKnownTypes; 9 | using UnityEngine; 10 | using Netgo.Network; 11 | 12 | 13 | namespace Netgo.Network 14 | { 15 | 16 | public class NGMessageReceiver : MonoBehaviour 17 | { 18 | 19 | public List mReceiveCache; 20 | 21 | public delegate void NGMessageProcessor(byte [] data); 22 | public NGMessageProcessor MessageProcessor; 23 | 24 | public static NGMessageReceiver Instance; 25 | 26 | 27 | 28 | private void Awake() 29 | { 30 | DontDestroyOnLoad(this.gameObject); 31 | if(Instance == null) 32 | { 33 | Instance = this; 34 | } 35 | //mSocket = NGGameClient.mSocket; 36 | mReceiveCache = new List(); 37 | StartReceive(); 38 | } 39 | 40 | 41 | public void StartReceive() 42 | { 43 | NGNetwork.Socket.Receive(); 44 | } 45 | private void Update() 46 | { 47 | StartCoroutine(Process()); 48 | } 49 | 50 | public IEnumerator Process() 51 | { 52 | lock (NGNetwork.Socket.MBufferQueue) 53 | { 54 | // NGLogger.LogDebug("Lock BufferQueue"); 55 | while (NGNetwork.Socket.MBufferQueue.Count > 0) 56 | { 57 | //NGLogger.LogDebug("Proceess BufferQueue"); 58 | NGBuffer buffer = NGNetwork.Socket.MBufferQueue.Dequeue(); 59 | mReceiveCache.AddRange(buffer.Bytes); 60 | byte[] currBytes; 61 | while ((currBytes = NGMessageCodec.Decode(ref mReceiveCache)) != null) 62 | { 63 | //NGLogger.LogDebug("Decode message from BufferQueue"); 64 | //mReceiveCache.Clear(); 65 | //ProcessRecieveData(currBytes); 66 | MessageProcessor(currBytes); 67 | } 68 | } 69 | } 70 | 71 | yield return new WaitForSeconds(2); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGMessageReceiver.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da42744610f7e43c5b491772cf49bd14 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGNetwork.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace Netgo.Network 3 | { 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using UnityEngine; 7 | using System.Net.Sockets; 8 | using System.Net; 9 | using Netgo.Library; 10 | 11 | 12 | [RequireComponent(typeof(NGNetworkIncomingEvent))] 13 | public class NGNetwork : NGNetworkIncomingEvent 14 | { 15 | public string Address; 16 | public int Port; 17 | public ProtocolType Type; 18 | public static SocketStatus Status = SocketStatus.Disconnected; 19 | 20 | public static bool IsConnected { get { return Status == SocketStatus.Connected; } } 21 | 22 | public static NGNetwork Instance = null; 23 | 24 | public static NGSocket Socket; 25 | 26 | private void Awake() 27 | { 28 | 29 | if (Instance == null) 30 | { 31 | Instance = this; 32 | DontDestroyOnLoad(gameObject); 33 | } 34 | else if (Instance != this) 35 | { 36 | Destroy(gameObject); 37 | } 38 | 39 | 40 | if (Status != SocketStatus.Connected) 41 | { 42 | IPAddress address = IPAddress.Parse(Address); 43 | IPEndPoint serverAddress = new IPEndPoint(address, Port); 44 | Socket = new NGSocket(Type); 45 | Socket.Connect(serverAddress); 46 | 47 | } 48 | } 49 | public override void OnConnected() 50 | { 51 | Status = SocketStatus.Connected; 52 | NGLogger.LogDebug("On connected"); 53 | } 54 | 55 | private void OnDestroy() 56 | { 57 | if (Instance == this) 58 | { 59 | NGLogger.LogDebug("Socket is Closed."); 60 | Socket.Close(); 61 | } 62 | 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGNetwork.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6f431c2404e1346fa8eba2aa7de59801 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGNetworkIncomingEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | 4 | namespace Netgo.Network 5 | { 6 | public class NGNetworkEvent 7 | { 8 | public delegate void DelegateOnConnected(); 9 | public static DelegateOnConnected OnConnected; 10 | } 11 | public interface NGISocketStatusEvent 12 | { 13 | void OnConnected(); 14 | } 15 | public class NGNetworkIncomingEvent : MonoBehaviour, NGISocketStatusEvent 16 | { 17 | public virtual void OnConnected() { } 18 | public void OnEnable() 19 | { 20 | NGNetworkEvent.OnConnected += this.OnConnected; 21 | } 22 | 23 | public void OnDisable() 24 | { 25 | NGNetworkEvent.OnConnected -= this.OnConnected; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGNetworkIncomingEvent.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7f55dc00141ec46fa8548519c1d40f38 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGSocket.cs: -------------------------------------------------------------------------------- 1 | namespace Netgo.Network 2 | { 3 | 4 | using System.Net.Sockets; 5 | using System.Net; 6 | using System; 7 | using System.Threading; 8 | using UnityEngine; 9 | using System.Text; 10 | using System.Collections.Generic; 11 | 12 | 13 | using Netgo.Library; 14 | 15 | 16 | //// State object for receiving data from remote device. 17 | //public class StateObject 18 | //{ 19 | // // Client socket. 20 | // public Socket workSocket = null; 21 | // // Size of receive buffer. 22 | // public const int BufferSize = 256; 23 | // // Receive buffer. 24 | // public byte[] buffer = new byte[BufferSize]; 25 | // // Received data string. 26 | // public StringBuilder sb = new StringBuilder(); 27 | //} 28 | 29 | //https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-client-socket-example?view=netframework-4.8 30 | 31 | //https://blog.csdn.net/treepulse/article/details/53465137 32 | public class NGSocket : NGISocket 33 | { 34 | 35 | public enum OpCode 36 | { 37 | JoinLobby = 0, 38 | LeaveLobby = 1, 39 | JoinRoom = 2, 40 | LeaveRoom = 3, 41 | CreateRoom = 4, 42 | LaunchEvent = 5, 43 | SubscribeMsgChannels = 6, 44 | UnSubscribeMsgChannels = 7 45 | } 46 | 47 | 48 | private Socket mClientSocket; 49 | 50 | private static int mBufferSize = 1024; 51 | private byte[] mBuffer = new byte[mBufferSize]; 52 | 53 | private Queue mBufferQueue = new Queue(); 54 | 55 | private static ManualResetEvent connectDone = new ManualResetEvent(false); 56 | private static ManualResetEvent sendDone = new ManualResetEvent(false); 57 | private static ManualResetEvent receiveDone = new ManualResetEvent(false); 58 | 59 | private string receivestr; 60 | 61 | public Queue MBufferQueue { get => mBufferQueue; set => mBufferQueue = value; } 62 | 63 | public NGSocket(ProtocolType type) 64 | { 65 | mClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, type); 66 | 67 | } 68 | 69 | public void Connect(IPEndPoint serverIP) 70 | { 71 | mClientSocket.BeginConnect(serverIP, OnConnectResult, mClientSocket); 72 | } 73 | 74 | public void OnConnectResult(IAsyncResult result) 75 | { 76 | try 77 | { 78 | Socket client = (Socket)result.AsyncState; 79 | client.EndConnect(result); 80 | connectDone.Set(); 81 | 82 | } 83 | catch (Exception e) 84 | { 85 | Debug.Log(e.ToString()); 86 | } 87 | } 88 | 89 | public void Receive() 90 | { 91 | //StateObject state = new StateObject(); 92 | //state.workSocket = socket; 93 | mClientSocket.BeginReceive(mBuffer, 0, mBufferSize, 0, OnReceiveResult, mClientSocket); 94 | } 95 | public void OnReceiveResult(IAsyncResult result) 96 | { 97 | try 98 | { 99 | Socket socket = (Socket)result.AsyncState; 100 | int bytesRead = socket.EndReceive(result); 101 | 102 | //NGLogger.LogDebug("OnReceiveResult" + bytesRead); 103 | 104 | if (bytesRead > 0) 105 | { 106 | 107 | NGBuffer buffer = new NGBuffer(mBuffer, bytesRead); 108 | lock (mBufferQueue) 109 | { 110 | mBufferQueue.Enqueue(buffer); 111 | } 112 | 113 | socket.BeginReceive(mBuffer, 0, mBufferSize, 0, new AsyncCallback(OnReceiveResult), socket); 114 | } 115 | else 116 | { 117 | // All the data has arrived; put it in response. 118 | //if (state.sb.Length > 1) 119 | //{ 120 | // receivestr = state.sb.ToString(); 121 | //} 122 | // Signal that all bytes have been received. 123 | receiveDone.Set(); 124 | } 125 | } 126 | catch (Exception e) 127 | { 128 | Debug.Log(e.ToString()); 129 | 130 | } 131 | } 132 | 133 | public void Send(byte[] data) 134 | { 135 | // Begin sending the data to the remote device. 136 | mClientSocket.BeginSend(data, 0, data.Length, 0, new AsyncCallback(OnSendResult), mClientSocket); 137 | } 138 | 139 | public void OnSendResult(IAsyncResult result) 140 | { 141 | try 142 | { 143 | // Retrieve the socket from the state object. 144 | Socket socket = (Socket)result.AsyncState; 145 | 146 | // Complete sending the data to the remote device. 147 | int bytesSent = socket.EndSend(result); 148 | Console.WriteLine("Sent {0} bytes to server.", bytesSent); 149 | 150 | // Signal that all bytes have been sent. 151 | sendDone.Set(); 152 | } 153 | catch (Exception e) 154 | { 155 | Console.WriteLine(e.ToString()); 156 | } 157 | } 158 | 159 | public void Close() 160 | { 161 | mClientSocket.Close(); 162 | } 163 | 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGSocket.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a4277b8b51bd34681a3261df6d848f16 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGUDPSocket.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net.Sockets; 3 | using System.Net; 4 | using System.Collections.Generic; 5 | using Netgo.Library; 6 | using UnityEngine; 7 | namespace Netgo.Network 8 | { 9 | //https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-client-socket-example?view=netframework-4.8 10 | public class NGUDPSocket : NGISocket 11 | { 12 | UdpClient mUdpClient; 13 | 14 | private Queue mBufferQueue = new Queue(); 15 | 16 | public Queue MBufferQueue { get => mBufferQueue; set => mBufferQueue = value; } 17 | 18 | public void Connect(IPEndPoint endPoint) 19 | { 20 | mUdpClient.Connect(endPoint); 21 | } 22 | 23 | public void Receive() 24 | { 25 | mUdpClient.BeginReceive(new AsyncCallback(OnReceiveResult),mUdpClient); 26 | } 27 | 28 | public void OnReceiveResult(IAsyncResult result) 29 | { 30 | try 31 | { 32 | UdpClient client = (UdpClient)result.AsyncState; 33 | IPEndPoint point = new IPEndPoint(IPAddress.Any, 8000); 34 | 35 | byte [] bytesRead = client.EndReceive(result,ref point); 36 | if (bytesRead.Length > 0) 37 | { 38 | NGBuffer buffer = new NGBuffer(bytesRead, bytesRead.Length); 39 | lock (mBufferQueue) 40 | { 41 | mBufferQueue.Enqueue(buffer); 42 | } 43 | 44 | client.BeginReceive(new AsyncCallback(OnReceiveResult), mUdpClient); 45 | } 46 | else 47 | { 48 | // All the data has arrived; put it in response. 49 | //if (state.sb.Length > 1) 50 | //{ 51 | // receivestr = state.sb.ToString(); 52 | //} 53 | // Signal that all bytes have been received. 54 | //receiveDone.Set(); 55 | } 56 | } 57 | catch (Exception e) 58 | { 59 | Debug.Log(e.ToString()); 60 | 61 | } 62 | } 63 | 64 | 65 | public void Send(byte[] data) 66 | { 67 | mUdpClient.BeginSend(data, data.Length, new AsyncCallback(OnSendResult), mUdpClient); 68 | 69 | } 70 | 71 | public void OnSendResult(IAsyncResult result) 72 | { 73 | try 74 | { 75 | // Retrieve the socket from the state object. 76 | UdpClient client = (UdpClient)result.AsyncState; 77 | 78 | // Complete sending the data to the remote device. 79 | int bytesSent = client.EndSend(result); 80 | Console.WriteLine("Sent {0} bytes to server.", bytesSent); 81 | 82 | // Signal that all bytes have been sent. 83 | // sendDone.Set(); 84 | } 85 | catch (Exception e) 86 | { 87 | Console.WriteLine(e.ToString()); 88 | } 89 | } 90 | 91 | 92 | 93 | 94 | 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Assets/Netgo/Network/NGUDPSocket.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 99cad23cf19994d069713c35b410082e 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6b2c83ba3154476893e9e7ab5e48324 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Plugins/Google.Protobuf.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harlanc/netgo-unity-client/efcc2553ff3a2393b8669b88c1367f52ffca88bf/Assets/Plugins/Google.Protobuf.dll -------------------------------------------------------------------------------- /Assets/Plugins/Google.Protobuf.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0c830a7c0803f4b55bc6407d84c20390 3 | PluginImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | iconMap: {} 7 | executionOrder: {} 8 | defineConstraints: [] 9 | isPreloaded: 0 10 | isOverridable: 0 11 | isExplicitlyReferenced: 0 12 | validateReferences: 1 13 | platformData: 14 | - first: 15 | Any: 16 | second: 17 | enabled: 1 18 | settings: {} 19 | - first: 20 | Editor: Editor 21 | second: 22 | enabled: 0 23 | settings: 24 | DefaultValueInitialized: true 25 | - first: 26 | Windows Store Apps: WindowsStoreApps 27 | second: 28 | enabled: 0 29 | settings: 30 | CPU: AnyCPU 31 | userData: 32 | assetBundleName: 33 | assetBundleVariant: 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 netgo-framework 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # netgo-unity-client 2 | 3 | ## Introduction 4 | 5 | netgo-unity-client is a unity client SDK for [netgo](https://github.com/netgo-framework/netgo),it is easy to use and contains a demo on how to use it. 6 | 7 | ## Start the Demo 8 | 9 | ### Environment 10 | 11 | - Unity 2018.4.2f1 12 | - MacOS Catalina 13 | - Android Mobile Phone 14 | 15 | ### Build the APK for Android 16 | 17 | ##### Configure Network 18 | 19 | Open the **DemoLobbyScene** and configure the [netgo server](https://github.com/netgo-framework/netgo) IP address and port. 20 | 21 | ![](http://qiniu.harlanc.vip/12.24.2019_8:03:50.png) 22 | 23 | ##### Switch Platform 24 | 25 | Switch the Platform to Android. 26 | 27 | ![](http://qiniu.harlanc.vip/12.24.2019_7:46:29.png) 28 | 29 | ##### Build 30 | 31 | Click **Build** to generate the APK. 32 | 33 | ### Other Platforms 34 | 35 | netgo-unity-client can also be run on MacOS/IOS/Windows. 36 | 37 | 38 | ### Run and Operate 39 | 40 | ##### Menu 41 | 42 | You should install and run the APK on more than one clients.Look at the lobby scene menu: 43 | 44 | ![](http://qiniu.harlanc.vip/12.24.2019_9:41:23.png) 45 | 46 | 1. **Room Name :** Define a unique name for a Room. 47 | 2. **Room Capacity :** The count which one Room can hold. 48 | 3. **Join Or Create Room:** If the Room exists , then join the Room ,else create a new Room. 49 | 4. **Create Room:** Just create the Room. 50 | 5. **Join Room:** Just join the Room. 51 | 52 | ##### Communications 53 | 54 | When a client first join a room, a cube will be instantiated(Here we call **Mine Cube**).The **Mine Cube** will be cloned(Here we call **Clone Cube**) on other client when the other one join the same room.You can click the **Mine Cube** to change the colors,it can be synced by using **[RPC](https://github.com/netgo-framework/netgo-unity-client/tree/master/Assets/Netgo/Application/RPC)**: 55 | 56 | ![](https://github.com/netgo-framework/netgo-unity-client/blob/master/README/netgo-client-rpc.gif) 57 | 58 | And then we click **Move** button to let the two cubes move.We here use **[View Sync](https://github.com/netgo-framework/netgo-unity-client/tree/master/Assets/Netgo/Application/ViewSynchronizer)** to sync the positions and rotations for each other: 59 | 60 | ![](https://github.com/netgo-framework/netgo-unity-client/blob/master/README/netgo_client_readme_viewsync.gif) 61 | 62 | When you click the **Clone Cube**,we here use **[Custom Event](https://github.com/netgo-framework/netgo-unity-client/tree/master/Assets/Netgo/Application/CustomEvent)** to send a message to **Mine Cube**. 63 | 64 | For details you can review the revelant souce codes. 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /README/netgo-client-rpc.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harlanc/netgo-unity-client/efcc2553ff3a2393b8669b88c1367f52ffca88bf/README/netgo-client-rpc.gif -------------------------------------------------------------------------------- /README/netgo_client_readme_viewsync.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harlanc/netgo-unity-client/efcc2553ff3a2393b8669b88c1367f52ffca88bf/README/netgo_client_readme_viewsync.gif --------------------------------------------------------------------------------