Unity实现持续点击按钮播放帧动画的效果

前言

在最近的开发中,有这样的一个需求,按住按钮实现帧序列的变化,实现向前播放的动画或者向后倒退的动画。我试了几种方法,最终实现了这一个效果。具体实现方法如下所示:

实现步骤

1.新建工程,导入序列帧,如下图所示。

unity 当前播放动画 unity点击播放动画_unity 当前播放动画


2.在场景中新建一个Image组件,用于切换帧序列,如下图所示:

unity 当前播放动画 unity点击播放动画_Time_02


3.新建ChangeImage.cs脚本,用于动态切换帧序列,脚本代码如下图所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ChangeImages : MonoBehaviour 
{
	//图片精灵数组
	public Sprite[] thisSprite;
	//显示图片
	public Image thisImage;
	//图片数组
	public int imageNumber = 0;

	public void AddImage()
	{
		if (imageNumber < 140)
		{
			imageNumber++;
			StartCoroutine(ToShowAddImage());
		}
	}

	public void DelImage()
	{
		if (imageNumber > 0)
		{
			imageNumber--;
			StartCoroutine(ToShowAddImage());
		}
	}

	IEnumerator ToShowAddImage()
	{
		yield return new WaitForSeconds(0.1f);
		thisImage.sprite = thisSprite[imageNumber];
	}

}

4.将ChangeImage.cs脚本挂载到场景中的Canvas上,将序列帧和Image组件赋值到该脚本上,如下图所示:

unity 当前播放动画 unity点击播放动画_Time_03


5.在场景中新添加两个按钮,用于控制动画的播放,如图所示:

unity 当前播放动画 unity点击播放动画_Time_04


6.新建按钮控制脚本ButtonManager.cs和ButtonManager0.cs,这两个脚本分别控制动画的前进和倒退(其实完全使用一个脚本就可以,或者使用继承,我在这里是偷个懒),脚本代码如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

/// <summary>
/// 继承:按下,抬起和离开的三个接口
/// </summary>
public class ButtonManager : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
    //延迟时间
    public float delay = 0f;
    //按钮是否是按下状态
    public bool isDown = false;
    //按钮最后一次是被按住时持续的时间
    public float lastIsDownTime;
    //改变图片
    public ChangeImages changeImages;
    //是否开始发送
    public bool isCount = true;
    //计时
    public double countTime = 0f;

    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        InputButtonDown();
    }
    //按钮连续按下执行的方法
    public virtual void InputButtonDown()
    {
        //如果按钮是被按下状态
        if (isDown)
        {
            //当前时间 - 按钮最后一次被按下的时间 > 延迟时间0.2秒
            if (Time.time - lastIsDownTime > delay)
            {
                //触发长按的方法
                ToSend();
                //记录按钮最后一次被按下的时间
                lastIsDownTime = Time.time;
            }
        }
    }

    void ToSend() 
    {
        if (isCount) 
        {
            countTime += Time.deltaTime;
            if (countTime > 0.01f)
            {
                isCount = false;
                changeImages.AddImage();
                countTime = 0f;
                StartCoroutine(ToReStartCount());
            }
        }
    }

    IEnumerator ToReStartCount()
    {
        yield return new WaitForSeconds(0.1f);
        isCount = true;
    }

    //当按钮被按下后系统自动调用此方法
    public void OnPointerDown(PointerEventData eventData)
    {
        isDown = true;
        lastIsDownTime = Time.time;
    }
    //当按钮抬起的时候自动调用此方法
    public void OnPointerUp(PointerEventData eventData)
    {
        isDown = false;
        isCount = true;
        countTime = 0f;
    }
    //当鼠标从按钮上离开时调用此方法
    public void OnPointerExit(PointerEventData eventData)
    {
        isDown = false;
        isCount = true;
        countTime = 0f;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

/// <summary>
/// 继承:按下,抬起和离开的三个接口
/// </summary>
public class ButtonManager0 : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler
{
    //延迟时间
    public float delay = 0f;
    //按钮是否是按下状态
    public bool isDown = false;
    //按钮最后一次是被按住时持续的时间
    public float lastIsDownTime;
    //改变图片
    public ChangeImages changeImages;
    //是否开始发送
    public bool isCount = true;
    //计时
    public double countTime = 0f;

    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        InputButtonDown();
    }
    //按钮连续按下执行的方法
    public virtual void InputButtonDown()
    {
        //如果按钮是被按下状态
        if (isDown)
        {
            //当前时间 - 按钮最后一次被按下的时间 > 延迟时间0.2秒
            if (Time.time - lastIsDownTime > delay)
            {
                //触发长按的方法
                ToSend();
                //记录按钮最后一次被按下的时间
                lastIsDownTime = Time.time;
            }
        }
    }

    void ToSend() 
    {
        if (isCount) 
        {
            countTime += Time.deltaTime;
            if (countTime > 0.01f)
            {
                isCount = false;
                changeImages.DelImage();
                countTime = 0f;
                StartCoroutine(ToReStartCount());
            }
        }
    }

    IEnumerator ToReStartCount()
    {
        yield return new WaitForSeconds(0.1f);
        isCount = true;
    }

    //当按钮被按下后系统自动调用此方法
    public void OnPointerDown(PointerEventData eventData)
    {
        isDown = true;
        lastIsDownTime = Time.time;
    }
    //当按钮抬起的时候自动调用此方法
    public void OnPointerUp(PointerEventData eventData)
    {
        isDown = false;
        isCount = true;
        countTime = 0f;
    }
    //当鼠标从按钮上离开时调用此方法
    public void OnPointerExit(PointerEventData eventData)
    {
        isDown = false;
        isCount = true;
        countTime = 0f;
    }
}

7.分别将两个脚本挂载到前进、后退的按钮上,并且将ChangeImage赋值到上面,如下图所示:

unity 当前播放动画 unity点击播放动画_System_05


8.运行项目,发现已经实现了控制帧序列播放前进与后退的功能,如下图所示:

unity 当前播放动画 unity点击播放动画_unity 当前播放动画_06