问题描述
目前我正在 Unity 中开发 2D 游戏。我正在使用 EditorWindow 对导入的 spritesheet 进行切片并从这些 sprite 创建动画。
目前,我有切片电子表格功能的代码,下面详细介绍给那些有兴趣参考的人:
public void Slice()
{
var textures = Selection.GetFiltered<Texture2D>(SelectionMode.Assets);
foreach (var texture in textures)
{
Processtexture(texture,pixelPerUnit,spriteSize,pivot,alignment);
}
}
static void Processtexture(Texture2D texture,int pixelPerUnit,Vector2Int spriteSize,Vector2 pivot,Alignment alignment)
{
string path = AssetDatabase.GetAssetPath(texture);
{
TextureImporter textureImporter =
TextureImporter.GetAtPath(path) as TextureImporter;
//Set characteristics for spritesheet
textureImporter.textureType = TextureImporterType.Sprite;
textureImporter.spriteImportMode = SpriteImportMode.Multiple;
textureImporter.spritePixelsPerUnit = pixelPerUnit;
textureImporter.filterMode = FilterMode.Point;
textureImporter.textureCompression = TextureImporterCompression.Uncompressed;
int colCount = texture.width / spriteSize.x;
int rowCount = texture.height / spriteSize.y;
//Create Spritesheet Metadata based on characteristics
List<SpriteMetaData> Metas = new List<SpriteMetaData>();
for (int c = 0; c < colCount; c++)
{
for (int r = 0; r < rowCount; r++)
{
SpriteMetaData Meta = new SpriteMetaData();
Meta.rect = new Rect(c * spriteSize.x,r * spriteSize.y,spriteSize.x,spriteSize.y);
Meta.name = (rowCount - r - 1) + "-" + c;
Meta.alignment = (int)alignment;
Meta.pivot = pivot;
Metas.Add(Meta);
}
}
//Apply the Metadata to the spritesheet
textureImporter.spritesheet = Metas.ToArray();
AssetDatabase.ImportAsset(path,ImportAssetoptions.ForceUpdate);
}
}
目前让我感到悲伤的部分是通过脚本将这个新切片的电子表格转换为动画。
目前我可以使用下面的代码片段在 spritesheet 的目录中创建一个空的动画剪辑:
string path = AssetDatabase.GetAssetPath(texture);
string newPath = Path.GetDirectoryName(path);
AnimationClip clip = new AnimationClip();
AssetDatabase.CreateAsset(clip,newPath + "\\" + spriteName ".anim");
我很难找到如何向这个新创建的动画添加精灵。我查看了 AnimationCurves 和 AnimationEvents,但似乎找不到通过编辑器将精灵链接到动画的步骤。
如果有人有通过脚本创建统一动画剪辑的经验或知识,我们将不胜感激。如果我需要更多信息,请告诉我。这是我第一次使用这项服务。谢谢大家的帮助!
解决方法
我在此发布我的决议,以供其他人参考!我最终引用了文章 Create Animation Clip from Sprite[] (Programmatically) 和 How to get child sprites from a 'Multiple Sprite' Texture。
通过编辑器窗口从选定的精灵表创建动画的结果代码粘贴如下:
public void Animate()
{
var textures = Selection.GetFiltered<Texture2D>(SelectionMode.Assets);
foreach (var texture in textures)
{
GenerateAnimations(texture,spriteSize,spriteName);
}
}
static void GenerateAnimations(Texture2D texture,Vector2Int spriteSize,string spriteNameGlobal)
{
//Create an Array of all sprites in the selected texture
string path = AssetDatabase.GetAssetPath(texture);
Sprite[] allSprites = AssetDatabase.LoadAllAssetsAtPath(path).OfType<Sprite>().ToArray();
string newPath = Path.GetDirectoryName(path);
//Determine the number of rows & columns based on preset "spriteSize" Vector2
int colCount = texture.width / spriteSize.x;
int rowCount = texture.height / spriteSize.y;
//Loop through each row of the spritesheet to make an animation
for (int i = 0; i < rowCount; i++)
{
//Create a sprite subsection for a row of sprites
Sprite[] batchSprites = new Sprite[colCount];
for (int j = 0; j < batchSprites.Length; j++)
{
batchSprites[j] = allSprites[i * colCount + j];
}
//Create the base AnimationClip
AnimationClip clip = new AnimationClip();
clip.frameRate = 12f;
//Create the CurveBinding
EditorCurveBinding spriteBinding = new EditorCurveBinding();
spriteBinding.type = typeof(SpriteRenderer);
spriteBinding.path = "";
spriteBinding.propertyName = "m_Sprite";
//Create the KeyFrames
ObjectReferenceKeyframe[] spriteKeyFrames = new ObjectReferenceKeyframe[colCount];
for (int j = 0; j < spriteKeyFrames.Length; j++)
{
spriteKeyFrames[j] = new ObjectReferenceKeyframe();
spriteKeyFrames[j].time = j/clip.frameRate;
spriteKeyFrames[j].value = batchSprites[j];
}
AnimationUtility.SetObjectReferenceCurve(clip,spriteBinding,spriteKeyFrames);
//Set Loop Time to True
AnimationClipSettings settings = AnimationUtility.GetAnimationClipSettings(clip);
settings.loopTime = true;
AnimationUtility.SetAnimationClipSettings(clip,settings);
//Save the clip
AssetDatabase.CreateAsset(clip,newPath + "\\" + spriteNameGlobal + i + ".anim");
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
在使用此代码时,如果不小心会弹出一些有趣的问题。一个主要的问题是没有将 spriteBinding.propertyname 设置为“m_Sprite”。如果您决定修改此代码,请注意这一点。
我希望这证明有用!如果有任何不清楚的地方,或者有进一步的建议以澄清问题,请回复,我可以尝试改进此回复。