Unity简单计时器,实现随时播放,暂停,继续,停止
2017-11-28 18:45
344 查看
最近的项目中要用到简单的计时功能,又因为函数的构造已经写好了,不想去改变,所以最后用了dotween模拟计时功能,闲下来时就自己实现了一个简易的计时器
首先是状态图
![](http://img.blog.csdn.net/20171114185119960?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYTgyNzQ0MzQ2OQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
计时器由三个状态组成,停止状态,播放状态和暂停状态,其中的切换逻辑见图
因为是一个工具类,所有为了使用上尽可能的简单,我在调用方式上模仿了dotween的使用方式
大致是这样的
首先定义一个CountTimeModel对象,局部和全局的都可以,如果想在任意地方去暂停播放最好用全局类型
pause函数可以暂停计时,continue可以从之前的进度重新开始,这两个函数特别好用
内部实现原理,我使用了unity的协程机制,但是因为工具类没有继承自monobehaviour,所有在启动协程上使用了取巧的方式
最开始的方法是在begin时需要将调用者传入以执行协程,后面觉得不够方便,违反了工具类的实质,而且不是所有的调用者都继承了monobehaviour
其他两个类型用来控制状态的切换
最后是全部的代码,如果在使用过程中发现有什么问题或者需要改进,添加的功能都可以留言告诉我,我自己也在用这个脚本,慢慢优化
首先是状态图
计时器由三个状态组成,停止状态,播放状态和暂停状态,其中的切换逻辑见图
因为是一个工具类,所有为了使用上尽可能的简单,我在调用方式上模仿了dotween的使用方式
大致是这样的
CountTimeModel model1; void Start () { //计时5秒 model1 = CountTime.Count(5) .OnBegin(delegate { Debug.Log("开始"); }) .OnEnd(delegate { Debug.Log("结束"); }) .OnStop(delegate { Debug.Log("停止"); }) //更新,可以指定更新频率 .OnUpdate(onTimeUpdate); model1.Begin(); model1.Pause(); model1.Continue(); model1.Stop(); } // update对应的回调需要有一个float参数 void onTimeUpdate(float time) { Debug.Log(time); }
首先定义一个CountTimeModel对象,局部和全局的都可以,如果想在任意地方去暂停播放最好用全局类型
pause函数可以暂停计时,continue可以从之前的进度重新开始,这两个函数特别好用
内部实现原理,我使用了unity的协程机制,但是因为工具类没有继承自monobehaviour,所有在启动协程上使用了取巧的方式
/// <summary> /// 调用携程,需要借助这个类 /// </summary> public class CountTimeGameObject : MonoBehaviour { public static void PrintT(string msg) { Debug.Log(msg); } }在第一次计时时会创建一个空的对象去挂载这个脚本,然后将这个实例的引用抓在手里,后面全部通过这个behaviour的子类去启动协程
最开始的方法是在begin时需要将调用者传入以执行协程,后面觉得不够方便,违反了工具类的实质,而且不是所有的调用者都继承了monobehaviour
/// <summary> /// 更新频率,执行update的频率 /// </summary> public enum UpdateLevel { S,//1秒 S0,//0.1秒 S00//0.01秒 } /// <summary> /// 计时器的三种状态 /// </summary> public enum CountTimeStateType{ STOPED, PLAYING, PAUSED } /// <summary> /// 操作类型 /// </summary> public enum OperationType { NORMAL,//正常类型 PAUSED,//暂停操作 STOP//停止操作 }在创建计时实例时可以指定update刷新的类型,是通过UpdateLevel类型实现的,控制每多久执行一个update回调
其他两个类型用来控制状态的切换
最后是全部的代码,如果在使用过程中发现有什么问题或者需要改进,添加的功能都可以留言告诉我,我自己也在用这个脚本,慢慢优化
// ========================================================
// 描 述:计时工具类
// 作 者:xzf
// 创建时间:2017/11/14 15:36:35
// 版 本:v 1.0
// ========================================================
using System;
using System.Collections;
using UnityEngine;
namespace StoneTools
{
/// <summary>
/// 对CountTimeModel的调用做一层封装,添加了一些处理
/// </summary>
public class CountTime
{
public static CountTimeGameObject CountTimeObject;
/// <summary>
/// 计时
/// </summary>
/// <param name="time">时间</param>
/// <returns></returns>
public static CountTimeModel Count(float time)
{
if (!checkTimeAvailable(time)) {
return null;
}
checkCountTimeObject();
CountTimeModel timeModel = new CountTimeModel(time);
return timeModel;
}
/// <summary>
/// 计时
/// </summary>
/// <param name="time">时间</param>
/// <param name="level">刷新频率(调用update),默认为0.1s</param>
/// <returns></returns>
public static CountTimeModel Count(float time, UpdateLevel level)
{
if (!checkTimeAvailable(time))
{
return null;
}
checkCountTimeObject();
CountTimeModel timeModel = new CountTimeModel(time, level);
return timeModel;
}
/// <summary>
/// 计时
/// </summary>
/// <param name="time">时间</param>
/// <param name="isRealTime">是否真实时间,默认为游戏中时间</param>
/// <returns></returns>
public static CountTimeModel Count(float time, bool isRealTime)
{
if (!checkTimeAvailable(time))
{
return null;
}
checkCountTimeObject();
CountTimeModel timeModel = new CountTimeModel(time, isRealTime);
return timeModel;
}
/// <summary>
/// 计时
/// </summary>
/// <param name="time">时间</param>
/// <param name="level">刷新频率(调用update),默认为0.1s</param>
/// <param name="isRealTime">是否真实时间,默认为游戏中时间</param>
/// <returns></returns>
public static CountTimeModel Count(float time, UpdateLevel level, bool isRealTime)
{
if (!checkTimeAvailable(time))
{
return null;
}
checkCountTimeObject();
CountTimeModel timeModel = new CountTimeModel(time, isRealTime);
return timeModel;
}
static void checkCountTimeObject()
{
if (CountTimeObject == null)
{
GameObject tGO = new GameObject("【CountTimeObject】");
CountTimeObject = tGO.AddComponent<CountTimeGameObject>();
}
}
static bool checkTimeAvailable(float time) {
if (time <= 0)
return false;
return true;
}
}
/// <summary> /// 调用携程,需要借助这个类 /// </summary> public class CountTimeGameObject : MonoBehaviour { public static void PrintT(string msg) { Debug.Log(msg); } }
/// <summary> /// 更新频率,执行update的频率 /// </summary> public enum UpdateLevel { S,//1秒 S0,//0.1秒 S00//0.01秒 } /// <summary> /// 计时器的三种状态 /// </summary> public enum CountTimeStateType{ STOPED, PLAYING, PAUSED } /// <summary> /// 操作类型 /// </summary> public enum OperationType { NORMAL,//正常类型 PAUSED,//暂停操作 STOP//停止操作 }
public class CountTimeModel
{
private float _aimTime;
private float _currentTime = 0;
private float _updateValue = 0.1f;
private bool _isRealTime = false;
Action _beginAction; //开始
Action<float> _updateAction;//更新
Action _endAction; //正常结束
Action _stopAction; //中途停止
//记录当前状态
private CountTimeStateType _state = CountTimeStateType.STOPED;
//记录上一步执行的操作
private OperationType _operation = OperationType.NORMAL;
public CountTimeModel(float cTime)
{
_aimTime = cTime;
}
public CountTimeModel(float cTime, bool isRealTime)
{
_aimTime = cTime;
_isRealTime = isRealTime;
}
public CountTimeModel(float cTime, UpdateLevel level)
{
_aimTime = cTime;
setUpdateLevel(level);
}
public CountTimeModel(float cTime, UpdateLevel level, bool isRealTime) {
_aimTime = cTime;
setUpdateLevel(level);
_isRealTime = isRealTime;
}
void setUpdateLevel(UpdateLevel level) {
switch (level)
{
case UpdateLevel.S:
_updateValue = 1f;
break;
case UpdateLevel.S0:
_updateValue = 0.1f;
break;
case UpdateLevel.S00:
_updateValue = 0.01f;
break;
default:
break;
}
}
/// <summary>
/// 开始
/// </summary>
public void Begin()
{
if (_state != CountTimeStateType.STOPED)
return;
if (_beginAction != null)
{
_beginAction();
}
_currentTime = 0;
CountTime.CountTimeObject.StartCoroutine(updateTime());
}
/// <summary>
/// 暂停
/// </summary>
public void Pause() {
if (_state != CountTimeStateType.PLAYING)
return;
_operation = OperationType.PAUSED;
}
/// <summary>
/// 继续
/// </summary>
public void Continue() {
if (_state != CountTimeStateType.PAUSED)
return;
_operation = OperationType.NORMAL;
CountTime.CountTimeObject.StartCoroutine(updateTime());
}
/// <summary>
/// 停止
/// </summary>
public void Stop() {
if (_state == CountTimeStateType.STOPED)
return;
_operation = OperationType.STOP;
}
IEnumerator updateTime()
{
_state = CountTimeStateType.PLAYING;
if (_isRealTime)
{
while (_currentTime < _aimTime)
{
//停止计时
if (_operation != OperationType.NORMAL)
break;
yield return new WaitForSecondsRealtime(_updateValue);
_currentTime += _updateValue;
if(_updateAction != null)
_updateAction(_currentTime);
}
}
else
{
while (_currentTime < _aimTime)
{
//停止计时
if (_operation != OperationType.NORMAL)
break;
yield return new WaitForSeconds(_updateValue);
_currentTime += _updateValue;
if (_updateAction != null)
_updateAction(_currentTime);
}
}
if (_operation == OperationType.STOP)
{
if (_stopAction != null)
_stopAction();
_state = CountTimeStateType.STOPED;
}
else if (_operation == OperationType.NORMAL)
{
if (_endAction != null)
_endAction();
_state = CountTimeStateType.STOPED;
}
else if (_operation == OperationType.PAUSED) {
_state = CountTimeStateType.PAUSED;
}
_operation = OperationType.NORMAL;
yield return 0;
}
public CountTimeModel OnBegin(Action ac)
{
_beginAction = ac;
return this;
}
public CountTimeModel OnUpdate(Action<float> ac)
{
_updateAction = ac;
return this;
}
public CountTimeModel OnEnd(Action ac)
{
_endAction = ac;
return this;
}
public CountTimeModel OnStop(Action ac) {
_stopAction = ac;
return this;
}
}
}
相关文章推荐
- 使用MediaPlayer实现播放、暂停、继续和停止功能的简易音乐播放器
- 使用service的startservice 和bindservice方法实现音乐的播放、暂停、继续
- ocos2d-x中背景音乐的播放与停止、暂停与继续
- android暂停或停止其他音乐播放器的播放实现代码
- AS3.0实现音乐的播放,停止,暂停,和音量的控制
- 实现文件异步读写、暂停、继续、停止功能的类
- iOS开发 实现动画的暂停和继续播放
- Android开发笔记之广播,service实现音乐的播放暂停停止快进等功能
- C++实现的可以安全的暂停、继续、停止线程的封装类
- iOS 9音频应用播放音频之播放控制暂停停止前进后退的设置
- [转]C++实现系统服务暂停、停止、启动
- NSTimer 暂停 继续 停止 的方法
- Android实现控制第三方音乐播放器暂停/播放
- 简单实现Aandroid视频中播放暂停按钮的效果
- ijkPlayer 实现视频播放,暂停,功能
- MediaElement视频控制:播放、暂停、停止、后退、快进、跳转、音量
- [FAQ13878][Audio APP]收音机 APP 添加耳机hook键,以实现播放、暂停的功能
- 用js实现终止浏览器对页面HTML的继续解析即停止解析 兼容firefox
- VS2013 / MFC + OpenCV 2.4.9实现视频的播放暂停和结束
- 用AFNetworking实现断点续传,暂停,继续