UnityEditor-批处理Texture,spriteEditor,代码设置Pivot失效问题

需求起因,最近制作角色2D八方向的动画,美术提供的序列帧图片资源,角色不同动作不同方向的图片大小和角色实际的中心点是不一致的,如图所示:攻击和溃败的序列帧图片尺寸和角色在图片中心位置是不一样的。

UnityEditor-批处理Texture,spriteEditor,代码设置Pivot失效问题_第1张图片UnityEditor-批处理Texture,spriteEditor,代码设置Pivot失效问题_第2张图片

这样会导致一个问题:在动画状态切换的时候,犹豫锚点不一致的原因会导致位置的瞬间偏移,但这样导出序列帧资源也有一个好处是最大程度的降低图片尺寸。

那么解决这个问题方案是修改序列帧图片的锚点,将图片锚点设置在角色脚下,这样切换动画的时候就会以脚底为锚点解决位置偏移的问题。

代码设置Texture锚点,只需要先设置好一个模板texture,同一个动画的其他图片根据模板设置即可,通过Texture获取到其TextureImporter,再修改SpritePivote:

TextureImporter textureIm = AssetImporter.GetAtPath(path) as TextureImporter;

textureIm.spritePivot = tempSprite.spritePivot;

在实际执行时发现这个方式并没有生效,奇怪的是,手动在SpriteEditor下设置锚点时,Pivot自动从Center切换成了==>Custom

代码批量设置spritePivot的时候,仅设置了锚点,这个对应的枚举没有变化,所以对应的pivot设置没有生效。

UnityEditor-批处理Texture,spriteEditor,代码设置Pivot失效问题_第3张图片

手动修改的Texture pivot,如下图所示,资源对应的meta文件显示,SpritePivot和上面的Alignment都修改了,alignment由0==>9

UnityEditor-批处理Texture,spriteEditor,代码设置Pivot失效问题_第4张图片

批量设置的图片,meta文件显示,仅设置了spritePivot,alignment没有变化

UnityEditor-批处理Texture,spriteEditor,代码设置Pivot失效问题_第5张图片

那显然时alignment的问题导致pivot设置失效,有意思的是在TextureImporter、Sprite、Texture里都没有看到任何和alignment有关的字段,查阅官方Api得知,alignment对应的是SpriteAlignment

UnityEditor-批处理Texture,spriteEditor,代码设置Pivot失效问题_第6张图片

查到了大概是什么原因导致的失效,但是实在是找不到在那里设置这个alignment,都已经怀疑是不是Unity没对外提供接口,准备简单粗暴的直接批处理meta文件时,在Unity的官方问答中找到了解决方案:spritePivot失效原因,需要通过TextureImporterSettings进行赋值。

工具效果如下:

UnityEditor-批处理Texture,spriteEditor,代码设置Pivot失效问题_第7张图片

代码就很简单了,没几行,代码如下:

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class GenerateSpriteEditor : EditorWindow
{
    private Texture _spriteTemp;
    private SerializedProperty _forceTest;
    private SerializedObject _forceTestAssets;
    [SerializeField]//必须要加
    protected List _assetLst = new List();

    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);
    }
}

 

你可能感兴趣的:(UnityEditor)