需求起因,最近制作角色2D八方向的动画,美术提供的序列帧图片资源,角色不同动作不同方向的图片大小和角色实际的中心点是不一致的,如图所示:攻击和溃败的序列帧图片尺寸和角色在图片中心位置是不一样的。
这样会导致一个问题:在动画状态切换的时候,犹豫锚点不一致的原因会导致位置的瞬间偏移,但这样导出序列帧资源也有一个好处是最大程度的降低图片尺寸。
那么解决这个问题方案是修改序列帧图片的锚点,将图片锚点设置在角色脚下,这样切换动画的时候就会以脚底为锚点解决位置偏移的问题。
代码设置Texture锚点,只需要先设置好一个模板texture,同一个动画的其他图片根据模板设置即可,通过Texture获取到其TextureImporter,再修改SpritePivote:
TextureImporter textureIm = AssetImporter.GetAtPath(path) as TextureImporter;
textureIm.spritePivot = tempSprite.spritePivot;
在实际执行时发现这个方式并没有生效,奇怪的是,手动在SpriteEditor下设置锚点时,Pivot自动从Center切换成了==>Custom
代码批量设置spritePivot的时候,仅设置了锚点,这个对应的枚举没有变化,所以对应的pivot设置没有生效。
手动修改的Texture pivot,如下图所示,资源对应的meta文件显示,SpritePivot和上面的Alignment都修改了,alignment由0==>9
批量设置的图片,meta文件显示,仅设置了spritePivot,alignment没有变化
那显然时alignment的问题导致pivot设置失效,有意思的是在TextureImporter、Sprite、Texture里都没有看到任何和alignment有关的字段,查阅官方Api得知,alignment对应的是SpriteAlignment
查到了大概是什么原因导致的失效,但是实在是找不到在那里设置这个alignment,都已经怀疑是不是Unity没对外提供接口,准备简单粗暴的直接批处理meta文件时,在Unity的官方问答中找到了解决方案:spritePivot失效原因,需要通过TextureImporterSettings进行赋值。
工具效果如下:
代码就很简单了,没几行,代码如下:
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class GenerateSpriteEditor : EditorWindow
{
private Texture _spriteTemp;
private SerializedProperty _forceTest;
private SerializedObject _forceTestAssets;
[SerializeField]//必须要加
protected List<Texture> _assetLst = new List<Texture>();
protected void OnEnable()
{
//使用当前类初始化
_forceTestAssets = new SerializedObject(this);
//获取当前类中可序列话的属性
_forceTest = _forceTestAssets.FindProperty("_assetLst");
if (Selection.objects.Length > 0)
{
//获得所有选中的Texture对象
foreach (Texture texture in Selection.objects)
{
_assetLst.Add(texture);
}
}
}
private Vector2 _scrolPos;
private void OnGUI()
{
EditorGUILayout.BeginVertical();
{
EditorGUI.BeginChangeCheck();
{
_spriteTemp = EditorGUILayout.ObjectField("设置导出模板Sprite",_spriteTemp, typeof(Texture), false) as Texture;
}
EditorGUI.EndChangeCheck();
_scrolPos = EditorGUILayout.BeginScrollView(_scrolPos);
{
_forceTestAssets.Update();
EditorGUILayout.PropertyField(_forceTest, new GUIContent("需要批处理的Sprite"), true);
_forceTestAssets.ApplyModifiedPropertiesWithoutUndo();
}
EditorGUILayout.EndScrollView();
if (GUILayout.Button("批处理锚点"))
{
OnBtnClick();
}
}
EditorGUILayout.EndVertical();
}
private void OnBtnClick()
{
var path = AssetDatabase.GetAssetPath(_spriteTemp.GetInstanceID());
TextureImporter textureIm = AssetImporter.GetAtPath(path) as TextureImporter;
foreach (var texture in _assetLst)
{
SetSprite(texture, textureIm);
}
}
private void SetSprite(Texture exportSprite,TextureImporter tempSprite)
{
var path = AssetDatabase.GetAssetPath(exportSprite.GetInstanceID());
TextureImporter textureIm = AssetImporter.GetAtPath(path) as TextureImporter;
if (textureIm == null)
{
Debug.LogError($"sprite Is Null Spritepath = {path}");
return;
}
TextureImporterSettings texSettings = new TextureImporterSettings();
textureIm.ReadTextureSettings(texSettings);
texSettings.spriteAlignment = (int)SpriteAlignment.Custom;
textureIm.SetTextureSettings(texSettings);
textureIm.spritePivot = tempSprite.spritePivot;
AssetDatabase.ImportAsset(path);
}
}