public static void CreateImageList() { string path = EditorUtility.OpenFolderPanel("Select Image Folder", "", ""); if (string.IsNullOrEmpty(path)) { return; } // read existing mod file if existent ModdingData md = new ModdingData(); string modFile = path + "/" + SDKUtil.MODFILE_NAME; if (File.Exists(modFile)) { md = SDKUtil.ReadJSONFileDirect <ModdingData>(modFile); } if (md.imageData == null) { md.imageData = new List <ImageData>(); } // gather images IEnumerable <string> files = DirectoryUtil.GetFiles(path, new[] { "*.png", "*.jpg" }); foreach (string file in files) { string fileName = Path.GetFileName(file); if (md.imageData.Any(id => id.imageLink == fileName)) { continue; } string name = Path.GetFileNameWithoutExtension(fileName); if (DateTime.TryParseExact(SDKUtil.MaxLength(name, 19), "yyyy-MM-dd HH.mm.ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime)) { name = dateTime.ToLongDateString() + " " + dateTime.ToShortTimeString(); } md.imageData.Add(new ImageData(fileName, name)); } File.WriteAllText(modFile, SDKUtil.SerializeObject(md)); EditorUtility.DisplayDialog("Done", $"Found {md.imageData.Count} images. Check modding.json in target folder.", "OK"); }
public Zone(Zone copyFrom) : this() { name = copyFrom.name; minSize = copyFrom.minSize; curSize = copyFrom.curSize; offset = copyFrom.offset; offsetRaw = copyFrom.offsetRaw; scenePath = copyFrom.scenePath; availableTime = copyFrom.availableTime; hasAmbientColor = copyFrom.hasAmbientColor; hasBackgroundColor = copyFrom.hasBackgroundColor; hasLightColor = copyFrom.hasLightColor; hasLightIntensity = copyFrom.hasLightIntensity; ambientColor = copyFrom.ambientColor; lightColor = copyFrom.lightColor; lightIntensity = copyFrom.lightIntensity; backgroundColor = copyFrom.backgroundColor; chapter = copyFrom.chapter; createCheckpoint = copyFrom.createCheckpoint; isExit = copyFrom.isExit; isIntro = copyFrom.isIntro; reactivateTransitions = copyFrom.reactivateTransitions; invisibleGround = copyFrom.invisibleGround; music = copyFrom.music; randomMusic = copyFrom.randomMusic; skybox = copyFrom.skybox; blockAgents = copyFrom.blockAgents; variationOf = copyFrom.variationOf; originalName = copyFrom.originalName; properties = SDKUtil.CopyProperties(copyFrom.properties); foreach (Floor floor in copyFrom.floors) { Floor copy = new Floor(floor); copy.positionInfoMarker = floor.positionInfoMarker; // FIXME: quick-fix for retaining challenge mode correctly until copy-constructor for position info exists floors.Add(copy); } }
public override void OnGUI() { // independent of actual window if (uploadInProgress) { int timeRemaining = Mathf.Max(1, Mathf.RoundToInt((DateTime.Now.Subtract(uploadStartTime).Seconds / uploadProgress) * (1 - uploadProgress))); Progress.SetRemainingTime(uploadProgressId, timeRemaining); Progress.Report(uploadProgressId, uploadProgress, "Uploading worlds to server..."); } base.OnGUI(); GUILayout.Label("Packaging ensures that the editor shows the most up to date version of your world.", EditorStyles.wordWrappedLabel); // TODO: cache string[] worlds = GetWorldPaths(); if (worlds.Length == 0) { EditorGUILayout.Space(); EditorGUILayout.HelpBox("There are no worlds created yet. Use the Setup tool to create one.", MessageType.Info); } else { if (worlds.Length > 1) { EditorGUILayout.Space(); GUILayout.BeginHorizontal(); GUILayout.Label("Packaging Mode:", EditorStyles.wordWrappedLabel); packageMode = EditorGUILayout.Popup(packageMode, PACKAGE_OPTIONS); GUILayout.EndHorizontal(); } else { packageMode = 0; } EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress); string buttonText = "Package"; if (packageMode == 1) { string[] worldsToBuild = GetWorldsToBuild(packageMode).Select(Path.GetFileName).ToArray(); buttonText += " (" + ((dirWatcher.affectedFiles.Count > 0) ? string.Join(", ", worldsToBuild) : "everything") + ")"; } if (GUILayout.Button(buttonText)) { EditorCoroutineUtility.StartCoroutine(PackageWorlds(packageMode, releaseChannel, packageMode == 2, packageMode == 2), this); } EditorGUI.EndDisabledGroup(); EditorGUILayout.Space(); GUILayout.Label("To test inside the Quest or to make the world accessible to others, upload it to the traVRsal server.", EditorStyles.wordWrappedLabel); GUILayout.BeginHorizontal(); GUILayout.Label("Release Channel:", EditorStyles.wordWrappedLabel); releaseChannel = EditorGUILayout.Popup(releaseChannel, RELEASE_CHANNELS); EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || verifyInProgress || documentationInProgress); if (GUILayout.Button("Prepare Upload")) { EditorCoroutineUtility.StartCoroutine(PrepareUpload(), this); } EditorGUI.EndDisabledGroup(); GUILayout.EndHorizontal(); CheckTokenGUI(); if (worldListMismatch && !SDKUtil.networkIssue) { EditorGUILayout.Space(); EditorGUILayout.HelpBox("The worlds inside your Worlds folder do not match your registered worlds on www.traVRsal.com. You probably need to rename these locally to match exactly.", MessageType.Error); if (GUILayout.Button("Refresh")) { EditorCoroutineUtility.StartCoroutine(RefreshVerify(), this); } } if (uncompressedTextures > 0) { EditorGUILayout.Space(); GUILayout.BeginHorizontal(); EditorGUILayout.HelpBox("Uncompressed Textures in Project: " + uncompressedTextures, MessageType.Warning); if (GUILayout.Button("Fix")) { EditorCoroutineUtility.StartCoroutine(CompressTextures(), this); } GUILayout.EndHorizontal(); } if (verifications.Count > 0) { EditorGUILayout.Space(); GUILayout.Label("Verification Results", EditorStyles.boldLabel); foreach (string dir in GetWorldPaths()) { string worldName = Path.GetFileName(dir); if (!verifications.ContainsKey(worldName)) { continue; } VerificationResult v = verifications[worldName]; v.showDetails = EditorGUILayout.Foldout(v.showDetails, worldName); if (v.showDetails) { PrintTableRow("Size (Quest)", v.distroExistsAndroid ? SDKUtil.BytesToString(v.distroSizeAndroid) : "not packaged yet"); PrintTableRow("Size (Windows)", v.distroExistsStandaloneWin ? SDKUtil.BytesToString(v.distroSizeStandaloneWin) : "not packaged yet"); if (linuxSupport) { PrintTableRow("Size (Linux)", v.distroExistsStandaloneLinux ? SDKUtil.BytesToString(v.distroSizeStandaloneLinux) : "not packaged yet"); } if (v.documentationExists) { BeginPartialTableRow("Documentation"); if (GUILayout.Button("Open")) { Help.BrowseURL(GetDocuPath(worldName) + "index.html"); } EndPartialTableRow(); } else { PrintTableRow("Documentation", "not created yet"); } BeginPartialTableRow("Actions"); EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || !uploadPossible); if (GUILayout.Button("Upload")) { EditorCoroutineUtility.StartCoroutine(UploadWorld(worldName), this); } if (debugMode && GUILayout.Button("Register")) { EditorCoroutineUtility.StartCoroutine(PublishWorldUpdates(worldName), this); } EditorGUI.EndDisabledGroup(); EndPartialTableRow(); } } } if (debugMode) { EditorGUILayout.Space(); EditorGUILayout.HelpBox("Debug mode is enabled.", MessageType.Warning); EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || verifyInProgress || documentationInProgress); if (GUILayout.Button("Create Documentation")) { EditorCoroutineUtility.StartCoroutine(CreateDocumentation(), this); } EditorGUI.EndDisabledGroup(); } } OnGUIDone(); }
private static bool UpdateWorldData(string worldName) { string root = GetWorldsRoot() + "/" + worldName + "/"; World world = SDKUtil.ReadJSONFileDirect <World>(root + "World.json"); if (world == null) { EditorUtility.DisplayDialog("Error", $"World.json file for {worldName} seems corrupted and needs to be fixed first.", "OK"); return(false); } string worldBasePath = Path.GetDirectoryName(AssetDatabase.GUIDToAssetPath(AssetDatabase.AssetPathToGUID(root + "World.json"))) + "/Pieces"; world.objectSpecs = new List <ObjectSpec>(); string[] assets = AssetDatabase.FindAssets("*", new[] { root + "Pieces" }); foreach (string asset in assets) { string assetPath = AssetDatabase.GUIDToAssetPath(asset); if (!assetPath.ToLower().EndsWith(".prefab")) { continue; } GameObject prefab = PrefabUtility.LoadPrefabContents(assetPath); if (prefab.TryGetComponent(out ExtendedAttributes ea)) { if (!ea.spec.IsDefault()) { string prefix = Path.GetDirectoryName(assetPath); if (prefix != null && prefix.Length > worldBasePath.Length) { prefix = prefix.Substring(worldBasePath.Length + 1) + "/"; prefix = prefix.Replace('\\', '/'); } else { prefix = ""; } string fileName = Path.GetFileNameWithoutExtension(assetPath); ea.spec.objectKey = prefix + fileName; world.objectSpecs.Add(ea.spec); } } if (prefab != null) { PrefabUtility.UnloadPrefabContents(prefab); } } // increase version if (string.IsNullOrEmpty(world.version)) { world.version = "0.0.1"; } else { if (Version.TryParse(world.version, out Version version)) { world.version = $"{version.Major}.{version.Minor}.{version.Build + 1}"; } else { world.version = "0.0.1"; Debug.LogError($"World.json of {worldName} contained an unreadable version. Resetting to {world.version}."); } } world.versionCode++; // write back world.NullifyEmpties(); File.WriteAllText(root + "World.json", SDKUtil.SerializeObject(world)); return(true); }
private void ManipulateWorld(string command) { World world = LoadWorld(); if (world == null) { return; } switch (command) { case "SetToCurrentVersion": PackageInfo pi = PackageInfo.FindForAssetPath("Packages/com.wetzold.travrsal.sdk/package.json"); if (pi != null) { world.minVersion = pi.version; EditorUtility.DisplayDialog("Success", $"Set minimum app version required to play the world to {pi.version}.", "OK"); } break; case "AddZone": if (string.IsNullOrEmpty(zoneName)) { return; } string root = GetWorldPaths()[0]; string path = $"{root}/Data/{zoneName}.tmx"; if (File.Exists(path)) { EditorUtility.DisplayDialog("Error", "A zone with that name already exists.", "OK"); return; } AssetDatabase.CopyAsset($"Packages/{SDKUtil.PACKAGE_NAME}/Editor/CopyTemplates/EmptyZone.copy", $"Assets/Worlds/{world.key}/Data/{zoneName}.tmx"); // two cases: either world explicitly lists files already or default is used with config.world mechanism if (world.worldData != null && world.worldData.Count > 0) { world.worldData.Add(new WorldDataReference(path, WorldDataReference.ImportType.TileMap)); } else { string mapFile = root + "/Data/Config.world"; TMWorld worldMap = SDKUtil.ReadJSONFileDirect <TMWorld>(mapFile); if (worldMap != null) { worldMap.maps = worldMap.maps.Append(new WorldMap(Path.GetFileName(path))); File.WriteAllText(mapFile, SDKUtil.SerializeObject(worldMap)); } else { EditorUtility.DisplayDialog("Error", $"Data/Config.world file for {world.key} does not exist. New zone was created but needs to be manually linked.", "OK"); } } zoneName = ""; AssetDatabase.Refresh(); break; case "AddVariable": if (string.IsNullOrEmpty(varName)) { return; } if (world.initialVariables == null) { world.initialVariables = new List <Variable>(); } world.initialVariables.Add(new Variable(varName)); varName = ""; break; case "AddSetting": if (string.IsNullOrEmpty(worldSetting)) { return; } if (world.settings == null) { world.settings = new List <WorldSetting>(); } world.settings.Add(new WorldSetting(worldSetting)); worldSetting = ""; break; case "AddCustomShader": if (string.IsNullOrEmpty(customShader)) { return; } if (world.customShaders == null) { world.customShaders = new List <string>(); } world.customShaders.Add(customShader); customShader = ""; break; } SaveWorld(world); }
public string GetPersistedState() { return(SDKUtil.SerializeObject(this)); }
public void LoadPersistedState(string state) { Variable v = SDKUtil.DeserializeObject <Variable>(state); Merge(v); }
public override void OnGUI() { // independent of actual window if (uploadInProgress) { int timeRemaining = Mathf.Max(1, Mathf.RoundToInt((DateTime.Now.Subtract(uploadStartTime).Seconds / uploadProgress) * (1 - uploadProgress))); EditorUtility.DisplayProgressBar("Progress", "Uploading levels to server... " + timeRemaining + "s", uploadProgress); } base.OnGUI(); GUILayout.Label("Packaging ensures that the editor shows the most up to date version of your level.", EditorStyles.wordWrappedLabel); GUILayout.Space(10); GUILayout.BeginHorizontal(); GUILayout.Label("Packaging Mode:", EditorStyles.wordWrappedLabel); packageMode = GUILayout.SelectionGrid(packageMode, PACKAGE_OPTIONS, 2, EditorStyles.radioButton); GUILayout.EndHorizontal(); EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress); string buttonText = "Package"; if (packageMode == 1) { string[] levelsToBuild = GetLevelsToBuild().Select(path => Path.GetFileName(path)).ToArray(); buttonText += " (" + ((dirWatcher.affectedFiles.Count > 0) ? string.Join(", ", levelsToBuild) : "everything") + ")"; } if (GUILayout.Button(buttonText)) { EditorCoroutineUtility.StartCoroutine(PackageLevels(packageMode == 2 ? true : false, packageMode == 2 ? true : false), this); } EditorGUI.EndDisabledGroup(); GUILayout.BeginHorizontal(); EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || verifyInProgress); if (GUILayout.Button("Prepare Upload")) { EditorCoroutineUtility.StartCoroutine(PrepareUpload(), this); } EditorGUI.EndDisabledGroup(); EditorGUI.BeginDisabledGroup(packagingInProgress || uploadInProgress || !uploadPossible); if (GUILayout.Button("Upload")) { EditorCoroutineUtility.StartCoroutine(UploadLevels(), this); } EditorGUI.EndDisabledGroup(); GUILayout.EndHorizontal(); if (verifications.Count() > 0) { GUILayout.Space(10); GUILayout.Label("Verification Results", EditorStyles.boldLabel); foreach (string dir in GetLevelPaths()) { string levelName = Path.GetFileName(dir); if (!verifications.ContainsKey(levelName)) { continue; } VerificationResult v = verifications[levelName]; v.showDetails = EditorGUILayout.Foldout(v.showDetails, levelName); if (v.showDetails) { // PrintTableRow("Size (Original)", SDKUtil.BytesToString(v.sourceSize)); PrintTableRow("Size (Quest)", v.distroExistsAndroid ? SDKUtil.BytesToString(v.distroSizeAndroid) : "not packaged yet"); PrintTableRow("Size (PC)", v.distroExistsStandalone ? SDKUtil.BytesToString(v.distroSizeStandalone) : "not packaged yet"); if (v.documentationExists) { BeginPartialTableRow("Documentation"); if (GUILayout.Button("Open")) { Help.BrowseURL(GetDocuPath(levelName) + "index.html"); } EndPartialTableRow(); } else { PrintTableRow("Documentation", "not created yet"); } } } } if (debugMode) { EditorGUI.BeginDisabledGroup(documentationInProgress); if (GUILayout.Button("Create Documentation")) { EditorCoroutineUtility.StartCoroutine(CreateDocumentation(), this); } EditorGUI.EndDisabledGroup(); } OnGUIDone(); }