public void StartMachine(ICoroutineScheduler scheduler, DependencyContainer globalDependencies) { #region Networking var gameSettings = _gameSettingsProvider.ActiveSettings; var networking = GameObject.Find("Networking"); var lidgrenTransporter = networking.GetComponentInChildren <LidgrenNetworkTransporter>(); var networkMessageSender = networking.GetComponentInChildren <QueueingMessageSender>(); networkMessageSender.Transporter = lidgrenTransporter; var connectionIdPool = new ConnectionIdPool(maxConnectionIds: 64); //var connectionManager = new DefaultConnectionManager(lidgrenTransporter, connectionIdPool); var natFacilitatorEndpoint = Ipv4Endpoint.Parse(gameSettings.Other.NatFacilitatorEndpoint).ToIpEndPoint(); var natFacilitatorConnection = new LidgrenNatFacilitatorConnection(natFacilitatorEndpoint, lidgrenTransporter); var natPunchClient = new LidgrenNatPunchClient(scheduler, natFacilitatorConnection); var connectionAttemptTimeout = gameSettings.Other.ConnectionAttemptTimeout; var natPunchConnectionManager = new LidgrenPunchThroughFacilitator(lidgrenTransporter, scheduler, natPunchClient, connectionAttemptTimeout, connectionIdPool); lidgrenTransporter.ConnectionIdPool = connectionIdPool; var latencyInfo = new LatencyInfo(connectionIdPool.MaxConnectionIds); var groupRouterConfig = ConnectionGroups.RouterConfig; var networkSystems = NetworkSystem.Create( lidgrenTransporter, lidgrenTransporter, groupRouterConfig, ConnectionGroups.Default, ReplicationObjects.Factories, networkMessageSender, natPunchConnectionManager, latencyInfo, globalDependencies); var voloServer = networking.GetComponentInChildren <VoloNetworkServer>(); voloServer.NetworkSystems = networkSystems; voloServer.NatFacilitatorConnection = natFacilitatorConnection; var voloClient = networking.GetComponentInChildren <VoloNetworkClient>(); voloClient.NetworkSystems = networkSystems; voloClient.LatencyInfo = latencyInfo; var activeNetwork = new ActiveNetwork(networkSystems, voloServer, voloClient, scheduler); _playingData.ActiveNetwork = activeNetwork; _mainMenuData.ActiveNetwork = activeNetwork; _serverBrowserData.ActiveNetwork = activeNetwork; /* * Create lean and mean main menu system that allows a player to choose between single and multiplayer * * Notes: * - Keep as much logic that is generic to both single and multiplayer generic. Don't make a special code path * for singleplayer unless it is a feature that is only available in singleplayer. * - Options menu should be as game independent as possible, not relying on a specific singleplayer state for example. * - State machine transitions should also become separate states such that we can handle them in a better, cleaner way * * * Case 1: Single player game * - Boot game, start singleplayer, fly for one round, quit game * - On boot: create instance of a network system * - Pass network system into the state machine * - When going into the playing state, spawn/despawn/respawn pilot through replicator * * Case 2: Multiplayer game - server * - Boot game, main screen: choose to create multiplayer server, * - on boot create instance of network system * - when in starting multiplayer server state open transporter * - when a spawnpoint is selected replicate the player * - separate state machine for multiplayer logic * * Case 3: Multiplayer game - client * - Boot game, main screen: choose to join a multiplayer server * - server list: allow client to join a game, show if join/connect is in progress, allow for cancellation * - when a spawnpoint is selected request a spawn to the server */ #endregion _machine = new StateMachine <VoloStateMachine>(this, scheduler); _machine.AddState(States.NewsFlash, new NewsFlash(_machine, _newsFlashData)) .Permit(States.TitleScreen); _machine.AddState(States.TitleScreen, new TitleScreen(_machine, _titleScreenData)) .PermitChild(States.Frozen) .Permit(States.MainMenu); _machine.AddState(States.MainMenu, new MainMenu(_machine, _mainMenuData)) .PermitChild(States.Frozen) .Permit(States.TitleScreen) .Permit(States.ServerBrowser) .Permit(States.SpawnScreen); _machine.AddState(States.ServerBrowser, new ServerBrowser(_machine, _serverBrowserData)) .PermitChild(States.Frozen) .Permit(States.MainMenu) .Permit(States.SpawnScreen); _machine.AddState(States.SpawnScreen, new SpawnScreen(_machine, _spawnScreenData)) .PermitChild(States.Frozen) .PermitChild(States.OptionsMenu) .Permit(States.MainMenu) .Permit(States.Playing); _machine.AddState(States.Playing, new Playing(_machine, _playingData, _flyWingsuitData, _flyParachuteData, _spectatorModeData)) .PermitChild(States.Frozen) .PermitChild(States.OptionsMenu) .Permit(States.SpawnScreen); _machine.AddState(States.OptionsMenu, new OptionsMenuState(_machine, _optionsMenuData)) .PermitChild(States.Frozen) .Permit(States.SpawnScreen) .Permit(States.MainMenu); _machine.AddState(States.Frozen, new Frozen(_machine, _frozenData)); _machine.Transition(States.NewsFlash); }
private void OnGUI() { GUILayout.BeginVertical(); { GUILayout.Label("Status: " + _state); switch (_state) { case GameState.Disconnected: // _endpoint = GUILayout.TextField(_endpoint); // if (GUILayout.Button("Connect")) { // StartClient(); // } GUILayout.BeginHorizontal(); GUILayout.Label("Host"); _hostEndpoint = GUILayout.TextField(_hostEndpoint, GUILayout.Width(150)); if (GUILayout.Button("Connect")) { StartClient(Ipv4Endpoint.Parse(_hostEndpoint).ToIpEndPoint()); } GUILayout.EndHorizontal(); GUI.color = Color.white; GUILayout.BeginHorizontal(); GUILayout.Label("Host", GUILayout.Width(200)); GUILayout.Label("Endpoint", GUILayout.Width(150)); GUILayout.Label("Distance", GUILayout.Width(100)); GUILayout.Label("Country", GUILayout.Width(100)); GUILayout.Label("Version", GUILayout.Width(50)); GUILayout.EndHorizontal(); _hostListScrollPosition = GUILayout.BeginScrollView( _hostListScrollPosition, GUILayout.MaxHeight(400)); if (_availableHosts != null) { for (int i = 0; i < _availableHosts.Count || i >= 40; i++) { var hostInfo = _availableHosts[i]; GUI.color = Color.white; GUILayout.BeginHorizontal(); GUILayout.Label(hostInfo.Name, GUILayout.Width(200)); GUILayout.Label(hostInfo.PeerInfo.External.ToString(), GUILayout.Width(150)); GUILayout.Label(Mathf.RoundToInt((float)hostInfo.DistanceInKm) + " km", GUILayout.Width(100)); GUILayout.Label(hostInfo.Country, GUILayout.Width(100)); GUILayout.Label("v" + hostInfo.Version, GUILayout.Width(50)); GUI.color = Color.white; if (GUILayout.Button("Connect")) { StartClient(hostInfo.PeerInfo.External); } GUILayout.EndHorizontal(); } } GUILayout.EndScrollView(); GUI.color = Color.white; GUI.enabled = !_isHostListRefreshing; if (GUILayout.Button("Refresh host list")) { _isHostListRefreshing = true; const bool hideFull = false; const int limit = 100; _masterServerClient.Client.ListHosts( hideFull, limit, (statusCode, hosts) => { if (statusCode == HttpStatusCode.OK) { _availableHosts.Clear(); for (int i = 0; i < hosts.Count; i++) { var host = hosts[i]; _availableHosts.Add(host); } } _isHostListRefreshing = false; }); } GUI.enabled = true; GUILayout.BeginHorizontal(); _hostName = GUILayout.TextField(_hostName, maxLength: 100); GUILayout.Label("Port: "); _port = GUILayout.TextField(_port, maxLength: 20); if (GUILayout.Button("Host")) { var port = Convert.ToInt32(_port); StartListeningServer(_hostName, port); } GUILayout.EndHorizontal(); // if (GUILayout.Button("Host Listening Server")) { // StartListeningServer(); // } break; case GameState.Connecting: // Todo: cancel break; case GameState.Client: //GUILayout.Label("Latency: " + Mathd.ToMillis(_client.RoundtripTime * 0.5)); if (GUILayout.Button("Disconnect")) { StopClient(); } // GUILayout.Label("Game Clock: " + _synchedGameClock.CurrentTime); // GUILayout.Label("Fixed Clock: " + _syncedFixedClock.CurrentTime); // var packetsReceived = _client.UpdatePlayerPacketsReceived; // if (packetsReceived != null) { // for (int i = packetsReceived.Count - 1; i >= 0; i--) { // var packetTimestamp = packetsReceived[i]; // if (packetTimestamp < _localRealtimeClock.CurrentTime - 10f) { // break; // } // // var graphSize = new Vector2(100, 50); // var graphPosition = new Vector2(Screen.width - graphSize.x, Screen.height - graphSize.y); // GUI.color = Color.black; // _graphStyle.fontSize = 30; // var distanceFromOrigin = (int)Math.Round((_localRealtimeClock.CurrentTime - packetTimestamp) * 50.0); // GUI.Label( // new Rect(new Vector2((Screen.width - 50) - distanceFromOrigin, graphPosition.y), graphSize), // "|", // _graphStyle); // } // } break; case GameState.ListeningServer: if (GUILayout.Button("Disconnect")) { StopListeningServer(); } break; default: throw new ArgumentOutOfRangeException(); } } GUILayout.EndVertical(); GUI.color = Color.black; GUI.Label(new Rect(Screen.width - 40, 10, 40, 50), "v" + _versionInfo.VersionNumber); }