unity2D使用序列帧做动画,一般都用2d SpriteRenderer,它的好处是能够沿用图片原有的大小和锚点。特别是我们使用TexturePacker打图集的时候并且Trim边缘空白的时候,可以直接使用它,而不用在程序中调整它的位置等信息。
然而我们如果使用UGUI系统,SpriteRender缺有挺多冲突,特别是当我们组合使用的时候,渲染顺序导致的问题很多。所以我期望有一个基于UGUI的动画解决方案。
研究了一下,unity官方貌似并不提供这种基础组件,于是没办法,自己写了一个。如果你有更好的办法,请告诉我。
我自己基本的实现需求和原理是
* 要求在Editor模式下所见即所得的看到序列帧切换动画效果
* 要求能够读入并延续Sprite上自带的位置、锚点信息
* 轻量级
* 要求能够翻转,能够被外部程序所控制
实现代码见后文,使用方法:
* 将此脚本与Image绑定在同一个GameObject上
* 将你要使用的序列帧随便一帧绑定到sprite参数上
* 调整xoffset和yoffset,保证对齐到锚点
* 如果需要翻转,请将第一步的GameObject绑定到一个长宽为0的父节点上,并且点击EnableFlipX
* 在代码中调用,只需修改sprite或flipX属性后,调用Refresh()方法即可
/// <summary>
/// UGUI animation Component.
///
/// 使用方法:把他和Image组件挂在同一个GameObject上,调整好偏移。
/// 动画不要修改Image组件的sprite,修改本组件sprite即可。
///
/// author:CG
/// hanjiasongshu.com
/// </summary>
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System;
[ExecuteInEditMode]
public class UGUIAnimation : MonoBehaviour {
public Sprite sprite;
public float xoffset = 0;
public float yoffset = 0;
public Color color = Color.white;
/// <summary>
/// 启动flipx,需要有一个parent GameObject
/// </summary>
public bool enableFlipX = false;
public bool flipX;
void OnValidate(){
Refresh();
}
public void Refresh(){
SetSprite(sprite);
}
void SetSprite(Sprite s){
if(s == null ) return;
var image = this.GetComponent<Image>();
image.sprite = s;
image.rectTransform.sizeDelta = new Vector2( s.rect.width, s.rect.height);
var pos1x = 0.5f * s.rect.width - s.pivot.x;
var pos1y = 0.5f * s.rect.height - s.pivot.y;
image.transform.localPosition = new Vector3( pos1x + xoffset, pos1y + yoffset);
image.color = color;
if(enableFlipX){
if(flipX){
this.transform.parent.transform.localRotation = new Quaternion(0, -180f, 0, 0);
}else{
this.transform.parent.transform.localRotation = new Quaternion(0, 0, 0, 0);
}
}
}
}