using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Threading; using SimpleJSON; using UnityEngine; using UnityEditor; using UnityEditor.Rendering; using UnityEngine.Assertions; using UnityEngine.XR.WSA; using UnityScript.Macros; using Debug = UnityEngine.Debug; using Assets.Config; using System.Linq; class PhotoshopExporter : 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) { var assetPathExt = Path.GetExtension(assetPath); //todo a better test would be if the psd matches /actors/*/*.psd, but no psd deeper than that if (!(assetPath.Contains(_gameConfigData.SourceAssetsRoot) & assetPathExt.Contains(".psd"))) { continue; } //todo determining whether to run the processing should be in a class method //var assetPipelineSettingsTxt = // new StreamReader("Assets/AssetPipeline/AssetPipelineSettings.json").ReadToEnd(); //var assetPipelineSettingsTxt = // new StreamReader(_gameConfigData.AssetPipelineSettings).ReadToEnd(); //var assetPipelineSettings = JSONDecoder.Decode(assetPipelineSettingsTxt); //if (!(bool) assetPipelineSettings["AssetPipeline"]["ProcessArtSrc"] || // !(bool) assetPipelineSettings["AssetPipeline"]["ProcessPSD"]) //{ // Debug.Log("PSD processing is turned off. Skipping " + assetPath); // return; //} if (!_gameConfigData.AssetPipelineSettings.ProcessArtSrc || !_gameConfigData.AssetPipelineSettings.ProcessPSD) { Debug.Log("PSD processing is turned off. Skipping " + assetPath); return; } //var psExporter = Directory.GetCurrentDirectory().Replace("\\", "/") + // "/Tools/photoshop/PhotoshopToSpine_command.jsx"; var psExporter = Directory.GetCurrentDirectory().Replace("\\", "/") + "/" + _gameConfigData.PhotoshopToSpineExportScript; //find a valid path to photoshop, not a good way to do this, should somehow be set as a per user //setting //getting this path should be in a class method var photoshopPaths = _gameConfigData.PhotoshopExeFilePaths.ToList(); //photoshopPaths.Add("C:/Program Files/Adobe/Adobe Photoshop CC 2018/Photoshop.exe"); //photoshopPaths.Add("C:/Program Files/Adobe/Adobe Photoshop CC 2017/Photoshop.exe"); //photoshopPaths.Add("C:/Program Files/Adobe/Adobe Photoshop CC 2015.5/Photoshop.exe"); //photoshopPaths.Add("/Applications/Adobe Photoshop CC 2018/Adobe Photoshop CC 2018.app/Contents/MacOS/Adobe Photoshop CC 2018"); //photoshopPaths.Add("/Applications/Adobe Photoshop CC 2017/Adobe Photoshop CC 2017.app/Contents/MacOS/Adobe Photoshop CC 2017"); var photoshopPath = ""; foreach (var testPath in photoshopPaths) { if (!File.Exists(testPath)) continue; photoshopPath = testPath; break; } if (photoshopPath == "") { throw new Exception("Cannot find Photoshop! Exports from Photoshop have failed!"); } Debug.Log("Photoshop path: " + photoshopPath); //todo put these in a class method var fullAssetPath = Path.GetFullPath(assetPath); var actorName = Path.GetFileNameWithoutExtension(assetPath).Split('_')[0]; //var doneFile = Path.GetDirectoryName(assetPath) + '/' + "photoshop_exports/export_finished.txt"; var doneFile = Path.GetDirectoryName(assetPath) + '/' + _gameConfigData.PhotoshopDoneFile; Debug.Log("Actor: " + actorName); Debug.Log("PSD: " + fullAssetPath); var psArgs = string.Format(" \"{0}\" \"{1}\"", fullAssetPath, psExporter); Debug.Log("ps args: \n" + photoshopPath + psArgs); var psProcess = new Process { StartInfo = { FileName = photoshopPath, Arguments = psArgs, CreateNoWindow = true, UseShellExecute = true, ErrorDialog = true } }; if (File.Exists(doneFile)) { File.Delete(doneFile); } // find out if PS is busy by looking for a file that only exists while PhotoshopToSpine_command.jsx is // running. Offcourse, it's also possible PhotoshopToSpine_command.jsx started running, created the busy // file and then hit an error or PS crashed, leaving the file existing forever and ever, so there needs // to be a way to abort the script while (File.Exists("Assets/ArtSrc/ArtSrc/Data/Photoshop_is_busy.txt")) { // //todo put some handling in here to notify the Unity user that PS is busy and give them a button to cancel //todo and return early //todo throw a warning that the PSD was not exported Thread.Sleep(new TimeSpan(0, 0, 2)); } Debug.Log("Executing Photoshop command"); try { // photoshop script will create the doneFile after it's finished exporting all pngs and spine json psProcess.Start(); } catch (Exception e) { Console.WriteLine(e.Message); } AssetDatabase.Refresh(); } } }