Unity计时器设计 - 基础计时器
来源:互联网 发布:德国巧克力价格 知乎 编辑:程序博客网 时间:2024/06/09 03:39
Unity计时器设计 - 基础计时器
在Unity中,Time类的功能较少,例如Time.time在Awake等函数中无法获取,并且没有计时器概念等,大部分项目有计时器的需求,这篇文章将实现一个自己定义的计时器。
在开始写代码之前,先总结需求:
计时器应当具有以下操作:
- 设置计时器
- 开始和取消计时器
- 暂停和继续计时器
- 重置计时器
- 一系列事件(OnStart,OnUpdate,OnCancel,OnEnd等)。
并且具有这些属性:
- 计时器时间:开始、剩余、到时、总时长。
- 计时器状态:未开始,运行中,暂停中。
设计完以上内容后,可以做这些事情:
- 延时函数
- 一切基于时间执行的概念,例如技能,类似cocos2d-x的动作系统等。
- 很多情况下,计时器不希望随挂载对象被销毁时消失,所以Timer不继承于MonoBehaviour。
总结完可以开始写了。
首先,添加引用
using UnityEngine;using System;
可以运行的最基础的计时器:
//注意不继承于MonoBehaviorpublic class Timer{ //开始时间 public float StartTime { get; private set; } //持续时间 public float Duration { get; private set; } //结束时间 public float EndTime { get; private set; } //当前时间 public float CurTime { get; private set; } //运行标识 public bool IsStart { get; private set; } //开始和结束事件,这里直接用System.Action(相当于空返回值无参数委托) public Action OnStart { get; set; } public Action OnEnd { get; set; } public Action OnUpdate { get; set; } //构造函数,设置计时器 public Timer(float duration) { Duration = duration; } //开始计时 Timer类不继承于MonoBehaviour,该方法不会在任何对象开始时被调用。 public void Start() { IsStart = true; StartTime = Time.time; CurTime = StartTime; EndTime = StartTime + Duration; if(OnStart != null) OnStart(); } //更新时间,并检查状态。Timer类不继承于MonoBehaviour,该方法将在中心计时器每帧调用。 public void Update() { if (!IsStart) return; CurTime += Time.deltaTime; if(CurTime > EndTime) { End(); } else if (OnUpdate != null) OnUpdate(); } //计时器结束 void End() { IsStart = false; if(OnEnd!= null) OnEnd(); }}
- 新增取消
//取消事件public Action OnCancel { get; set; }//取消接口。public void Cancel(){ IsStart = false; if(OnCancel != null) OnCancel();}
- 新增暂停和继续
//事件public Action OnPause { get; set; }public Action OnContinue { get; set; }//属性public bool IsPause { get; private set; }//取消接口public void Pause(){ IsPause = false; if(OnCancel != null) OnCancel();}//继续接口public void Continue(){ IsPause = true; if(OnContinue!= null) OnContinue();}//Update逻辑需要更改public void Update(){ if (!IsStart) return; CurTime += Time.deltaTime; if(IsPause) EndTime += Time.deltaTime; if(CurTime > EndTime) { End(); } else if (OnUpdate != null) OnUpdate();}
- 新增重置:
//重置接口public void Reset(){ IsStart = false; IsPause = false;}
一个简单的计时器就这样完成了。
但是我们往往需要获取计时器的各种属性,下面新增一些public属性:
- 计时器已经完成的百分比,常用于
public float Ratio{ get { if(!IsStart) { return 0; } else { return 1 - (EndTime - CurTime) / Duration; } }}
- 计时器次数,可用于循环计时、检测是否已经完成等。(常规循环计时推荐新定义循环计时器)
//开始次数public int StartCount { get; private set; }//完成次数public int FinishCount { get; private set; }//Start修改public void Start(){ IsStart = false; StartTime = Time.time; CurTime = StartTime; EndTime = StartTime + Duration; //新增这一行↓ StartCount++; if(OnStart != null) OnStart();}//End修改void End(){ IsStart = true; //新增这一行↓ FinishCount++; if(OnEnd!= null) OnEnd();}
简单的计时器设计完成啦!
但是还不可以运行,毕竟Update还不会主动调用。
我们可以先简单写一个中心计时器来解决问题:
新建CenterTimer.cs:
using UnityEngine;using System.Collections.Generic;//因为中心计时器应该只有一个,所以所有新定义的成员都应该为静态成员。public Class CenterTimer : MonoBehaviour{ static List<Timer> timers = new List<Timer>(); //添加计时器 public static void AddTimer(Timer timer) { timers.Add(timer); } //移除计时器 public static void RemoveTimer(Timer timer) { timers.Remove(timer); } //每帧更新 void Update() { foreach(var timer in timers) { timer.Update(); } }}
同时对Timer类做一点点修改:
public void Start(){ IsStart = true; StartTime = Time.time; CurTime = StartTime; EndTime = StartTime + Duration; //新增这一行↓ CenterTime.AddTimer(this); StartCount++; if(OnStart!= null) OnStart();}//计时器结束void End(){ IsStart = false; if(OnEnd!= null) OnEnd(); //新增这一行↓ CenterTimer.RemoveTimer(this);}public void Reset(){ IsStart = false; IsPause = false; //新增这一行↓ CenterTimer.RemoveTimer(this);}
使用方法如下:
Test.cs 挂在一个GameObject上
CenterTimer.cs 挂在摄像头上。
using UnityEngine;public class Test : MonoBehaviour{ Timer timer; void Update() { if(Input.GetKeyDown(KeyCode.T)) { timer = new Timer(3f); timer.OnUpdate += SetScale; timer.OnEnd += Hide; timer.Start(); } } //缩放动画 void SetScale() { float scale = 1 - timer.Ratio; gameObject.transform.localScale = new Vector3(scale, scale, scale); } void Hide() { gameObject.SetActive(false); }}
执行游戏并按下T键,我们可以看到该对象在3秒内从大变小到完全消失。
0 0
- Unity计时器设计 - 基础计时器
- Unity 计时器
- 【Unity】计时器
- unity 计时器
- unity 计时器
- 设计计时器
- 计时器
- 计时器
- 计时器
- 计时器
- 计时器
- 计时器
- 计时器
- 计时器
- 计时器
- 计时器
- 计时器
- 计时器
- liferay监听器
- 修改UIAlertController字体颜色大小
- Android广播机制——广播的注册
- mybatis 关于时间的问题与技巧
- centos服务器配置caffe环境
- Unity计时器设计 - 基础计时器
- react native 嵌入原生Android应用中的问题
- [生存志] 第119节 刘安编著淮南鸿烈
- angularjs 自定义指令的分类
- Hibernate Set Cascade Example (save, update, delete and delete-orphan)
- MSP430 12864显示
- 如何配置spring+springmvc+mybatis环境
- 监视Linux服务器的性能
- v-model和v-for指令