public static void LaunchPlayerClient() { //Make sure the build exists if (!BuildExist()) { Debug.LogError("No build exists! Build one using `Tools -> Volt Unity Builder -> Volt Builder -> Build Player`"); return; } //Make sure the run client script still exists string buildDir = $"{GameBuilder.GetBuildDirectory()}Team-Capture-Quick/"; if (!File.Exists($"{buildDir}RunClient.ps1")) { Debug.LogError("The build is missing the 'RunClient.ps1' script!"); return; } Process.Start(new ProcessStartInfo { FileName = "pwsh", Arguments = $"{buildDir}RunClient.ps1", WorkingDirectory = buildDir }); }
/// <summary> /// Builds the game using Volt Builder's <see cref="GameBuilder.BuildGame"/> /// </summary> public static void StartVoltBuilder() { Debug.Log("Build game started..."); System.Console.WriteLine("Build game started..."); ParseCommandLineArguments(out Dictionary <string, string> arguments); if (!arguments.ContainsKey("buildTarget")) { EditorApplication.Exit(-1); } bool currentZipBuild = false; if (SettingsManager.Instance.ContainsKey <bool>(ZipBuildKey)) { currentZipBuild = SettingsManager.Instance.Get <bool>(ZipBuildKey); } SettingsManager.Instance.Set(ZipBuildKey, true); BuildTarget target = (BuildTarget)Enum.Parse(typeof(BuildTarget), arguments["buildTarget"]); string buildDir = $"{GameBuilder.GetBuildDirectory()}{target}-DevOpsBuild/{PlayerSettings.productName}"; System.Console.WriteLine($"Building TC for {target} platform to {buildDir}"); GameBuildOptions options = new GameBuildOptions(buildDir, target, BuildActions.GetBuildActions()); AddressablesBuilder.BuildAddressables(); GameBuilder.BuildGame(options); SettingsManager.Instance.Set(ZipBuildKey, currentZipBuild); }
/// <summary> /// Creates a new server process /// </summary> /// <param name="workingNetManager"></param> /// <param name="gameName"></param> /// <param name="sceneName"></param> /// <param name="maxPlayers"></param> /// <param name="userProvider"></param> /// <param name="shutOnDisconnect"></param> /// <param name="onServerStarted"></param> /// <param name="onServerFailedToStart"></param> internal static void CreateServerProcess(this NetworkManager workingNetManager, string gameName, string sceneName, int maxPlayers, UserProvider userProvider, bool shutOnDisconnect, Action onServerStarted, Action onServerFailedToStart = null) { #if UNITY_EDITOR string serverOnlinePath = $"{GameBuilder.GetBuildDirectory()}Team-Capture-Quick/{ServerOnlineFile}"; #else string serverOnlinePath = $"{Game.GetGameExecutePath()}/{ServerOnlineFile}"; #endif //Check to make sure the server online file doesn't already exist if (File.Exists(serverOnlinePath)) { onServerFailedToStart?.Invoke(); Logger.Error("A server is already running!"); return; } #if UNITY_EDITOR string tcApp = $"{GameBuilder.GetBuildDirectory()}Team-Capture-Quick/"; #else string tcApp = Game.GetGameExecutePath(); #endif #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN tcApp += "/Team-Capture.exe"; #else tcApp += "/Team-Capture"; #endif string tcArguments = $"-batchmode -nographics -gamename \"{gameName}\" -scene {sceneName} -maxplayers {maxPlayers} -auth-method {userProvider.ToString()}" + $"{(shutOnDisconnect ? " -closeserveronfirstclientdisconnect" : string.Empty)} -high"; #if UNITY_EDITOR_LINUX || UNITY_STANDALONE_LINUX ProcessHelper.LaunchLinuxTerminalAndLaunchProcess(tcApp, tcArguments); #else System.Diagnostics.Process tcProcess = new() { StartInfo = new System.Diagnostics.ProcessStartInfo { FileName = tcApp, Arguments = tcArguments, WorkingDirectory = Game.GetGameExecutePath() } }; tcProcess.Start(); #endif //We need to wait for the server online file, and to not cause the game to freeze we run it async WaitForServerOnlineFile(serverOnlinePath, onServerStarted, onServerFailedToStart).Forget(); }
private static string GetBuildDir() { string buildDir = $"{GameBuilder.GetBuildDirectory()}Team-Capture-Quick/"; if (!Directory.Exists(buildDir)) { return(null); } string fullPath = $"{buildDir}{ApplicationName}"; return(!File.Exists(fullPath) ? null : Path.GetFullPath(fullPath)); }
/// <summary> /// Starts the server and connects a player /// </summary> public void CreateGame() { #if UNITY_EDITOR //If we are running as the editor, then we to check to see if an existing build already exists and use that instead if (!Directory.Exists($"{GameBuilder.GetBuildDirectory()}Team-Capture-Quick/")) { Debug.LogError("There is no pre-existing build of Team-Capture! Build the game using VoltBuild."); return; } #endif //Make sure the game name isn't white space or null if (string.IsNullOrWhiteSpace(gameNameText.text)) { Logger.Error("Game name input is white space or null!"); gameNameImage.color = errorColor; return; } //Make sure the max players input is actually a number if (int.TryParse(maxPlayersText.text, out int result)) { //Make sure max players is greater then 1 if (result <= 1) { Logger.Error("Max players must be greater then one!"); maxPlayersImage.color = errorColor; return; } maxPlayers = result; } else //Display an error if is not a number { Logger.Error("Max players input isn't just an int!"); maxPlayersImage.color = errorColor; return; } if (netManager.isNetworkActive) { StartCoroutine(QuitExistingGame(CreateServerProcess)); return; } CreateServerProcess(); }
private static bool BuildExist() { string buildDir = $"{GameBuilder.GetBuildDirectory()}Team-Capture-Quick/"; if (!Directory.Exists(buildDir)) { return(false); } #if UNITY_EDITOR_WIN string applicationName = "Team-Capture.exe"; #else string applicationName = "Team-Capture"; #endif return(File.Exists($"{buildDir}{applicationName}")); }
/// <summary> /// Builds the game using Volt Builder's <see cref="GameBuilder.BuildGame"/> /// </summary> public static void StartVoltBuilder() { System.Console.WriteLine("Build game started..."); ParseCommandLineArguments(out Dictionary <string, string> arguments); if (!arguments.ContainsKey("buildTarget")) { EditorApplication.Exit(-1); } BuildTarget target = (BuildTarget)Enum.Parse(typeof(BuildTarget), arguments["buildTarget"]); string buildDir = $"{GameBuilder.GetBuildDirectory()}{target}-DevOpsBuild/{PlayerSettings.productName}"; System.Console.WriteLine($"Building TC for {target} platform to {buildDir}"); GameBuilder.BuildGame(buildDir, target); }
private static void OnDraw() { EditorGUILayout.BeginVertical(GUIStyles.DropdownContentStyle); Color defaultGUIBackgroundColor = GUI.backgroundColor; GUILayout.Label("Quick Start", GUIStyles.DropdownHeaderStyle); string tcFolder = $"{GameBuilder.GetBuildDirectory()}/Team-Capture-Quick/"; #if UNITY_EDITOR_WIN const string appName = "Team-Capture.exe"; #else const string appName = "Team-Capture"; #endif string tcFullPath = $"{tcFolder}{appName}"; if (!File.Exists(tcFullPath)) { EditorGUILayout.HelpBox("You need to build Team-Capture first before being able to use quick start!", MessageType.Error); } else { //Get all TC scenes IReadOnlyList <TCScene> scenes = TCScenesManager.GetAllOnlineScenes(); EditorGUILayout.BeginHorizontal(); { GUI.backgroundColor = Color.green; if (GUILayout.Button("Start")) { //Start each process for (int i = 0; i < quickstartData.entries.Count; i++) { QuickStartEntry entry = quickstartData.entries[i]; //Build arguments string arguments = $"-scene {scenes[quickstartData.selectedSceneIndex].SceneFileName} -auth-method {quickstartData.authMode.ToString()} "; if (entry.server) { arguments += "-batchmode -nographics "; } arguments += entry.additionalArguments; #if UNITY_EDITOR_LINUX if (entry.server) { ProcessHelper.LaunchLinuxTerminalAndLaunchProcess(tcFullPath, arguments); continue; } #endif //Setup and start the process Process newProcess = new Process { StartInfo = new ProcessStartInfo(tcFullPath, arguments) }; newProcess.Start(); StartedProcesses.Add(newProcess); Thread.Sleep(200); } Debug.Log(quickstartData.entries.Count > 1 ? $"Started {quickstartData.entries.Count} processes..." : "Started 1 process..."); } GUI.backgroundColor = defaultGUIBackgroundColor; GUI.backgroundColor = Color.red; if (GUILayout.Button("Stop All")) { //Kill each started process for (int i = 0; i < StartedProcesses.Count; i++) { Process process = StartedProcesses[i]; if (process.HasExited) { continue; } process.Kill(); } StartedProcesses.Clear(); Debug.Log("Stopped processes."); } GUI.backgroundColor = defaultGUIBackgroundColor; } EditorGUILayout.EndHorizontal(); //Make sure there are online scenes if (scenes.Count == 0) { EditorGUILayout.HelpBox("There are no available scenes!", MessageType.Error); } else { //Check that all scenes still exist if (quickstartData.selectedSceneIndex > scenes.Count) { quickstartData.selectedSceneIndex = 0; } //Display the scenes in a popup (aka a dropdown) string[] names = scenes.Select(scene => scene.SceneFileName).ToArray(); quickstartData.selectedSceneIndex = EditorGUILayout.Popup("Scene", quickstartData.selectedSceneIndex, names); } quickstartData.authMode = (UserProvider)EditorGUILayout.EnumPopup("Auth-Mode", quickstartData.authMode); GUILayout.Space(10f); GUILayout.Label("Processes", GUIStyles.DropdownHeaderStyle); if (quickstartData.entries.Count == 0) { EditorGUILayout.HelpBox("There are no processes!", MessageType.Error); } else { for (int i = 0; i < quickstartData.entries.Count; i++) { QuickStartEntry entry = quickstartData.entries[i]; GUILayout.BeginVertical(); { GUILayout.BeginHorizontal(); { GUILayout.Space(10); entry.server = EditorGUILayout.Toggle("Server?", entry.server); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); { GUILayout.Space(10); entry.additionalArguments = EditorGUILayout.TextField("Additional Arguments", entry.additionalArguments); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); { GUILayout.Space(10); if (GUILayout.Button("Remove", new GUIStyle(EditorStyles.miniButtonMid))) { quickstartData.entries.RemoveAt(i); } } GUILayout.EndHorizontal(); GUILayout.Space(8f); } GUILayout.EndVertical(); } } if (GUILayout.Button("Add Process")) { quickstartData.entries.Add(new QuickStartEntry { additionalArguments = string.Empty }); } if (EditorGUI.EndChangeCheck()) { string json = JsonUtility.ToJson(quickstartData); EditorPrefs.SetString(QuickStartDataKey, json); } } EditorGUILayout.EndVertical(); }