RebuildDatabase(GameObject go) { // list up all assets from root so far... List <string> allAssets = new List <string>(); Stack <string> paths = new Stack <string>(); paths.Push(Application.dataPath); while (paths.Count != 0) { string path = paths.Pop(); string[] files = Directory.GetFiles(path, "*.asset"); foreach (var e in files) { allAssets.Add(e.Substring(Application.dataPath.Length - 6)); } foreach (string e in Directory.GetDirectories(path)) { paths.Push(e); } } var database = go.GetComponent <SsAssetDatabase>(); foreach (var path in allAssets) { // add only SsAnimation to the list SsAnimation e = AssetDatabase.LoadAssetAtPath(path, typeof(SsAnimation)) as SsAnimation; if (e != null) { database.AddAnime(e); CreateSpritePrefab(e); } } }
public void AddAnime(SsAnimation anm) { CleanupAnimeList(); foreach (var e in animeList) if (e == anm) return; animeList.Add(anm); }
// Create game object with this script and animation which in 'Resources' folder. static public GameObject CreateGameObjectWithAnime(string name, string animName) { GameObject go = new GameObject(name); SsSprite sprite = go.AddComponent <SsSprite>(); SsAnimation anim = (SsAnimation)Resources.Load(animName, typeof(SsAnimation)); sprite.Animation = anim; return(go); }
void OnEnable() { _anime = target as SsAnimation; // _database = SsAssetPostProcessor.GetDatabase(); // if (!_database) // { // Debug.LogWarning("SpriteStudioDatabase not found"); // } }
void OnEnable() { _anime = target as SsAnimation; // _database = SsAssetPostProcessor.GetDatabase(); // if (!_database) // { // Debug.LogWarning("SpriteStudioDatabase not found"); // } }
CreateSpritePrefab(SsAnimation anime) { var po = new PrefabricatableObject("SpriteStudioPrefabs", anime.name); SsSprite spr = po.GetOrAddComponent <SsSprite>(); spr.Animation = null; // force to update when the same animation attached spr.Animation = anime; #if UNITY_4_0 || UNITY_4_1 || UNITY_4_2 || UNITY_4_3 || UNITY_4_4 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9 spr.gameObject.SetActive(true); #endif po.Close(true); }
public void AddAnime(SsAnimation anm) { CleanupAnimeList(); foreach (var e in animeList) { if (e == anm) { return; } } animeList.Add(anm); }
void ChangeAnime(string name, int loop) { SsAnimation anm = SsAssetDatabase.Instance.GetAnime(name); _sprite.PlayCount = loop; _sprite.Animation = anm; if (loop == 1) { _sprite.AnimationFinished = AnimeFinished; } else { _sprite.AnimationFinished = null; } }
public override void OnInspectorGUI() { EditorGUILayout.BeginHorizontal(); { EditorGUILayout.LabelField("AnimeList", (string)null, GUILayout.MaxWidth(60)); if (GUILayout.Button("Pickup")) { Undo.RegisterUndo(_target, "Pickup"); // trim _target.CleanupAnimeList(); // find all anims attached to sprites in scene var sprites = FindObjectsOfType(typeof(SsSprite)) as SsSprite[]; foreach (var e in sprites) { SsAnimation anm = e.Animation; if (!anm) { continue; } _target.AddAnime(anm); } } if (GUILayout.Button("Add")) { Undo.RegisterUndo(_target, "Add"); _target.animeList.Add(null); } if (GUILayout.Button("Clear")) { Undo.RegisterUndo(_target, "Clear"); _target.animeList.Clear(); } if (PrefabUtility.GetPrefabType(_target) == PrefabType.Prefab || PrefabUtility.GetPrefabType(_target) == PrefabType.PrefabInstance) { if (GUILayout.Button("Instantiate")) { var obj = Instantiate(_target); Undo.RegisterCreatedObjectUndo(obj, "Instantiate"); obj.name = SsAssetDatabase.fileName; } } } EditorGUILayout.EndHorizontal(); DrawDefaultInspector(); }
// Replace animation without rebuilding mesh. // This is faster than changing animation via Animation property. // This requires the equality of parts struct between before and after. // Do the same behaviour as Animation property if no animation is set. public void ReplaceAnimation(SsAnimation anm) { if (!_animation) { // do the same Animation property because it needs to build a mesh. Animation = anm; return; } if (anm.PartList.Length != _animation.PartList.Length) { Debug.LogError("Can't replace animation because of the difference of the parts count.\n" + anm.name + ": " + anm.PartList.Length + " " + _animation.name + ": " + _animation.PartList.Length); return; } _animation = anm; if (anm == _prevAnimation) { return; } if (!_animation) { Init(); return; } // initialize values ResetAnimationStatus(); Pause(); // get parts and images. _partResList = _animation.PartList; _imageList = _animation.ImageList; _partsNum = _partResList.Length; // replace parts resources for (int i = 0; i < _parts.Length; ++i) { _parts[i]._res = _partResList[i]; } // must invoke vertex update to display initial posed animation. _vertChanged = true; // also must update uv _uvChanged = true; // reflect blend settings to shader _extraChanged = true; // to fix the problem that h/vFlipped animation from initial time doesn't affects mesh. // created children transforms are updated inside. UpdateAlways(); // init animation range _startAnimeFrame = 0; if (_animation) { _endAnimeFrame = _animation.EndFrame; } else { _endAnimeFrame = 0; } _prevAnimation = _animation; // auto start after changed if (PlayAtStart && Application.isPlaying) { Play(); } }
OnPostprocessAllAssets( string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { // reject re-entering for files unnecessary to import during an another file is created internally. if (_s_rejectReenter) { // Debug.LogError("REJECT ->" + importedAssets[0]); return; } string dbFilename = Path.GetFileName(SsAssetDatabase.filePath); // ignore database import if (importedAssets.Length == 1 && importedAssets[0].EndsWith(dbFilename, _pathComparison)) { #if _RELINK_DB_OBJECT_TO_PREFAB UpdateDatabaseObjectInHierarchy(); #endif // Debug.LogWarning("IGNORE Database"); return; } // if (importedAssets.Length > 0) // Debug.Log("ENTER importing " + importedAssets[0] + " count: " + importedAssets.Length); // reject reenter this function while importing new generated files. _s_rejectReenter = true; try { AssetDatabase.Refresh(); // get game object contains database GameObject databaseGo = GetDatabaseGo(); bool createDatabase = false; // make database first to assure the existing. if (databaseGo == null) { createDatabase = true; } else { // ignore database delete and re-create it if (deletedAssets.Length > 0 && deletedAssets[0].EndsWith(dbFilename, _pathComparison)) { createDatabase = true; } } if (createDatabase) { // create database // Debug.LogWarning("Create Database: " + databaseGo); var go = CreateDatabaseGo(); RebuildDatabase(go); databaseGo = SaveDatabase(go); } _database = databaseGo.GetComponent <SsAssetDatabase>(); int prevAnimeListCount = _database.animeList.Count; // filter imported files and create assets as needed foreach (var name in importedAssets) { // ignore database file in filename list if (name.EndsWith(dbFilename, _pathComparison)) { continue; } #if _GENERATE_SHADERS if (name.EndsWith(_shaderTemplateFilename, _pathComparison)) { BuildShaders(name); } #endif if (name.EndsWith(".ssax", _pathComparison)) { SsaxImporter v = SsaxImporter.Create(name); if (v != null) { var anm = v.AnimeRes; CreateSpritePrefab(anm); _database.AddAnime(anm); } } } // assets will be deleted foreach (var name in deletedAssets) { if (!name.EndsWith(".asset", _pathComparison)) { continue; } Object asset = AssetDatabase.LoadAssetAtPath(name, typeof(SsAnimation)); // remove animation element from list SsAnimation anim = asset as SsAnimation; if (anim == null) { continue; } _database.animeList.Remove(anim); } // cleanup null elements in the database _database.CleanupAnimeList(); if (_database.animeList.Count != prevAnimeListCount) { // apply modification of database to actual file EditorUtility.SetDirty(databaseGo); } AssetDatabase.SaveAssets(); #if _RELINK_DB_OBJECT_TO_PREFAB // update game object refers to the database prefab UpdateDatabaseObjectInHierarchy(); #endif } catch { // Debug.LogWarning("ABORT importing"); throw; } finally { _s_rejectReenter = false; // Debug.Log("LEAVE importing"); } }
Load(string srcPath) { _database = SsAssetPostProcessor.GetDatabase(); string path = Path.GetDirectoryName(srcPath); // new path name of ss anime asset string newPath = path + "/assets/" + Path.GetFileNameWithoutExtension(srcPath) + "_ssa.asset"; // identify the encoding which is Shift-JIS or UTF-8 Encoding encode = SsEncoding.SJIS; { StreamReader sr = File.OpenText(srcPath); string xmlHeaderText = sr.ReadLine(); // XmlDocument requires one node at least and also needs to get "encoding" attribute. string dummy = System.String.Copy(xmlHeaderText); dummy = dummy.Replace("<?xml", "<Dummy"); dummy = dummy.Replace("?>", "/>"); xmlHeaderText += dummy; sr.Close(); XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlHeaderText); XmlNode node = doc.FirstChild.NextSibling; string encStr = node.Attributes["encoding"].Value; if (encStr == "shift_jis") { encode = SsEncoding.SJIS; } else if (encStr == "utf-8") { encode = SsEncoding.UTF8; } } // to read SJIS encoded text correctly. string textAll = File.ReadAllText(srcPath, encode); // create directory if it doesn't exist. bool newAsset = false; if (!Directory.Exists(path + "/assets")) { AssetDatabase.CreateFolder(path, "assets"); } else { // try to open existing asset _anmRes = AssetDatabase.LoadAssetAtPath(newPath, typeof(SsAnimation)) as SsAnimation; } if (_anmRes == null) { // create new asset _anmRes = ScriptableObject.CreateInstance <SsAnimation>(); newAsset = true; } else { // update existing asset ClearPreviousMaterials(); _anmRes.ImageList = null; _anmRes.PartList = null; System.GC.Collect(); } // update imported time _anmRes.UpdateImportedTime(); // save original resource path _anmRes.OriginalPath = srcPath; // save scale factor at this import. if (!_anmRes.UseScaleFactor) { _anmRes.ScaleFactor = _database.ScaleFactor; } #if _BUILD_UNIFIED_SHADERS if (_anmRes._UseUnifiedShader == UseUnifiedShaderEnum.Default) { // use global setting _anmRes.UseUnifiedShader = _database.UseUnifiedShader; } else { // use own setting _anmRes.UseUnifiedShader = (_anmRes._UseUnifiedShader == UseUnifiedShaderEnum.Yes); } #endif if (!LoadXml(path, textAll)) { Debug.LogError("Failed to import animation data: " + srcPath); return(false); } if (newAsset) { AssetDatabase.CreateAsset(_anmRes, newPath); } else { // modification done internally is not applied actual file, so must make it dirty before. EditorUtility.SetDirty(_anmRes); AssetDatabase.SaveAssets(); //same as EditorApplication.SaveAssets(); } #if false // AddObjectToAsset() a_mat.mat -> hoge.ssax.asset // ↓ // hoge.ssax.mat // hoge.ssax.asset // umm... foreach (var e in _anmRes.ImageList) { if (e.material != null) { e.material.name = e.texture.name + "_Mat"; AssetDatabase.AddObjectToAsset(e.material, _anmRes); // Reimport the asset after adding an object. // Otherwise the change only shows up when saving the project AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(e.material)); } } #endif return(true); }
// Replace animation without rebuilding mesh. // This is faster than changing animation via Animation property. // This requires the equality of parts struct between before and after. // Do the same behaviour as Animation property if no animation is set. public void ReplaceAnimation(SsAnimation anm) { if (!_animation) { // do the same Animation property because it needs to build a mesh. Animation = anm; return; } if (anm.PartList.Length != _animation.PartList.Length) { Debug.LogError("Can't replace animation because of the difference of the parts count.\n" + anm.name + ": " + anm.PartList.Length + " " + _animation.name + ": " + _animation.PartList.Length); return; } _animation = anm; if (anm == _prevAnimation) return; if (!_animation) { Init(); return; } // initialize values ResetAnimationStatus(); Pause(); // get parts and images. _partResList = _animation.PartList; _imageList = _animation.ImageList; _partsNum = _partResList.Length; // replace parts resources for (int i = 0; i < _parts.Length; ++i) { if (i >= _partResList.Length) break; SsPartRes partRes = _partResList[i]; SsImageFile image = partRes.IsRoot ? null : _imageList[partRes.SrcObjId]; _parts[i].ReplaceResource(partRes, image); if (i >= 1) { // update material buffer _materials[i - 1] = _parts[i]._material; } } // must invoke vertex update to display initial posed animation. _vertChanged = true; // also must update uv _uvChanged = true; // also may update priority _prioChanged = true; // reflect blend settings to shader _extraChanged = true; // to fix the problem that h/vFlipped animation from initial time doesn't affects mesh. // created children transforms are updated inside. UpdateAlways(); // init animation range _startAnimeFrame = 0; if (_animation) _endAnimeFrame = _animation.EndFrame; else _endAnimeFrame = 0; _prevAnimation = _animation; // auto start after changed if (PlayAtStart && Application.isPlaying) Play(); }