NGUI Atlas整理工具
发表于2017-03-15
NGUI Atlas整理工具的出现是为了解决使用NGUI的Atlas时,不好去整理Atlas的问题,美术同学在开始制作时,很难完美地规划一个Sprite放在那个Atlas里,后期由于DrawCall,内存等优化需求,很可能需要把一个Sprite从一个Atlas移动到另一个,但这个时候一个尴尬的问题出现了: 已经做好的Prefab怎么办?手工调整的话,面临着工作量过大的问题,而且,很难保证不出错。于是,一个靠谱的Atlas整理工具的需求就出现了。
分左右两边,每边显示一个Atlas
功能
自动查找到使用Atlas的Prefab
自动查找到没有被使用的Sprite, 并使用红色字体标示出来
左边移动到右边,右边移动到左边,并在移动时,自动修改使用Atlas的Prefab
支持删除没有被使用的Sprite,如果有被使用,会提示用户
实现
实现还是很简单的,一个依赖查找器,和一个界面绘制类即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | public class AtlasAssetScan : ObjectSingleton { string [] PREFAB_DIRS = new string [] { "Assets/Resources/UI/Prefab/" , "Assets/ArtSource/UI/Prefab/" }; public List FindDepend(UIAtlas atlas) { var results = new List(); string atlasPath = AssetDatabase.GetAssetPath(atlas.GetInstanceID()); var list = AssetDatabase.GetAllAssetPaths(); foreach (var path in list) { if (!PREFAB_DIRS.Any((dir)=>{ return path.StartsWith(dir);})) { continue ; } var prefab = AssetDatabase.LoadMainAssetAtPath(path) as GameObject; if (prefab == null ) { continue ; } var deps = AssetDatabase.GetDependencies(path, true ); if (!deps.Contains(atlasPath)) { continue ; } results.Add(prefab); } return results; } public List< string > FindUnusedSprites(UIAtlas atlas) { } public List FindDepend(UIAtlas atlas, string spriteName) { } } string > |
扫描指定目录,使用AssetDatabase的接口,获取以来关系即可
界面绘制方面,基于Unity编辑器强大的Layout和Draw功能还是比较容易实现的
UI分割,使用了EditorGUILayoutHorizontalPanes外部组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | public static void SwitchSprite( bool left, UISpriteData sd) { UIAtlas source = null ; UIAtlas target = null ; if (left) { source = instance.leftAtlas.atlas; target = instance.rightAtlas.atlas; } else { source = instance.rightAtlas.atlas; target = instance.leftAtlas.atlas; } SwitchSprite(source, target, sd); } static void SwitchSprite(UIAtlas source, UIAtlas target, UISpriteData sd) { if (target.GetSprite(sd.name) != null ) { EditorUtility.DisplayDialog( "Error To Move" , string .Format( "不能移动 Sprite {0} 在目标atlas {1} 中有同名Sprite" , sd.name, target), "OK" ); return ; } UIAtlasMaker.SpriteEntry entry = null ; List sprites = new List(); UIAtlasMaker.ExtractSprites(source, sprites); for ( int i = sprites.Count; i > 0;) { UIAtlasMaker.SpriteEntry ent = sprites[--i]; if (ent.name == sd.name) { entry = ent; sprites.RemoveAt(i); } } UIAtlasMaker.UpdateAtlas(source, sprites); sprites.Clear(); UIAtlasMaker.ExtractSprites(target, sprites); sprites.Add(entry); UIAtlasMaker.UpdateAtlas(target, sprites); ModifyPrefab(source, target, sd.name); } |
Sprite交换,使用NGUI自带的UIAtlasMaker即可
总结
虽然只是一个小工具,但也可以大大提升工作效率,提高美术同学的幸福感
在UGUI虽然Unity把Atlas的打包过程屏蔽了起来,为我们带来了便利。但很多项目为了效率,和便于控制最终Atlas,以及AssetBundle打包等原因还是会自己拼Atlas,希望这个NGUIAtlas整理工具可以给大家带来一些启发