private static void TagsDialog(SimulatedVRCPlayer player) { Dictionary <string, string> tags = player.GetRawTags(); if (tags.Count > 0) { SimpleGUI.IndentWithHeader( () => GUILayout.Label("Tags: "), () => { foreach (string key in new List <string>(tags.Keys)) { GUILayout.BeginHorizontal(); tags[key] = EditorGUILayout.TextField(key, tags[key]); SimpleGUI.ActionButton("X", () => tags.Remove(key), GUILayout.MaxWidth(30)); GUILayout.EndHorizontal(); } } ); } GUILayout.BeginHorizontal(); string tagName = player.SetMetadata <string>("tagName", oldName => EditorGUILayout.TextField(oldName)); string tagValue = player.SetMetadata <string>("tagValue", oldName => EditorGUILayout.TextField(oldName)); SimpleGUI.ActionButton("Add tag", () => tags[tagName] = tagValue); GUILayout.EndHorizontal(); }
public void PrintCharacterSummary(int tick) { SimpleGUI.SetCursorPosition(0, _characterIndex); Console.WriteLine(Dead ? $"{Name} has died. " : $"{Name} at ({X},{Y}) has {HitPoints} hit points left"); }
private static bool DrawPlayerTemplateWithRemoveButton(PlayerTemplate playerTemplate, bool withRemoveButton) { EditorGUI.indentLevel++; playerTemplate.playerName = EditorGUILayout.TextField("Name", playerTemplate.playerName); SimpleGUI.DrawFoldout(playerTemplate, "More settings", () => { playerTemplate.avatarPrefab = SimpleGUI.ObjectField("Custom avatar", playerTemplate.avatarPrefab, false); playerTemplate.spawnPoint = SimpleGUI.ObjectField("Custom spawn point", playerTemplate.spawnPoint, true); playerTemplate.customId = EditorGUILayout.IntField("Custom id", playerTemplate.customId); }); GUILayout.BeginHorizontal(); GUILayout.Label("Has Vr"); playerTemplate.hasVr = EditorGUILayout.Toggle(playerTemplate.hasVr); GUILayout.Label("Join on start"); playerTemplate.joinByDefault = EditorGUILayout.Toggle(playerTemplate.joinByDefault); bool remove = false; if (withRemoveButton) { remove = GUILayout.Button("Remove"); } GUILayout.EndHorizontal(); EditorGUI.indentLevel--; return(remove); }
public static void DrawActiveRuntimePlayer(VRCEmulator emulator, SimulatedVRCPlayer player) { DrawRuntimePlayer(player); GUILayout.BeginHorizontal(); if (emulator.GetAmountOfPlayers() > 1) { SimpleGUI.ActionButton("Disconnect", () => emulator.RemovePlayer(player)); } if (!player.IsUsingVR()) { SimpleGUI.ActionButton("Make VR", player.PromoteToVRUser); } else { SimpleGUI.ActionButton("Make Desktop", player.DemoteToDesktopUser); } SimpleGUI.ActionButton("Make Master", () => emulator.MakeMaster(player)); SimpleGUI.ActionButton("Make Local", () => emulator.MakeLocal(player)); GUILayout.EndHorizontal(); SimpleGUI.DrawFoldout(player, "More settings", () => { AvatarChangeDialog(player); TagsDialog(player); }); }
private void DrawClientSection() { DrawClientSettingsList(_settings.clients); SimpleGUI.SectionSpacing(); if (SimpleGUI.ErrorBox(_settings.WorldId == null, "Can't start clients, missing WorldID")) { return; } if (SimpleGUI.ErrorBox(_settings.userId == null, "Can't find user id, please log in SDK.")) { return; } if (SimpleGUI.ErrorBox(!_settings.IsGamePathValid(), "Can't find game executable")) { return; } if (!_localTesting) { _keepInstance = EditorGUILayout.Toggle("Keep current instance ID", _keepInstance); } _localTesting = EditorGUILayout.Toggle("Use local testing", _localTesting); _clientsManager.InstanceId = EditorGUILayout.TextField(_clientsManager.InstanceId); GUILayout.BeginHorizontal(); string startButtonText = _localTesting ? "Start last version (no build)" : "Start"; SimpleGUI.ActionButton(startButtonText, () => _clientsManager.StartClients(false, _keepInstance, _localTesting, _keepInstanceForce)); if (ClientProcessesManager.IsAnyRunning()) { SimpleGUI.ActionButton("Restart", () => _clientsManager.StartClients(true, _keepInstance, _localTesting, _keepInstanceForce)); } GUILayout.EndHorizontal(); if (!Application.isPlaying) { if (_localTesting) { SimpleGUI.ActionButton("Build & Start", BuildAndTest); } else { if (SimpleGUI.ErrorBox(APIUser.CurrentUser == null || !VRC_SdkBuilder.VerifyCredentials(), "Can't find user for auto publish, please log in SDK.")) { return; } SimpleGUI.ActionButton("Build & Auto Publish & Start", PublishAndTest); } } }
public void ReceiveSpellDamage(string description, int index, double points) { if (_hitPoints > 0) { _hitPoints = _hitPoints - points; } SimpleGUI.SetCursorPosition(index, _characterIndex); Console.WriteLine($" {Name} received {points} damage from the spell {description}"); }
private static void AvatarChangeDialog(SimulatedVRCPlayer player) { GameObject avatar = player.SetMetadata <GameObject>("avatar", oldValue => SimpleGUI.ObjectField("Avatar", oldValue, false)); if (avatar != null) { SimpleGUI.ActionButton("Change Avatar", () => player.ChangeAvatar(avatar)); } }
private bool DrawClientSettings(ClientSettings settings, string buttonAction) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("Name", GUILayout.Width(35)); settings.name = EditorGUILayout.TextField(settings.name, GUILayout.Width(100), GUILayout.ExpandWidth(true)); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("Profile", GUILayout.Width(45)); settings.profile = EditorGUILayout.IntField(settings.profile, GUILayout.Width(20)); if (_localTesting) { GUILayout.Label("Num of", GUILayout.Width(45)); settings.instances = EditorGUILayout.IntField(settings.instances, GUILayout.Width(20)); } GUILayout.Label("Enabled", GUILayout.Width(55)); settings.enabled = EditorGUILayout.Toggle(settings.enabled, GUILayout.Width(15)); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); GUILayout.Label("VR", GUILayout.Width(20)); settings.vr = EditorGUILayout.Toggle(settings.vr, GUILayout.Width(15)); bool isRunning = ClientProcessesManager.IsAnyRunning(settings.profile); if (isRunning) { SimpleGUI.ActionButton("Stop All", () => ClientProcessesManager.KillProfile(settings.profile), GUILayout.Width(65)); SimpleGUI.ActionButton("Restart All", () => { ClientProcessesManager.KillProfile(settings.profile); _clientsManager.StartClients(_keepInstance, _keepInstanceForce, _localTesting, settings); }, GUILayout.Width(90)); } if (_localTesting || !isRunning) { SimpleGUI.ActionButton("Start One", () => _clientsManager.StartClients(_keepInstance, _keepInstanceForce, _localTesting, settings.WithInstances(1)), GUILayout.Width(80)); } bool actionButton = GUILayout.Button(buttonAction, GUILayout.Width(70)); EditorGUILayout.EndHorizontal(); return(actionButton); }
private void DrawAddPlayerBox() { if (_currentlyEdited == null || (_currentlyEdited.playerName == "" && _currentlyEdited.customId == 0)) { _currentlyEdited = PlayerTemplate.CreateNewPlayer(true); } PlayerTemplateEditor.DrawPlayerTemplate(_currentlyEdited); SimpleGUI.ActionButton("Add player", () => { _controller.Emulator.SpawnPlayer(GotoUdonSettings.Instance, _currentlyEdited); _currentlyEdited = PlayerTemplate.CreateNewPlayer(true); }); }
public void AddSpellCast(string shortName, int x, int y, int time) { Spell sp = SpellBook.LookupSpell(shortName); if (sp != null) { SimpleGUI.SetCursorForSpellCast(_spellCasts.Count); Console.WriteLine($"Cast {sp.Description} at ({x},{y}) @{time}"); SpellCast sc = new SpellCast(sp, x, y, time, _spellCasts.Count + 1); _gameWorld.Clock.Tick += sc.OnTick; _spellCasts.Add(sc); } }
private void DrawPlayersEditor() { GotoUdonSettings settings = _controller.Settings; if (SimpleGUI.WarningBox(!settings.enableSimulation, "Simulation is disabled")) { return; } VRCEmulator emulator = _controller.Emulator; if (SimpleGUI.InfoBox(!VRCEmulator.IsReady, "Waiting for emulation to begin...")) { return; } SimpleGUI.ErrorBox(emulator.GetAmountOfPlayers() == 0, "Emulator should not be started without at least one player!"); SimpleGUI.OptionSpacing(); GUILayout.Label("Global settings"); emulator.IsNetworkSettled = GUILayout.Toggle(emulator.IsNetworkSettled, "Is network settled"); GUILayout.Label("Spawned players: "); SimpleGUI.OptionSpacing(); foreach (SimulatedVRCPlayer runtimePlayer in _controller.RuntimePlayers) { if (!runtimePlayer.gameObject.activeSelf) { continue; } SimulatedPlayerEditor.DrawActiveRuntimePlayer(emulator, runtimePlayer); SimpleGUI.OptionSpacing(); } SimpleGUI.SectionSpacing(); GUILayout.Label("Available players: "); SimpleGUI.OptionSpacing(); foreach (SimulatedVRCPlayer runtimePlayer in _controller.RuntimePlayers) { if (runtimePlayer.gameObject.activeSelf) { continue; } SimulatedPlayerEditor.DrawAvailableRuntimePlayer(emulator, runtimePlayer); SimpleGUI.OptionSpacing(); } DrawAddPlayerBox(); }
private void DrawClientSettingsList(List <ClientSettings> allClients) { ClientSettings removed = null; int maxProfile = 10; foreach (ClientSettings clientSettings in allClients) { if (clientSettings.profile > maxProfile) { maxProfile = clientSettings.profile; } bool beforeVr = clientSettings.vr; if (DrawClientSettings(clientSettings, "Remove")) { removed = clientSettings; } if (!beforeVr && clientSettings.vr) { allClients.ForEach(client => { if (client != clientSettings) { client.vr = false; } }); } SimpleGUI.OptionSpacing(); } if (removed != null) { allClients.Remove(removed); } SimpleGUI.ActionButton("Add client", () => { allClients.Add(new ClientSettings() { name = "", profile = maxProfile + 1, instances = 1, enabled = true }); }); }
private void OnGUI() { #if GOTOUDON_DEV ReleaseHelper.DrawReleaseHelper(); #endif #if GOTOUDON_SIMULATION_LEGACY UpdaterEditor.Instance.DrawVersionInformation(); ImplementationValidator.DrawValidationErrors(ImplementationValidator.ValidateEmulator()); SimpleGUI.WarningBox(true, "NETWORK AND VRCHAT PHYSICS ARE NOT SIMULATED, NETWORK RELATED SETTINGS ONLY AFFECT RETURNED VALUES IN SCRIPTS, DEFAULT UNITY PHYSICS APPLIES (might be improved later)"); _scroll = GUILayout.BeginScrollView(_scroll, GUIStyle.none); if (EditorApplication.isPlaying) { DrawPlayersEditor(); } else { DrawTemplatesEditor(); } #else _scroll = GUILayout.BeginScrollView(_scroll, GUIStyle.none); #endif if (GUILayout.Button( $"============ IMPORTANT ============\nFor emulation use CyanEmu instead: https://github.com/CyanLaser/CyanEmu", EditorStyles.helpBox)) { Application.OpenURL("https://github.com/CyanLaser/CyanEmu"); } if (SimpleGUI.DrawFoldout("Unsafe Simulation", "UNSAFE") && SimpleGUI.DrawFoldout("Unsafe Simulation", "VERY UNSAFE")) { if (!EditorApplication.isPlaying) { DrawGlobalOptions(GotoUdonSettings.Instance); } } SimpleGUI.DrawFooterInformation(); GUILayout.EndScrollView(); }
internal void DrawVersionInformation() { DrawSdkUpdateComponent(); string version = GotoUdonEditor.VERSION; string sdkVersion = GotoUdonEditor.CurrentSDKVersion; string recommendedSdkVersion = GotoUdonEditor.ImplementedSDKVersion; string versionString = sdkVersion == recommendedSdkVersion ? $"GotoUdon {version} for SDK {recommendedSdkVersion}" : $"GotoUdon {version} for SDK {recommendedSdkVersion}, running on SDK {sdkVersion}"; string githubUrl = "https://github.com/GotoFinal/GotoUdon/releases"; if (_updateCheckerLibraryResponse != null) { if (SimpleGUI.WarningBox(_updateCheckerLibraryResponse.IsError, _updateCheckerLibraryResponse.Error)) { if (GUILayout.Button($"{versionString}. Click to check for new version at: {githubUrl}", EditorStyles.helpBox)) { Application.OpenURL(githubUrl); } return; } ReleaseInfo releaseInfo = _updateCheckerLibraryResponse.ReleaseInfo; if (releaseInfo.UnityPackage != null && SimpleGUI.InfoBox(releaseInfo.IsNewerThan(version), $"There is new version available: {releaseInfo.Version}! Click to update!\n{releaseInfo.Name}\n{releaseInfo.Description}") ) { GUILayout.BeginHorizontal(); if (!_downloadingUpdate) { SimpleGUI.ActionButton($"Update to {releaseInfo.Version}!", UpdateLibrary); } SimpleGUI.ActionButton("Download manually.", () => Application.OpenURL(releaseInfo.UnityPackage.DownloadUrl)); GUILayout.EndHorizontal(); return; } } if (GUILayout.Button($"{versionString}. Click to retry check for new version.", EditorStyles.helpBox)) { ForceCheckForUpdate(); } }
private void DrawSdkUpdateComponent() { if (_updateCheckerSdkResponse != null) { if (_updateCheckerSdkResponse.IsError) { #if GOTOUDON_DEV SimpleGUI.ErrorBox(_updateCheckerSdkResponse.IsError, "Failed to check for VRChat SDK update."); #endif return; } ReleaseInfo releaseInfo = _updateCheckerSdkResponse.ReleaseInfo; if (releaseInfo.Version == null) { return; } string newestSdkVersion = NormalizeVrChatSDKVersion(releaseInfo.Version); string currentSdkVersion = NormalizeVrChatSDKVersion(GotoUdonEditor.CurrentSDKVersion); // I give up, TODO: save version in own repository instead of using vrchat if (currentSdkVersion.EndsWith("05.06") && newestSdkVersion.EndsWith("05.12")) { return; } if (releaseInfo.Version.StartsWith(GotoUdonEditor.ImplementedSDKVersion)) { return; } if (releaseInfo.UnityPackage != null && SimpleGUI.InfoBox( VersionUtils.IsRightNewerThanLeft(currentSdkVersion, newestSdkVersion), $"There is new VRChat UDON SDK version available: {releaseInfo.Version}!\n{releaseInfo.Name}\n{releaseInfo.Description}") ) { GUILayout.BeginHorizontal(); // if (!_downloadingSdk) // SimpleGUI.ActionButton($"Update to {releaseInfo.Version}!", UpdateSdk); SimpleGUI.ActionButton("Download manually.", () => Application.OpenURL(releaseInfo.UnityPackage.DownloadUrl)); GUILayout.EndHorizontal(); } } }
private void DrawTemplatesEditor() { EditorGUI.BeginChangeCheck(); DrawGlobalOptions(GotoUdonSettings.Instance); SimpleGUI.SectionSpacing(); #if GOTOUDON_SIMULATION_LEGACY List <PlayerTemplate> templates = GotoUdonSettings.Instance.playerTemplates; if (templates.Count == 0) { templates.Add(PlayerTemplate.CreateNewPlayer(true)); } GUILayout.Label("Players to create at startup:"); PlayerTemplate toRemove = null; foreach (var template in templates) { if (PlayerTemplateEditor.DrawPlayerTemplateWithRemoveButton(template)) { toRemove = template; } SimpleGUI.OptionSpacing(); } templates.Remove(toRemove); if (templates.Count == 0) { templates.Add(PlayerTemplate.CreateNewPlayer(true)); } SimpleGUI.ActionButton("Add another player", () => templates.Add(PlayerTemplate.CreateNewPlayer(templates.Count == 0))); SimpleGUI.SectionSpacing(); if (SimpleGUI.EndChangeCheck()) { EditorUtility.SetDirty(GotoUdonSettings.Instance); } SimpleGUI.InfoBox(true, "In play mode you will be able to control all created players here, or add more"); #endif }
private void DrawGlobalOptions(GotoUdonSettings settings) { settings.Init(); if (!settings.IsSimulatorInstalled) { SimpleGUI.ActionButton("Install legacy simulator (probably doesnt work)", () => settings.IsSimulatorInstalled = true); } else { SimpleGUI.ActionButton("Remove simulator", () => settings.IsSimulatorInstalled = false); } #if GOTOUDON_SIMULATION_LEGACY SimpleGUI.ErrorBox(settings.avatarPrefab == null, "You need to select some avatar prefab to use this resource. You can find ybot-mini in Assets folder with this resource."); SimpleGUI.ErrorBox(settings.spawnPoint == null, "You need to select some spawn point to use this resource!"); GUILayout.Label("Global settings"); SimpleGUI.Indent(() => { settings.enableSimulation = EditorGUILayout.Toggle("Enable simulation", settings.enableSimulation); settings.avatarPrefab = SimpleGUI.ObjectField("Avatar prefab", settings.avatarPrefab, false); settings.spawnPoint = SimpleGUI.ObjectField("Spawn point", settings.spawnPoint, true); }); // nah, not really working // SimpleGUI.DrawFoldout(this, "Advanced settings", () => // { // SimpleGUI.WarningBox(true, // "Enabling vrchat client mode might cause some issues, but also allow to test your scripts with secure heap enabled\n" + // "This will add or remove VRC_CLIENT define for compiler, meaning that all internal sdk code will think its running on client and not in editor.\n" + // "Use at own risk."); // string VRC_CLIENT = "VRC_CLIENT"; // bool vrchatClientMode = UnityCompilerUtils.IsDefineEnabled(VRC_CLIENT); // string buttonName = vrchatClientMode ? "Use vrchat editor mode" : "Use vrchat client mode"; // SimpleGUI.ActionButton(buttonName, () => UnityCompilerUtils.SetDefineEnabled(VRC_CLIENT, !vrchatClientMode)); // }); #endif }
static void Main(string[] args) { #region World Setup Character c1 = new Character("Aziz", 200, 2, 2); Character c2 = new Character("Borax", 250, 3, 5); Character c3 = new Character("Cersei", 200, 6, 3); Character c4 = new Character("Dora", 200, 8, 8); List <Character> characters = new List <Character> { c1, c2, c3, c4 }; GameWorld world = new GameWorld(characters, 100); #endregion #region User Interaction string userInputStr = ""; while (userInputStr != "qqq") { if (Console.KeyAvailable) { userInputStr += Console.ReadKey(true).KeyChar.ToString(); SimpleGUI.SetCursorForUserInput(); Console.Write(userInputStr); } if (userInputStr.Length == 3 && userInputStr != "qqq") { UserInput input = new UserInput(userInputStr); if (input.IsValid) { world.SCManager.AddSpellCast(input.ShortName, input.X, input.Y, world.Clock.Time + 1); } userInputStr = ""; SimpleGUI.ResetUserInput(); } } #endregion }
public static void DrawValidationErrors(List <MissingImplementationData> missingImpls) { VRCVersionStatus versionStatus = IsVRChatSdkOutdated(); if (missingImpls.Count == 0) { SimpleGUI.ErrorBox(versionStatus == VRCVersionStatus.Error, "SDK version check failed, please report this to author. You can try to keep using current version, but some features might not work correctly"); SimpleGUI.ErrorBox(versionStatus == VRCVersionStatus.Outdated, $"Please update your VRChat SDK, this GotoUdon was made for: {GotoUdonEditor.ImplementedSDKVersion}"); SimpleGUI.ErrorBox(versionStatus == VRCVersionStatus.TooNew, "Please update GotoUdon if new version is available, if not you can try to keep using current version, but some features might not work correctly.\n" + "You can also check our discord to see if we are already working on update.\n" + "For emulation please use CyanEmu instead: https://github.com/CyanLaser/CyanEmu"); return; } StringBuilder errorStr = new StringBuilder( $"GotoUdon {GotoUdonEditor.VERSION} is not compatible with VRChat sdk {GotoUdonEditor.CurrentSDKVersion}.\n"); if (versionStatus == VRCVersionStatus.Same) { errorStr.AppendLine("This project is no longer maintained, Please use CyanEmu instead: https://github.com/CyanLaser/CyanEmu"); } errorStr.AppendLine("Auto detected problematic methods: "); foreach (MissingImplementationData missingImpl in missingImpls) { errorStr.AppendLine($" - {missingImpl.FieldName}"); } errorStr.AppendLine(); errorStr.AppendLine("If your udon scripts don't use methods above they might work just fine in emulator."); SimpleGUI.ErrorBox(true, errorStr.ToString()); }
public static void DrawAvailableRuntimePlayer(VRCEmulator emulator, SimulatedVRCPlayer player) { DrawRuntimePlayer(player); SimpleGUI.ActionButton("Connect", () => emulator.AddPlayer(player)); }
private static void openGUI() { simpleGUI = new SimpleGUI (); Application.Run (simpleGUI); }
public void PrintGameClock(int tick) { SimpleGUI.SetCursorForTime(); Console.WriteLine($"Game Time: {tick}"); }
private void OnGUI() { #if GOTOUDON_DEV DrawReleaseHelper(); #endif UpdaterEditor.Instance.DrawVersionInformation(); _scroll = GUILayout.BeginScrollView(_scroll, GUIStyle.none); if (!Application.isPlaying) { VRCSdkControlPanel.InitAccount(); } _settings.Init(); SimpleGUI.DrawFoldout(this, "Help", () => { SimpleGUI.InfoBox(true, "Here you can prepare profiles (vrchat --profile=x option) and launch them at once and connect to given world.\n" + "Each profile can be logged in to other vrchat account, allowing you for simple testing.\n" + "You can also disable some profiles, this will just simply ignore them when using button to start all clients.\n" + "Keeping instance might cause issues on restart with multiple clients, vrchat servers might still think you are trying to join twice."); }); EditorGUI.BeginChangeCheck(); SimpleGUI.DrawFoldout(this, "Advanced settings", () => { SimpleGUI.WarningBox(string.IsNullOrWhiteSpace(_settings.WorldId), "Missing world. Make sure your world have a vrc world descriptor and you are logged in to SDK."); SimpleGUI.InfoBox(string.IsNullOrWhiteSpace(_settings.UserId), "Login to SDK and User ID field will fill up itself"); _settings.userId = EditorGUILayout.TextField("User ID", _settings.userId); SimpleGUI.InfoBox(string.IsNullOrWhiteSpace(_settings.gamePath), "This should be automatically filled from sdk, but if its not, point it to your vrchat.exe"); _settings.gamePath = EditorGUILayout.TextField("Game path", _settings.gamePath); _settings.launchOptions = EditorGUILayout.TextField("Launch options", _settings.launchOptions); _settings.localLaunchOptions = EditorGUILayout.TextField("Local launch options", _settings.localLaunchOptions); // _settings.sendInvitesOnUpdate = EditorGUILayout.Toggle("Send invites on world update", _settings.sendInvitesOnUpdate); _settings.accessType = (ApiWorldInstance.AccessType)EditorGUILayout.EnumPopup("Access Type", _settings.accessType); _keepInstanceForce = EditorGUILayout.Toggle("Force keep instance ID", _keepInstanceForce); if (_keepInstanceForce) { _keepInstance = true; } GUILayout.BeginHorizontal(); GUILayout.Label("Same room restart wait time (s)", GUILayout.Width(200)); _settings.sameInstanceRestartDelay = EditorGUILayout.IntField(_settings.sameInstanceRestartDelay, GUILayout.Width(30)); GUILayout.EndHorizontal(); }); SimpleGUI.SectionSpacing(); DrawClientSection(); SimpleGUI.SectionSpacing(); if (SimpleGUI.EndChangeCheck()) { EditorUtility.SetDirty(_settings); EditorUtility.SetDirty(GotoUdonInternalState.Instance); } SimpleGUI.DrawFooterInformation(); GUILayout.EndScrollView(); }
public void SpellCastEnded(int index) { SimpleGUI.DeleteLine(index, _characterIndex); }
public static void DrawReleaseHelper() { #if GOTOUDON_DEV SimpleGUI.ActionButton($"Package GotoUdon-{Version}", PrepareRelease); }
private static void openGUI() { simpleGUI = new SimpleGUI(); Application.Run(simpleGUI); }