using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading; using UnityEngine; using UnityEditor; using Debug = UnityEngine.Debug; using Assets.Config; using Spine; using Object = System.Object; class PhotoshopLayersProcessor : AssetPostprocessor { private static GameConfigData _gameConfigData; static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { _gameConfigData = GameConfigDataManager.GetGameData(); // todo getting paths should be in a utility class //var actorsSrcPath = "Assets/ArtSrc/Actors"; var actorsSrcPath = _gameConfigData.ActorsSrcPath; foreach (string assetPath in importedAssets) { if (!(assetPath.Contains("export_finished.txt"))) { continue; } //todo put these in a class method var fullAssetPath = Path.GetFullPath(assetPath); //todo you idiot! break apart these paths the normal way, by splitting on the dir seperator! var assetName = new DirectoryInfo(Path.GetDirectoryName(Path.GetDirectoryName(assetPath))).Name; var assetType = new DirectoryInfo(Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(assetPath)))).Name; Debug.Log("doneFile: " + fullAssetPath); Debug.Log("assetName: " + assetName); switch (assetType) { case "Actors": //todo there should be much if any asset processing code in the switch, most of that should be tucked away //todo into their own classes, so that this script is just control flow //todo yet again, get this path from a class method, this is shitty code that will be prone to breaking var spineDoc = Path.GetDirectoryName(Path.GetDirectoryName(assetPath)) + '/' + assetName + ".spine"; Debug.Log("spineDoc: " + spineDoc); if (!File.Exists(spineDoc)) continue; Debug.Log("Reimporting " + spineDoc); AssetDatabase.ImportAsset(spineDoc); break; case "Environments": case "SceneLaunchers": //todo there should be much if any asset processing code in the switch, most of that should be tucked away //todo into their own classes, so that this script is just control flow var jsonPath = Directory.GetFiles(Path.GetDirectoryName(assetPath), "*.json")[0]; Debug.Log("jsonPath: " + jsonPath); var reader = new StreamReader(new FileStream(jsonPath, FileMode.Open, FileAccess.Read, FileShare.Read)); var root = Json.Deserialize(reader) as Dictionary; var parentGameObject = new GameObject(assetName); var layerDepth = 1; foreach (KeyValuePair skinMap in (Dictionary) root["skins"]) { foreach (KeyValuePair slotEntry in (Dictionary) skinMap.Value) { var skinMaps = (Dictionary) skinMap.Value; if (layerDepth == 1) { //this means the front most layer will sort be sorted to -1, ensuring actors are on top layerDepth = (skinMaps.Count + 1) * -1; } foreach (KeyValuePair layerPng in ((Dictionary) slotEntry .Value)) { var properties = (Dictionary) layerPng.Value; Debug.Log("layerPng: " + layerPng.Key); var spriteGameObject = new GameObject(layerPng.Key); var spriteRenderer = spriteGameObject.AddComponent(); var spritePath = Path.GetDirectoryName(assetPath) + "/" + layerPng.Key + ".png"; if (!File.Exists(spritePath)) { Debug.LogWarning(string.Format("Cannot prefab {0}. File doesn't exist!", spritePath)); continue; } Debug.Log(String.Format("adding {0} to game object", spritePath)); var importerSettings = (TextureImporter) TextureImporter.GetAtPath(spritePath); if (importerSettings.textureType != TextureImporterType.Sprite) { importerSettings.textureType = TextureImporterType.Sprite; importerSettings.SaveAndReimport(); } spriteRenderer.sprite = AssetDatabase.LoadAssetAtPath(spritePath); if (spriteRenderer.sprite == null) { Debug.LogWarning("Skipping. Could not load sprite!"); continue; } // spriteRenderer.sprite = sprite; layerDepth += 1; spriteRenderer.sortingOrder = layerDepth; Debug.Log("layerDepth: " + layerDepth); Debug.Log("spritePixelsPerUnit: " + importerSettings.spritePixelsPerUnit); spriteGameObject.transform.position = new Vector3( (float) properties["x"] / importerSettings.spritePixelsPerUnit, ((float) properties["y"]) / importerSettings.spritePixelsPerUnit, 0); spriteGameObject.transform.parent = parentGameObject.transform; spriteGameObject.transform.position = spriteGameObject.transform.TransformPoint(0.0f, 0.0f, 0.0f); } } } //todo this should be taken from the gameconfig class const string prefabsDir = "Assets/Prefabs"; if (!Directory.Exists(prefabsDir)) { Debug.Log("Created " + prefabsDir); Directory.CreateDirectory(prefabsDir); } var prefabTargetPath = string.Format("{1}/{0}.prefab", assetName, prefabsDir); Debug.Log("Creating " + prefabTargetPath); //todo bane, please replace the below with the gameconfig path to where prefabs are stored PrefabUtility.CreatePrefab(prefabTargetPath, parentGameObject); UnityEngine.Object.DestroyImmediate(parentGameObject); break; default: Debug.Log("There is no PSD postprocessor for " + assetType); return; } //remove the doneFile so that it triggers this Postprocessor the next time there's a PS export AssetDatabase.DeleteAsset(assetPath); AssetDatabase.Refresh(); } } }