本文提供详细教程 记录遇到的难点并帮助同行的朋友们 坚持以最简单的方法传授和把更好的阅读体验带给你们! |
网盘资源一键下载 (点点关注,不迷路!谢谢支持!!)
提取码:41i6
One
Two
Three
Four
Five
Six
Seven
Eight
Nine
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FrameControll : MonoBehaviour
{
public GameObject Xulie; //序列图
public FrameTexturesController XulieFrame; //控制图片脚本
public Texture2D[] XulieTu; //读取到的图片
private AssetBundle AB1;
private readonly string ABPath = Application.streamingAssetsPath + "/wwjj";
private void Awake()
{
AB1 = AssetBundle.LoadFromFile(ABPath);
XulieTu = AB1.LoadAllAssets<Texture2D>();
XulieFrame.Frames = XulieTu;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
XulieFrame.Play(0, -1, true);
}
}
}
控制序列帧播放脚本
using UnityEngine;
using UnityEngine.UI;
public class FrameTexturesController: MonoBehaviour
{
///
/// 播放状态
///
private enum PlayStatus
{
///
/// 重置状态 (重置后会立即返回到原状态)
///
reset,
///
/// 播放开始状态
///
play,
///
/// 回放开始状态
///
playback,
///
/// 暂停开始状态
///
pause,
///
/// 停止开始状态
///
stop,
///
/// 播放中状态
///
playing,
///
/// 暂停状态
///
paused,
///
/// 停止状态
///
stopped
}
///
/// 显示控件
///
[SerializeField]
private RawImage rimg_output;
///
/// 帧速度
///
[SerializeField]
private int frameRate;
///
/// 帧序列
///
public Texture2D[] _frames;
public Texture2D[] _frames1;
public Texture2D[] Frames
{
set
{
_frames = value;
_timePreFrame = 1f / frameRate;
}
}
public Texture2D[] Frames1
{
set
{
_frames1 = value;
_timePreFrame = 1f / frameRate;
}
}
///
/// 播放速度
///
private float _speed = 1;
public float Speed
{
get => _speed;
set => _speed = value;
}
///
/// 是否循环播放
///
private bool _isLoop = false;
public bool IsLoop
{
get => _isLoop;
}
///
/// 是否正在播放
///
public bool IsPlaying
{
get => _playStatus == PlayStatus.play || _playStatus == PlayStatus.playing;
}
///
/// 是否正在回放
///
public bool IsPlaybacking
{
get => (_playStatus == PlayStatus.play || _playStatus == PlayStatus.playing) && _realSpeed < 0;
}
///
/// 开始帧的位置
///
private int _startFrameIndex = -1;
///
/// 结束帧的位置(最后一帧的后一帧)
///
private int _endFrameIndex = -1;
///
/// 当前播放位置
///
private int _curFrameIndex;
///
/// 固有帧间隔时间
///
private float _timePreFrame;
///
/// 实际帧间隔时间 := 固有帧间隔时间 / 播放速度
/// 即,计算了播放速度以后的帧间隔时间
///
private float _realTimePreFrame;
///
/// 实际播放速度 := 播放速度 * 播放方向
///
private float _realSpeed;
///
/// 当前事件间隔
///
private float _curTime;
///
/// 循环次数
///
private int _loopCount = -1;
///
/// 播放状态
///
private PlayStatus _playStatus = PlayStatus.stop;
///
/// 播放
///
public void Play(int startIndex = 0, int endIndex = -1, bool isLoop = false)
{
_isLoop = isLoop;
_startFrameIndex = startIndex;
_endFrameIndex = endIndex == -1 ? _frames.Length : endIndex;
_playStatus = PlayStatus.play;
}
///
/// 暂停
///
public void Pause() => _playStatus = PlayStatus.pause;
///
/// 回放
///
public void Playback(int startIndex = -1, int endIndex = -1, bool isLoop = false)
{
_isLoop = isLoop;
_startFrameIndex = startIndex == -1 ? _frames.Length - 1 : startIndex;;
_endFrameIndex = endIndex;
_playStatus = PlayStatus.playback;
}
///
/// 停止
///
public void Stop() => _playStatus = PlayStatus.stop;
private void Update()
{
CheckPlayStatus();
}
///
/// 检查播放状态
///
private void CheckPlayStatus()
{
switch (_playStatus)
{
case PlayStatus.pause:
OnPause();
break;
case PlayStatus.play:
OnPlay();
break;
case PlayStatus.playback:
OnPlayback();
break;
case PlayStatus.reset:
OnReset();
break;
case PlayStatus.stop:
OnStop();
break;
case PlayStatus.playing:
OnPlaying();
break;
case PlayStatus.paused:
break;
case PlayStatus.stopped:
break;
}
}
///
/// 暂停开始状态处理
///
private void OnPause()
{
}
///
/// 播放开始状态处理
///
private void OnPlay()
{
if (_speed == 0) // 播放速度如果为0,则进入暂停状态
{
_playStatus = PlayStatus.pause;
return;
}
_realSpeed = _speed > 0 ? _speed : -_speed; // 计算实际播放速度
_realTimePreFrame = _timePreFrame / _realSpeed; // 计算实际帧间隔时间
_curTime = 0; // 重置当前计时时间
_curFrameIndex = _startFrameIndex; // 重置回播放起始位置
rimg_output.texture = _frames[_curFrameIndex]; // 显示起始画面
_curFrameIndex++; // 将位置指针移至下一位
_playStatus = PlayStatus.playing; // 进入播放状态
}
///
/// 回放开始状态处理
///
private void OnPlayback()
{
if (_speed == 0) // 播放速度如果为0,则进入暂停状态
{
_playStatus = PlayStatus.pause;
return;
}
_realSpeed = _speed < 0 ? _speed : -_speed; // 计算实际播放速度
_realTimePreFrame = _timePreFrame / (-_realSpeed); // 计算实际帧间隔时间
_curTime = 0; // 重置当前计时时间
_curFrameIndex = _startFrameIndex; // 重置回播放起始位置
rimg_output.texture = _frames[_curFrameIndex]; // 显示起始画面
_curFrameIndex--; // 将位置指针移至下一位
_playStatus = PlayStatus.playing; // 进入播放状态
}
///
/// 重置状态处理
///
private void OnReset()
{
}
///
/// 停止开始状态处理
///
private void OnStop()
{
//rimg_output.texture = null;
_playStatus = PlayStatus.stopped;
}
///
/// 播放中状态处理
///
private void OnPlaying()
{
if (_curTime < _realTimePreFrame) // 当前计时未达到实际帧间隔时间
{
_curTime += Time.deltaTime; // 不做任何操作,仅累加计时时间
}
else
{
if (_curFrameIndex != _endFrameIndex) // 当前帧未到达结束位置
{
rimg_output.texture = _frames[_curFrameIndex]; // 显示当前帧画面
_curFrameIndex += _realSpeed > 0 ? 1 : -1; // 将位置指针移至下一位
_curTime = 0;
}
else
{
if (_isLoop) // 启用循环播放
{
Play(_startFrameIndex, _endFrameIndex, true); // 重新播放
}
else
{
Pause(); // 暂停播放
}
}
}
}
}
Demo一键下载 (点点关注,不迷路!谢谢支持!!)
提取码:9msb
在后期的项目中,用到了很多AB资源打包和旋转序列图的功能,会在后期慢慢出教程,我们需要一步一步的学习,关于序列图操作的拓展也会在后面讲解!谢谢大家支持!
拥有自己的服务器 让开发工作不再难 |
MyBe
阿里云 —ESC服务器部署和搭建购买方式(图文并排,一目了然)
一键领取阿里全产品2000元优惠券大礼包 (新手必得享超值优惠)
本博客为非营利性个人原创 所刊登的所有作品的著作权均为本人所拥有 本人保留所有法定权利,违者必究! 对于需要复制、转载、链接和传播博客文章或内容的 请及时和本博主进行联系,留言,Email: [email protected] ———————————————————————————————— 版权声明:对于经本博主明确授权和许可使用文章及内容的 使用时请注明文章或内容出处并注明网址 转载请附上原文出处链接及本声明。 |