public GorillaHat(string path) { if (path != "Default") { try { FileName = path; var bundleAndJson = PackageUtils.AssetBundleAndJSONFromPackage(FileName); AssetBundle = bundleAndJson.bundle; PackageJSON json = bundleAndJson.json; // get material object and stuff Hat = AssetBundle.LoadAsset <GameObject>("_Hat"); foreach (Collider collider in Hat.GetComponentsInChildren <Collider>()) { collider.enabled = false; // Disable colliders. They can be left in accidentally and cause some really weird issues. } // Make Descriptor Descriptor = PackageUtils.ConvertJsonToHat(json); Debug.Log(Descriptor.AuthorName); } catch (Exception err) { // loading failed. that's not good. Debug.Log(err); } } }
public GorillaMaterial(string path) { if (path != "Default") { try { // load FileName = path; var bundleAndJson = PackageUtils.AssetBundleAndJSONFromPackage(FileName); AssetBundle = bundleAndJson.bundle; PackageJSON json = bundleAndJson.json; // get material object and stuff GameObject materialObject = AssetBundle.LoadAsset <GameObject>("_Material"); Material = materialObject.GetComponent <Renderer>().material; // Make Descriptor Descriptor = PackageUtils.ConvertJsonToMaterial(json); } catch (Exception err) { // loading failed. that's not good. Debug.Log(err); } } else { // try to load the default material Descriptor = new GorillaMaterialDescriptor(); Descriptor.MaterialName = "Default"; Descriptor.CustomColors = true; Material = Resources.Load <Material>("objects/treeroom/materials/lightfur"); } }
public static PackageJSON ReadObjectAllPackages() { string json = File.ReadAllText(@"C:\Users\Simo\Documents\Visual Studio 2015\Projects\Third application problem\PackageManager\dependencies\all_packages.json"); PackageJSON newObject = JsonConvert.DeserializeObject <PackageJSON>(json); return(newObject); }
public static (AssetBundle bundle, PackageJSON json) AssetBundleAndJSONFromPackage(string path) { AssetBundle bundle = null; PackageJSON json = null; using (ZipArchive archive = ZipFile.OpenRead(path)) { var jsonEntry = archive.Entries.First(i => i.Name == "package.json"); if (jsonEntry != null) { var stream = new StreamReader(jsonEntry.Open(), Encoding.Default); string jsonString = stream.ReadToEnd(); json = JsonConvert.DeserializeObject <PackageJSON>(jsonString); } foreach (ZipArchiveEntry entry in archive.Entries) { if (json != null && entry.Name == json.pcFileName) { //here the file var SeekableStream = new MemoryStream(); entry.Open().CopyTo(SeekableStream); SeekableStream.Position = 0; bundle = AssetBundle.LoadFromStream(SeekableStream); } } } return(bundle, json); }
public static void CheckDependencies(PackageJSON allPackages, DependencyJSON dependencies, List<string> installed) { for (int i = 0; i < dependencies.dependencies.Length; i++) { if (dependencies.dependencies[i] == "backbone") { if (installed.Contains("backbone")) { Console.WriteLine("Backbone is already installed"); } else { Console.WriteLine("Installing backbone"); Console.WriteLine("In order to install backbone, we need jQuery and underscore"); CreateFile("backbone"); installed.Add("backbone"); installed.Add("jQuery"); installed.Add("underscore"); for (int b = 0; b < allPackages.backbone.Length; b++) { CreateFile(allPackages.backbone[b]); } } } if (dependencies.dependencies[i] == "jQuery") { if (installed.Contains("jQuery")) { Console.WriteLine("jQuery is already installed"); } else { Console.WriteLine("Installing jQuery"); Console.WriteLine("In order to install jQuery, we need queryJ"); for (int b = 0; b < allPackages.jQuery.Length; b++) { CreateFile(allPackages.jQuery[b]); } } } if (dependencies.dependencies[i] == "underscore") { Console.WriteLine("Installing _underscore"); Console.WriteLine("In order to install _underscore , we need lodash"); for (int b = 0; b < allPackages.underscore.Length; b++) { CreateFile(allPackages.underscore[b]); } } } }
public static void Main() { List <string> installed = new List <string>(); //read the all packages file and create an PackageJSON PackageJSON allPackages = ReadObjectAllPackages(); //read the dependencies file and create an instance of DependencyJSON DependencyJSON dependencies = ReadObjectDependencies(); CheckDependencies(allPackages, dependencies, installed); }
public static void CheckDependencies(PackageJSON allPackages, DependencyJSON dependencies, List <string> installed) { for (int i = 0; i < dependencies.dependencies.Length; i++) { if (dependencies.dependencies[i] == "backbone") { if (installed.Contains("backbone")) { Console.WriteLine("Backbone is already installed"); } else { Console.WriteLine("Installing backbone"); Console.WriteLine("In order to install backbone, we need jQuery and underscore"); CreateFile("backbone"); installed.Add("backbone"); installed.Add("jQuery"); installed.Add("underscore"); for (int b = 0; b < allPackages.backbone.Length; b++) { CreateFile(allPackages.backbone[b]); } } } if (dependencies.dependencies[i] == "jQuery") { if (installed.Contains("jQuery")) { Console.WriteLine("jQuery is already installed"); } else { Console.WriteLine("Installing jQuery"); Console.WriteLine("In order to install jQuery, we need queryJ"); for (int b = 0; b < allPackages.jQuery.Length; b++) { CreateFile(allPackages.jQuery[b]); } } } if (dependencies.dependencies[i] == "underscore") { Console.WriteLine("Installing _underscore"); Console.WriteLine("In order to install _underscore , we need lodash"); for (int b = 0; b < allPackages.underscore.Length; b++) { CreateFile(allPackages.underscore[b]); } } } }
public static CosmeticDescriptor ConvertJsonToDescriptor(PackageJSON json) { CosmeticDescriptor Descriptor = new(); Descriptor.Name = json.descriptor.objectName; Descriptor.AuthorName = json.descriptor.author; Descriptor.Description = json.descriptor.description; Descriptor.CustomColors = json.config.customColors; Descriptor.DisablePublicLobbies = json.config.disableInPublicLobbies; return(Descriptor); }
public static GorillaMaterialDescriptor ConvertJsonToMaterial(PackageJSON json) { GorillaMaterialDescriptor Descriptor = new GorillaMaterialDescriptor(); Descriptor.MaterialName = json.descriptor.objectName; Descriptor.AuthorName = json.descriptor.author; Descriptor.Description = json.descriptor.description; Descriptor.CustomColors = json.config.customColors; Descriptor.DisablePublicLobbies = json.config.disableInPublicLobbies; return(Descriptor); }
public static PackageJSON HatDescriptorToJSON(GorillaCosmetics.Data.Descriptors.HatDescriptor hatDescriptor) { PackageJSON packageJSON = new PackageJSON(); packageJSON.descriptor = new Descriptor(); packageJSON.config = new Config(); packageJSON.descriptor.author = hatDescriptor.AuthorName; packageJSON.descriptor.objectName = hatDescriptor.HatName; packageJSON.descriptor.description = hatDescriptor.Description; packageJSON.config.customColors = hatDescriptor.CustomColors; packageJSON.config.disableInPublicLobbies = hatDescriptor.DisablePublicLobbies; return(packageJSON); }
public static PackageJSON MaterialDescriptorToJSON(GorillaCosmetics.Data.Descriptors.GorillaMaterialDescriptor materialDescriptor) { PackageJSON packageJSON = new PackageJSON(); packageJSON.descriptor = new Descriptor(); packageJSON.config = new Config(); packageJSON.descriptor.author = materialDescriptor.AuthorName; packageJSON.descriptor.objectName = materialDescriptor.MaterialName; packageJSON.descriptor.description = materialDescriptor.Description; packageJSON.config.customColors = materialDescriptor.CustomColors; packageJSON.config.disableInPublicLobbies = materialDescriptor.DisablePublicLobbies; //packageJSON.config.position = "rack"; return(packageJSON); }
public static PackageJSON MapDescriptorToJSON(MapDescriptor mapDescriptor) { PackageJSON packageJSON = new PackageJSON(); packageJSON.descriptor = new Descriptor(); packageJSON.config = new Config(); packageJSON.descriptor.author = mapDescriptor.AuthorName; packageJSON.descriptor.objectName = mapDescriptor.MapName; packageJSON.descriptor.description = mapDescriptor.Description; packageJSON.config.imagePath = null; packageJSON.config.gravity = mapDescriptor.GravitySpeed; // do config stuff here return(packageJSON); }
public GorillaHat(string path) { if (path != "Default") { try { FileName = path; var bundleAndJson = PackageUtils.AssetBundleAndJSONFromPackage(FileName); assetBundle = bundleAndJson.bundle; PackageJSON json = bundleAndJson.json; // get material object and stuff assetTemplate = assetBundle.LoadAsset <GameObject>("_Hat"); foreach (Collider collider in assetTemplate.GetComponentsInChildren <Collider>()) { collider.enabled = false; // Disable colliders. They can be left in accidentally and cause some really weird issues. } assetTemplate.SetActive(false); // Make Descriptor Descriptor = PackageUtils.ConvertJsonToDescriptor(json); } catch (Exception err) { // loading failed. that's not good. Debug.LogError(err); throw new Exception($"Loading hat at {path} failed."); } } else { Descriptor = new CosmeticDescriptor(); Descriptor.Name = "Default"; assetTemplate = null; } }
public static void ExportPackage(GameObject gameObject, string path, string typeName, PackageJSON packageJSON) { if (exporting) { return; } string fileName = Path.GetFileName(path); string folderPath = Path.GetDirectoryName(path); string androidFileName = Path.GetFileNameWithoutExtension(path) + "_android"; string pcFileName = Path.GetFileNameWithoutExtension(path) + "_pc"; string assetBundleScenePath = $"Assets/Editor/ExportScene.unity"; string oldScenePath = gameObject.scene.path; if (oldScenePath != null) { EditorSceneManager.SaveScene(gameObject.scene); } try { // Disable scene checking because it'll be loading the scene to export SceneChecker.disabled = true; exporting = true; Selection.activeObject = gameObject; MapDescriptor mapDescriptor = gameObject.GetComponent <MapDescriptor>(); // Compute Required Versions System.Version pcRequiredVersion = ComputePcVersion(mapDescriptor); System.Version androidRequiredVersion = ComputeAndroidVersion(mapDescriptor); if (!mapDescriptor.ExportLighting) { Lightmapping.Clear(); Lightmapping.ClearLightingDataAsset(); } //Check if editor folder exists just in case, since some people move it accidentally or something if (!AssetDatabase.IsValidFolder("Assets/Editor")) { Debug.LogWarning("The Editor folder does not exist. You may have installed the project incorrectly, or dragged the Editor folder into a subfolder."); Debug.LogWarning("If you experience problems with exporting, make sure your Editor folder is in the right place. If it still doesn't work, reinstall this unity project and make sure to follow the install instructions."); Debug.LogWarning("Trying to export anyways..."); AssetDatabase.CreateFolder("Assets", "Editor"); } EditorSceneManager.SaveScene(gameObject.scene, assetBundleScenePath, true); EditorSceneManager.OpenScene(assetBundleScenePath); // Destroy other maps that exist MapDescriptor[] descriptorList = Object.FindObjectsOfType <MapDescriptor>(); foreach (MapDescriptor descriptor in descriptorList) { if (descriptor.MapName != mapDescriptor.MapName) { Object.DestroyImmediate(descriptor.gameObject); } else { mapDescriptor = descriptor; gameObject = descriptor.gameObject; Selection.activeObject = gameObject; } } // Move objects that aren't in the map parent to the map parent foreach (GameObject sceneRootObject in EditorSceneManager.GetActiveScene().GetRootGameObjects()) { if (sceneRootObject != gameObject) { sceneRootObject.transform.SetParent(gameObject.transform); } } // Unpack all prefabs foreach (GameObject subObject in GameObject.FindObjectsOfType <GameObject>()) { if (PrefabUtility.GetPrefabInstanceStatus(subObject) != PrefabInstanceStatus.NotAPrefab) { PrefabUtility.UnpackPrefabInstance(PrefabUtility.GetOutermostPrefabInstanceRoot(subObject), PrefabUnpackMode.Completely, InteractionMode.AutomatedAction); } } // Skybox Stuff if (mapDescriptor.CustomSkybox != null) { // Create Fake Skybox GameObject skybox = GameObject.CreatePrimitive(PrimitiveType.Sphere); skybox.name = "Skybox"; skybox.transform.SetParent(gameObject.transform); skybox.transform.localScale = new Vector3(1000, 1000, 1000); skybox.transform.localPosition = Vector3.zero; skybox.transform.localRotation = Quaternion.identity; Object.DestroyImmediate(skybox.GetComponent <Collider>()); Material skyboxMaterial = new Material(Shader.Find("Bobbie/Outer")); skyboxMaterial.SetTexture("_Tex", mapDescriptor.CustomSkybox); skybox.GetComponent <Renderer>().material = skyboxMaterial; skybox.GetComponent <Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; } else { // Create Fake Skybox that represents the game's GameObject skyboxObject = AssetDatabase.LoadAssetAtPath("Assets/Prefabs/FakeSkybox.prefab", typeof(GameObject)) as GameObject; GameObject fakeSkybox = PrefabUtility.InstantiatePrefab(skyboxObject) as GameObject; fakeSkybox.transform.SetParent(gameObject.transform); fakeSkybox.transform.localPosition = Vector3.zero; } // Remove meshes from prefabs/triggers if (!DebugPrefabs) { StripMeshes <ObjectTrigger>(gameObject); StripMeshes <Teleporter>(gameObject); StripMeshes <TagZone>(gameObject); foreach (Renderer renderer in gameObject.GetComponentsInChildren <Renderer>()) { if (renderer.sharedMaterial != null && renderer.sharedMaterial.name.StartsWith("Teleport Point")) { Object.DestroyImmediate(renderer); } } StripMeshes <ObjectTrigger>(gameObject); } foreach (Renderer renderer in gameObject.GetComponentsInChildren <Renderer>()) { if (renderer.sharedMaterial != null && renderer.sharedMaterial.name.StartsWith("Spawn Point")) { bool foundTransform = false; foreach (Transform spawnPoint in mapDescriptor.SpawnPoints) { if (spawnPoint == renderer.gameObject.transform) { foundTransform = true; } } if (!foundTransform) { List <Transform> spawnPointArray = new List <Transform>(mapDescriptor.SpawnPoints); spawnPointArray.Add(renderer.gameObject.transform); mapDescriptor.SpawnPoints = spawnPointArray.ToArray(); } if (!DebugPrefabs) { Collider spawnPointCollider = renderer.gameObject.GetComponent <Collider>(); if (spawnPointCollider) { Object.DestroyImmediate(spawnPointCollider); } Object.DestroyImmediate(renderer); } } } if (mapDescriptor.SpawnPoints.Length == 0) { throw new System.Exception("No spawn points found! Add some spawn points to your map."); } // Take Screenshots with the thumbnail camera Camera thumbnailCamera = GameObject.Find("ThumbnailCamera")?.GetComponent <Camera>(); if (thumbnailCamera != null) { // Normal Screenshot Texture2D screenshot = CaptureScreenshot(thumbnailCamera, 512, 512); byte[] screenshotPNG = ImageConversion.EncodeToPNG(screenshot); File.WriteAllBytes(Application.temporaryCachePath + "/preview.png", screenshotPNG); packageJSON.config.imagePath = "preview.png"; // Cubemap Screenshot Texture2D screenshotCubemap = CaptureCubemap(thumbnailCamera, 1024, 1024); byte[] screenshotCubemapPNG = ImageConversion.EncodeToPNG(screenshotCubemap); File.WriteAllBytes(Application.temporaryCachePath + "/preview_cubemap.png", screenshotCubemapPNG); packageJSON.config.cubemapImagePath = "preview_cubemap.png"; packageJSON.config.mapColor = AverageColor(screenshotCubemap); } else { throw new System.Exception("ThumbnailCamera is missing! Make sure to add a ThumbnailCamera to your map."); } Object.DestroyImmediate(thumbnailCamera.gameObject); // Pre-Process stuff for both platforms - PC and Android. GameObject spawnPointContainer = new GameObject("SpawnPointContainer"); spawnPointContainer.transform.SetParent(gameObject.transform); spawnPointContainer.transform.localPosition = Vector3.zero; spawnPointContainer.transform.localRotation = Quaternion.identity; spawnPointContainer.transform.localScale = Vector3.one; List <string> spawnPointNames = new List <string>(); for (int i = 0; i < mapDescriptor.SpawnPoints.Length; i++) { Transform spawnPointTransform = mapDescriptor.SpawnPoints[i].gameObject.transform; Vector3 oldPos = spawnPointTransform.position; var oldRotation = spawnPointTransform.rotation; spawnPointTransform.SetParent(spawnPointContainer.transform); spawnPointTransform.rotation = oldRotation; spawnPointTransform.position = oldPos; string nameString = "SpawnPoint" + (i < 10 ? "0" + i : i.ToString()); mapDescriptor.SpawnPoints[i].gameObject.name = nameString; spawnPointNames.Add(nameString); } packageJSON.config.spawnPoints = spawnPointNames.ToArray(); // Replace tiling materials with baked versions foreach (Renderer renderer in gameObject.GetComponentsInChildren <Renderer>()) { if (renderer.sharedMaterial != null && renderer.sharedMaterial.shader.name.Contains("Standard Tiling") && !renderer.sharedMaterial.shader.name.Contains("Baked")) { renderer.sharedMaterial = Object.Instantiate(renderer.sharedMaterial); renderer.sharedMaterial.shader = Shader.Find("Standard Tiling Baked"); Transform rendererTransform = renderer.gameObject.transform; Vector3 newVector = RotatePointAroundPivot(rendererTransform.lossyScale, new Vector3(0, 0, 0), rendererTransform.rotation.eulerAngles); renderer.sharedMaterial.SetVector("_ScaleVector", newVector); } } // Destroy all non-render cameras because people keep accidentally exporting them foreach (Camera camera in gameObject.GetComponentsInChildren <Camera>()) { if (camera.targetTexture == null && camera.gameObject != null) { Object.DestroyImmediate(camera.gameObject); } } //Destroy Audio listeners too since they can break sound foreach (AudioListener listener in gameObject.GetComponentsInChildren <AudioListener>()) { if (listener != null) { Object.DestroyImmediate(listener); } } // Lighting stuff. Make sure to set light stuff up and make it bigger, and bake if (mapDescriptor.ExportLighting) { foreach (Light light in Object.FindObjectsOfType <Light>()) { // needs to be redone, colors are inconsistent and can probably be made better if (light.type == LightType.Directional) { light.intensity *= 11.54f; light.color = new Color(0.3215f, 0.3215f, 0.3215f); } else { light.intensity *= 10f; } } bool baking = Lightmapping.BakeAsync(); if (baking) { Lightmapping.bakeCompleted -= PostBake; Lightmapping.bakeCompleted += PostBake; } else { throw new System.Exception("Couldn't start lightmapping."); } } else { foreach (Light light in Object.FindObjectsOfType <Light>()) { Object.DestroyImmediate(light); } Lightmapping.Clear(); Lightmapping.ClearLightingDataAsset(); PostBake(); } void PostBake() { gameObject.transform.localPosition = new Vector3(0, 5000, 0); // Save as prefab and build // PrefabUtility.SaveAsPrefabAsset(Selection.activeObject as GameObject, $"Assets/_{typeName}.prefab"); EditorSceneManager.SaveScene(gameObject.scene); AssetBundleBuild assetBundleBuild = default; assetBundleBuild.assetNames = new string[] { assetBundleScenePath }; assetBundleBuild.assetBundleName = pcFileName; // Build for PC BuildPipeline.BuildAssetBundles(Application.temporaryCachePath, new AssetBundleBuild[] { assetBundleBuild }, 0, BuildTarget.StandaloneWindows64); // Do Android specific stuff here. Stripping MonoBehaviours and converting them to TextAssets, etc. // first we need to redo this bit of code because sometimes gameObject unreferences itself MapDescriptor[] descriptorList2 = Object.FindObjectsOfType <MapDescriptor>(); foreach (MapDescriptor descriptor in descriptorList2) { if (descriptor.MapName != mapDescriptor.MapName) { Object.DestroyImmediate(descriptor.gameObject); } else { mapDescriptor = descriptor; gameObject = descriptor.gameObject; Selection.activeObject = gameObject; } } StripPrefabsForQuest(gameObject); Object.DestroyImmediate(mapDescriptor); // Do it again for Android EditorSceneManager.SaveScene(gameObject.scene); // PrefabUtility.SaveAsPrefabAsset(Selection.activeObject as GameObject, $"Assets/_{typeName}.prefab"); // are these next 2 lines necessary? idk. probably test it. assetBundleBuild.assetNames = new string[] { assetBundleScenePath }; assetBundleBuild.assetBundleName = androidFileName; BuildPipeline.BuildAssetBundles(Application.temporaryCachePath, new AssetBundleBuild[] { assetBundleBuild }, 0, BuildTarget.Android); EditorPrefs.SetString("currentBuildingAssetBundlePath", folderPath); // JSON stuff packageJSON.androidFileName = androidFileName; packageJSON.pcFileName = pcFileName; packageJSON.descriptor.pcRequiredVersion = pcRequiredVersion.ToString(); packageJSON.descriptor.androidRequiredVersion = androidRequiredVersion.ToString(); string json = JsonUtility.ToJson(packageJSON, true); File.WriteAllText(Application.temporaryCachePath + "/package.json", json); // AssetDatabase.DeleteAsset($"Assets/_{typeName}.prefab"); // Delete the zip if it already exists and re-zip List <string> files = new List <string> { Application.temporaryCachePath + "/" + pcFileName, Application.temporaryCachePath + "/" + androidFileName, Application.temporaryCachePath + "/package.json", Application.temporaryCachePath + "/preview.png", Application.temporaryCachePath + "/preview_cubemap.png" }; if (File.Exists(Application.temporaryCachePath + "/tempZip.zip")) { File.Delete(Application.temporaryCachePath + "/tempZip.zip"); } CreateZipFile(Application.temporaryCachePath + "/tempZip.zip", files); // After zipping, clear some assets from the temp folder if (File.Exists(path)) { File.Delete(path); } foreach (string file in files) { if (File.Exists(file)) { File.Delete(file); } } // Move the ZIP and finalize File.Move(Application.temporaryCachePath + "/tempZip.zip", path); //Object.DestroyImmediate(gameObject); AssetDatabase.Refresh(); // Open scene again EditorSceneManager.OpenScene(oldScenePath); // Re-enable scene checking SceneChecker.disabled = false; exporting = false; EditorUtility.DisplayDialog("Exportation Successful!", "Exportation Successful!", "OK"); EditorUtility.RevealInFinder(path); } } catch (System.Exception e) { exporting = false; SceneChecker.disabled = false; Debug.Log("Something went wrong... let's load the old scene."); EditorUtility.DisplayDialog("Error!", e.Message, "OK"); if (oldScenePath != null) { EditorSceneManager.OpenScene(oldScenePath); } else { throw new System.Exception("Something went wrong and you don't have your work saved in a scene! PLEASE save your work in a scene before trying to export."); } throw e; } }
public static void ExportPackage(GameObject gameObject, string path, string typeName, PackageJSON packageJSON) { string fileName = Path.GetFileName(path); string folderPath = Path.GetDirectoryName(path); string androidFileName = Path.GetFileNameWithoutExtension(path) + "_android"; string pcFileName = Path.GetFileNameWithoutExtension(path) + "_pc"; Selection.activeObject = gameObject; EditorSceneManager.MarkSceneDirty(gameObject.scene); EditorSceneManager.SaveScene(gameObject.scene); PrefabUtility.SaveAsPrefabAsset(Selection.activeObject as GameObject, $"Assets/_{typeName}.prefab"); AssetBundleBuild assetBundleBuild = default; assetBundleBuild.assetNames = new string[] { $"Assets/_{typeName}.prefab" }; assetBundleBuild.assetBundleName = pcFileName; // Build for PC BuildTargetGroup selectedBuildTargetGroup = EditorUserBuildSettings.selectedBuildTargetGroup; BuildTarget activeBuildTarget = EditorUserBuildSettings.activeBuildTarget; BuildPipeline.BuildAssetBundles(Application.temporaryCachePath, new AssetBundleBuild[] { assetBundleBuild }, 0, BuildTarget.StandaloneWindows64); // Do it again for Android assetBundleBuild.assetBundleName = androidFileName; BuildPipeline.BuildAssetBundles(Application.temporaryCachePath, new AssetBundleBuild[] { assetBundleBuild }, 0, BuildTarget.Android); EditorPrefs.SetString("currentBuildingAssetBundlePath", folderPath); // JSON stuff packageJSON.androidFileName = androidFileName; packageJSON.pcFileName = pcFileName; string json = JsonUtility.ToJson(packageJSON, true); File.WriteAllText(Application.temporaryCachePath + "/package.json", json); AssetDatabase.DeleteAsset($"Assets/_{typeName}.prefab"); // Delete the zip if it already exists and re-zip if (File.Exists(Application.temporaryCachePath + "/tempZip.zip")) { File.Delete(Application.temporaryCachePath + "/tempZip.zip"); } CreateZipFile(Application.temporaryCachePath + "/tempZip.zip", new List <string> { Application.temporaryCachePath + "/" + pcFileName, Application.temporaryCachePath + "/" + androidFileName, Application.temporaryCachePath + "/package.json" }); if (File.Exists(path)) { File.Delete(path); } File.Move(Application.temporaryCachePath + "/tempZip.zip", path); UnityEngine.Object.DestroyImmediate(gameObject); /*if (File.Exists(path)) * { * File.Delete(path); * } * Debug.Log(path); * //File.Move(Application.temporaryCachePath + "/PC_" + fileName, path); * //File.Move(Application.temporaryCachePath + "/Android_" + fileName, path); * AssetDatabase.Refresh(); * //EditorUtility.DisplayDialog("Exportation Successful!", "Exportation Successful!", "OK");*/ AssetDatabase.Refresh(); }
public static void ExportPackage(GameObject gameObject, string path, string typeName, PackageJSON packageJSON) { string fileName = Path.GetFileName(path); string folderPath = Path.GetDirectoryName(path); string androidFileName = Path.GetFileNameWithoutExtension(path) + "_android"; string pcFileName = Path.GetFileNameWithoutExtension(path) + "_pc"; string assetBundleScenePath = $"Assets/Editor/ExportScene.unity"; string oldScenePath = gameObject.scene.path; if (oldScenePath != null) { EditorSceneManager.SaveScene(gameObject.scene); } try { Selection.activeObject = gameObject; MapDescriptor mapDescriptor = gameObject.GetComponent <MapDescriptor>(); if (!mapDescriptor.ExportLighting) { Lightmapping.Clear(); Lightmapping.ClearLightingDataAsset(); } //EditorSceneManager.MarkSceneDirty(gameObject.scene); EditorSceneManager.SaveScene(gameObject.scene, assetBundleScenePath, true); EditorSceneManager.OpenScene(assetBundleScenePath); MapDescriptor[] descriptorList = Object.FindObjectsOfType <MapDescriptor>(); foreach (MapDescriptor descriptor in descriptorList) { if (descriptor.MapName != mapDescriptor.MapName) { Object.DestroyImmediate(descriptor.gameObject); } else { mapDescriptor = descriptor; gameObject = descriptor.gameObject; Selection.activeObject = gameObject; } } // First, unpack all prefabs foreach (GameObject subObject in GameObject.FindObjectsOfType <GameObject>()) { if (PrefabUtility.GetPrefabInstanceStatus(subObject) != PrefabInstanceStatus.NotAPrefab) { PrefabUtility.UnpackPrefabInstance(PrefabUtility.GetOutermostPrefabInstanceRoot(subObject), PrefabUnpackMode.Completely, InteractionMode.AutomatedAction); } } // Skybox Stuff if (mapDescriptor.CustomSkybox != null) { // Create Fake Skybox GameObject skybox = GameObject.CreatePrimitive(PrimitiveType.Sphere); skybox.name = "Skybox"; skybox.transform.SetParent(gameObject.transform); skybox.transform.localScale = new Vector3(1000, 1000, 1000); skybox.transform.localPosition = Vector3.zero; skybox.transform.localRotation = Quaternion.identity; Object.DestroyImmediate(skybox.GetComponent <Collider>()); Material skyboxMaterial = new Material(Shader.Find("Bobbie/Outer")); skyboxMaterial.SetTexture("_Tex", mapDescriptor.CustomSkybox); skybox.GetComponent <Renderer>().material = skyboxMaterial; skybox.GetComponent <Renderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; } else { // Create Fake Skybox that represents the game's GameObject skyboxObject = AssetDatabase.LoadAssetAtPath("Assets/Prefabs/FakeSkybox.prefab", typeof(GameObject)) as GameObject; GameObject fakeSkybox = PrefabUtility.InstantiatePrefab(skyboxObject) as GameObject; fakeSkybox.transform.SetParent(gameObject.transform); fakeSkybox.transform.localPosition = Vector3.zero; } // Remove meshes from prefabs/triggers if (!DebugPrefabs) { StripMeshes <ObjectTrigger>(gameObject); StripMeshes <Teleporter>(gameObject); StripMeshes <TagZone>(gameObject); foreach (Renderer renderer in gameObject.GetComponentsInChildren <Renderer>()) { if (renderer.sharedMaterial != null && renderer.sharedMaterial.name.StartsWith("Teleport Point")) { Object.DestroyImmediate(renderer); } } StripMeshes <ObjectTrigger>(gameObject); } foreach (Renderer renderer in gameObject.GetComponentsInChildren <Renderer>()) { if (renderer.sharedMaterial != null && renderer.sharedMaterial.name.StartsWith("Spawn Point")) { bool foundTransform = false; foreach (Transform spawnPoint in mapDescriptor.SpawnPoints) { if (spawnPoint == renderer.gameObject.transform) { foundTransform = true; } } if (!foundTransform) { List <Transform> spawnPointArray = new List <Transform>(mapDescriptor.SpawnPoints); spawnPointArray.Add(renderer.gameObject.transform); mapDescriptor.SpawnPoints = spawnPointArray.ToArray(); } if (!DebugPrefabs) { Collider spawnPointCollider = renderer.gameObject.GetComponent <Collider>(); if (spawnPointCollider) { Object.DestroyImmediate(spawnPointCollider); } Object.DestroyImmediate(renderer); } } } if (mapDescriptor.SpawnPoints.Length == 0) { throw new System.Exception("No spawn points found! Add some spawn points to your map."); } // Take Screenshots with the thumbnail camera Camera thumbnailCamera = gameObject.transform.Find("ThumbnailCamera")?.GetComponent <Camera>(); if (thumbnailCamera != null) { // Normal Screenshot Texture2D screenshot = CaptureScreenshot(thumbnailCamera, 512, 512); byte[] screenshotPNG = ImageConversion.EncodeToPNG(screenshot); File.WriteAllBytes(Application.temporaryCachePath + "/preview.png", screenshotPNG); packageJSON.config.imagePath = "preview.png"; // Cubemap Screenshot Texture2D screenshotCubemap = CaptureCubemap(thumbnailCamera, 1024, 1024); byte[] screenshotCubemapPNG = ImageConversion.EncodeToPNG(screenshotCubemap); File.WriteAllBytes(Application.temporaryCachePath + "/preview_cubemap.png", screenshotCubemapPNG); packageJSON.config.cubemapImagePath = "preview_cubemap.png"; packageJSON.config.mapColor = AverageColor(screenshotCubemap); /* quest stuff (disabled for now) * byte[] screenshotRaw = screenshot.GetRawTextureData(); * File.WriteAllBytes(Application.temporaryCachePath + "/preview_quest", screenshotRaw); */ } Object.DestroyImmediate(thumbnailCamera.gameObject); // Pre-Process stuff for both platforms - PC and Android. GameObject spawnPointContainer = new GameObject("SpawnPointContainer"); spawnPointContainer.transform.SetParent(gameObject.transform); spawnPointContainer.transform.localPosition = Vector3.zero; spawnPointContainer.transform.localRotation = Quaternion.identity; spawnPointContainer.transform.localScale = Vector3.one; List <string> spawnPointNames = new List <string>(); for (int i = 0; i < mapDescriptor.SpawnPoints.Length; i++) { Transform spawnPointTransform = mapDescriptor.SpawnPoints[i].gameObject.transform; Vector3 oldPos = spawnPointTransform.position; var oldRotation = spawnPointTransform.rotation; spawnPointTransform.SetParent(spawnPointContainer.transform); spawnPointTransform.rotation = oldRotation; spawnPointTransform.position = oldPos; string nameString = "SpawnPoint" + (i < 10 ? "0" + i : i.ToString()); mapDescriptor.SpawnPoints[i].gameObject.name = nameString; spawnPointNames.Add(nameString); } packageJSON.config.spawnPoints = spawnPointNames.ToArray(); // Replace tiling materials with baked versions foreach (Renderer renderer in gameObject.GetComponentsInChildren <Renderer>()) { if (renderer.sharedMaterial != null && renderer.sharedMaterial.shader.name.Contains("Standard Tiling") && !renderer.sharedMaterial.shader.name.Contains("Baked")) { renderer.sharedMaterial = Object.Instantiate(renderer.sharedMaterial); renderer.sharedMaterial.shader = Shader.Find("Standard Tiling Baked"); Transform rendererTransform = renderer.gameObject.transform; Vector3 newVector = RotatePointAroundPivot(rendererTransform.lossyScale, new Vector3(0, 0, 0), rendererTransform.rotation.eulerAngles); renderer.sharedMaterial.SetVector("_ScaleVector", newVector); } } // Destroy all non-render cameras because people keep accidentally exporting them foreach (Camera camera in gameObject.GetComponentsInChildren <Camera>()) { if (camera.targetTexture == null && camera.gameObject != null) { Object.DestroyImmediate(camera.gameObject); } } // Lighting stuff. Make sure to set light stuff up and make it bigger, and bake if (mapDescriptor.ExportLighting) { foreach (Light light in Object.FindObjectsOfType <Light>()) { if (light.type == LightType.Directional) { light.intensity *= 11.54f; light.color = new Color(0.3215f, 0.3215f, 0.3215f); } else { light.intensity *= 10f; } } Lightmapping.Bake(); } else { foreach (Light light in Object.FindObjectsOfType <Light>()) { Object.DestroyImmediate(light); } Lightmapping.Clear(); Lightmapping.ClearLightingDataAsset(); } gameObject.transform.localPosition = new Vector3(0, 5000, 0); // Save as prefab and build // PrefabUtility.SaveAsPrefabAsset(Selection.activeObject as GameObject, $"Assets/_{typeName}.prefab"); EditorSceneManager.SaveScene(gameObject.scene); AssetBundleBuild assetBundleBuild = default; assetBundleBuild.assetNames = new string[] { assetBundleScenePath }; assetBundleBuild.assetBundleName = pcFileName; // Build for PC BuildPipeline.BuildAssetBundles(Application.temporaryCachePath, new AssetBundleBuild[] { assetBundleBuild }, 0, BuildTarget.StandaloneWindows64); // Do Android specific stuff here. Stripping MonoBehaviours and converting them to TextAssets, etc. // first we need to redo this bit of code because sometimes gameObject unreferences itself MapDescriptor[] descriptorList2 = Object.FindObjectsOfType <MapDescriptor>(); foreach (MapDescriptor descriptor in descriptorList2) { if (descriptor.MapName != mapDescriptor.MapName) { Object.DestroyImmediate(descriptor.gameObject); } else { mapDescriptor = descriptor; gameObject = descriptor.gameObject; Selection.activeObject = gameObject; } } foreach (TagZone zone in gameObject.GetComponentsInChildren <TagZone>(true)) { if (zone != null && zone.gameObject != null) { CreateQuestText("{\"TagZone\": true}", zone.gameObject); Object.DestroyImmediate(zone); } } foreach (SurfaceClimbSettings surfaceClimbSettings in gameObject.GetComponentsInChildren <SurfaceClimbSettings>(true)) { if (surfaceClimbSettings != null && surfaceClimbSettings.gameObject != null) { SurfaceClimbSettingsJSON settingsJson = new SurfaceClimbSettingsJSON(); settingsJson.Unclimbable = surfaceClimbSettings.Unclimbable; settingsJson.slipPercentage = surfaceClimbSettings.slipPercentage; CreateQuestText(JsonUtility.ToJson(settingsJson), surfaceClimbSettings.gameObject); Object.DestroyImmediate(surfaceClimbSettings); } } int triggerCount = 1; foreach (ObjectTrigger objectTrigger in gameObject.GetComponentsInChildren <ObjectTrigger>(true)) { if (objectTrigger != null && objectTrigger.gameObject != null) { string objectName = "ObjectTrigger" + triggerCount; if (objectTrigger.ObjectToTrigger != null) { CreateQuestText("{\"TriggeredBy\": \"" + objectName + "\"}", objectTrigger.ObjectToTrigger); } ObjectTriggerJSON triggerJSON = new ObjectTriggerJSON(); triggerJSON.ObjectTriggerName = objectName; triggerJSON.OnlyTriggerOnce = objectTrigger.OnlyTriggerOnce; triggerJSON.DisableObject = objectTrigger.DisableObject; CreateQuestText(JsonUtility.ToJson(triggerJSON), objectTrigger.gameObject); Object.DestroyImmediate(objectTrigger); triggerCount++; } } int teleporterCount = 1; foreach (Teleporter teleporter in gameObject.GetComponentsInChildren <Teleporter>(true)) { if (teleporter != null && teleporter.gameObject != null) { string teleporterName = "Teleporter" + teleporterCount; foreach (Transform teleportPoint in teleporter.TeleportPoints) { if (teleportPoint != null && teleportPoint.gameObject != null) { CreateQuestText("{\"TeleportPoint\": \"" + teleporterName + "\"}", teleportPoint.gameObject); } } teleporter.TeleportPoints = null; string teleporterJSON = JsonUtility.ToJson(teleporter); teleporterJSON = teleporterJSON.Replace("\"TeleportPoints\":[],", "\"TeleporterName\": \"" + teleporterName + "\","); CreateQuestText(teleporterJSON, teleporter.gameObject); Object.DestroyImmediate(teleporter); teleporterCount++; } } RoundEndActions roundEndActions = gameObject.GetComponentInChildren <RoundEndActions>(true); if (roundEndActions != null && roundEndActions.gameObject != null) { foreach (GameObject roundEndActionObject in roundEndActions.ObjectsToEnable) { if (roundEndActionObject != null) { CreateQuestText("{\"RoundEndAction\": \"Enable\"}", roundEndActionObject); } } foreach (GameObject roundEndActionObject in roundEndActions.ObjectsToDisable) { if (roundEndActionObject != null) { CreateQuestText("{\"RoundEndAction\": \"Disable\"}", roundEndActionObject); } } RoundEndActionsJSON actionsJSON = new RoundEndActionsJSON(); actionsJSON.RoundEndActions = true; actionsJSON.RespawnOnRoundEnd = roundEndActions.RespawnOnRoundEnd; CreateQuestText(JsonUtility.ToJson(actionsJSON), roundEndActions.gameObject); Object.DestroyImmediate(roundEndActions); } Object.DestroyImmediate(mapDescriptor); // Do it again for Android EditorSceneManager.SaveScene(gameObject.scene); // PrefabUtility.SaveAsPrefabAsset(Selection.activeObject as GameObject, $"Assets/_{typeName}.prefab"); // are these next 2 lines necessary? idk. probably test it. assetBundleBuild.assetNames = new string[] { assetBundleScenePath }; assetBundleBuild.assetBundleName = androidFileName; BuildPipeline.BuildAssetBundles(Application.temporaryCachePath, new AssetBundleBuild[] { assetBundleBuild }, 0, BuildTarget.Android); EditorPrefs.SetString("currentBuildingAssetBundlePath", folderPath); // JSON stuff packageJSON.androidFileName = androidFileName; packageJSON.pcFileName = pcFileName; string json = JsonUtility.ToJson(packageJSON, true); File.WriteAllText(Application.temporaryCachePath + "/package.json", json); // AssetDatabase.DeleteAsset($"Assets/_{typeName}.prefab"); // Delete the zip if it already exists and re-zip List <string> files = new List <string> { Application.temporaryCachePath + "/" + pcFileName, Application.temporaryCachePath + "/" + androidFileName, Application.temporaryCachePath + "/package.json", Application.temporaryCachePath + "/preview.png", Application.temporaryCachePath + "/preview_cubemap.png" }; if (File.Exists(Application.temporaryCachePath + "/tempZip.zip")) { File.Delete(Application.temporaryCachePath + "/tempZip.zip"); } CreateZipFile(Application.temporaryCachePath + "/tempZip.zip", files); // After zipping, clear some assets from the temp folder if (File.Exists(path)) { File.Delete(path); } foreach (string file in files) { if (File.Exists(file)) { File.Delete(file); } } // Move the ZIP and finalize File.Move(Application.temporaryCachePath + "/tempZip.zip", path); //Object.DestroyImmediate(gameObject); AssetDatabase.Refresh(); // Open scene again EditorSceneManager.OpenScene(oldScenePath); } catch (System.Exception e) { Debug.Log("Something went wrong... let's load the old scene."); if (oldScenePath != null) { EditorSceneManager.OpenScene(oldScenePath); } else { throw new System.Exception("Something went wrong and you don't have your work saved in a scene! PLEASE save your work in a scene before trying to export."); } throw e; } }