|
一般我们做UI的时候会是这样的-----美术做张效果图,然后在切图给程序,程序在照着效果图来拼UI,可是明明美术以及拼好了啊,程序又需要在拼一次,下面我们来看看如何优化这一过程。
起因是这样的:
Unity3D提供了一种PSB资源文件直接转为Prefab的方案,通过这个可以方便的创建2d sprite 骨骼以及动画,有关2D PSD Importer的详细介绍可以查看官方的资料或者一位B站Up的视频
上面这一系列视频的开头介绍了PSD Importer的用法。
后来我就想能不能使用这个方法来处理UI呢?这样如果配合一些代码自动生成的方法,再加上PSD直接转为Prefab,这两者组合,将会为写UI的同学提供极大的便利,下面简单介绍一下如何修改官方的代码来实现我们的功能。
首先将2D PSDImporter添加到工程中
Window->Package Manager 中添加2D PSDImporter
然后我们在package中找到它
然后把它挪到我们的工程中去
放到当前工程中后,就可以在Package Manager中移除掉PSD Importer,但是PSDImporter 依赖了另外三个package,我们不能少了这几位。
下面我们来修改代码,首先找到PSDImporter.cs中的OnProducePrefab函数,这个函数就在读取PSB中的相关层的信息并创建物体,我们可以通过修改这个方法来实现我们的效果
GameObject OnProducePrefab(string assetname, Sprite[] sprites, SpriteLibraryAsset s)
{
GameObject root = null;
if (sprites != null && sprites.Length > 0)
{
var spriteImportData = GetSpriteImportData();
root = new GameObject();
root.name = assetname + "_GO";
RectTransform rectTransform = root.AddComponent<RectTransform>();
// /root.AddComponent<GraphicRaycaster>();
var canvas = root.AddComponent<Canvas>();
root.AddComponent<CanvasGroup>();
rectTransform.sizeDelta = new Vector2(750, 1334);
var psdLayers = GetPSDLayers();
for (int i = 0; i < psdLayers.Count; ++i)
{
BuildGroupGameObject(psdLayers, i, root.transform);
}
//var boneGOs = CreateBonesGO(root.transform);
for (int i = 0; i < psdLayers.Count; ++i)
{
var l = psdLayers;
GUID layerSpriteID = l.spriteID;
var sprite = sprites.FirstOrDefault(x => x.GetSpriteID() == layerSpriteID);
var spriteMetaData = spriteImportData.FirstOrDefault(x => x.spriteID == layerSpriteID);
if (sprite != null && spriteMetaData != null && l.gameObject != null)
{
//spriteRenderer.sortingOrder = psdLayers.Count - i;
var uvTransform = spriteMetaData.uvTransform;
var outlineOffset = new Vector2(spriteMetaData.rect.x - uvTransform.x + (spriteMetaData.pivot.x * spriteMetaData.rect.width),
spriteMetaData.rect.y - uvTransform.y + (spriteMetaData.pivot.y * spriteMetaData.rect.height)) * definitionScale / sprite.pixelsPerUnit;
Vector3 pos = new Vector3(outlineOffset.x, outlineOffset.y, 0);
pos = new Vector3(pos.x * sprite.pixelsPerUnit - rectTransform.sizeDelta.x / 2, pos.y * sprite.pixelsPerUnit - rectTransform.sizeDelta.y / 2, 0);
l.gameObject.transform.position = pos;
var spriteRenderer = l.gameObject.AddComponent<Image>();
//var spriteRenderer = l.gameObject.AddComponent<SpriteRenderer>();
spriteRenderer.sprite = sprite;
spriteRenderer.SetNativeSize();
}
}
}
return root;
}
rectTransform.sizeDelta =newVector2(750,1334);
这一行可以设置成你所想要的分辨率,或者各个项目框架的UI分辨率,whatever
pos =newVector3(pos.x * sprite.pixelsPerUnit - rectTransform.sizeDelta.x /2, pos.y * sprite.pixelsPerUnit - rectTransform.sizeDelta.y /2,0);
原来是在世界坐标中进行坐标计算,现在在UI坐标中需要进行坐标的转化放大处理
<hr/>下面让美术来个测试用的PSB文件试试看
所有的层都被放在了它改在的位置,可以看见美术的图层命名还是不太规范的,之后就可以通过图层的名字来自定义各种各样的规则,比如图层名字含有_Button,就自动添加Button组件等等,这些留给大家自行扩展。
总结
PSB文件可以直接生成Prefab,然后就可以根据Prefab自动化生成脚本,这样就大大加速了UI的开发速度,但是我们也需要对生成的UI进行一些其他的处理,比如锚点对其方式等等。
最后Github地址 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|