要做个倒计时的小功能,以前都是通过在update里记录Time.time以及上次时间变化时刻,做差后差值在0.9-1.1就减去一秒。 原理so简单,代码如下: using UnityEngine; using System.Collections; public class CountDown: MonoBehaviour{ public int totalSeconds = 60; int leaveSeconds;//剩余时间 string guiTitle = "开始"; bool whetherOn = false; float lastTime;//上次时间变化的时刻 或者 本次开始的时刻 void OnGUI(){ GUI.Button(new Rect(100,50,70,40),leaveSeconds.ToString()); if(GUI.Button(new Rect(200,50,70,40),guiTitle)){ if(guiTitle == "开始"){ guiTitle = "暂停"; whetherOn = true; lastTime = Time.time; } else{ guiTitle = "开始"; whetherOn = false; } } }
void Awake(){ leaveSeconds = totalSeconds; } void Update(){ if(whetherOn){ if(Time.time-lastTime>0.9f&&Time.time-lastTime<1.1f){ leaveSeconds--; lastTime = Time.time; } } } } 在认识了StartCoroutine函数后决定用这个来做一个倒计时。要注意的见一下代码备注。 public class CountDown: MonoBehaviour{ // 总秒数 public int totalSeconds = 60;
int leaveSeconds; bool onCountDown = false; string countDownTitle = "开始";
void Awake(){ leaveSeconds = totalSeconds; } void OnGUI(){ GUI.Button(new Rect(50, 50,50, 50), leaveSeconds.ToString());
if(GUI.Button(new Rect(150, 50, 80, 30), countDownTitle)){ if(countDownTitle == "开始"){ countDownTitle = "暂停"; onCountDown = true; StartCoroutine(DoCountDown()); } else{ countDownTitle = "开始"; onCountDown = false; StopAllCoroutines(); //只要StartCoroutine启动后,由它产生的效果就一直存在,除非你StopAllCorutines,而且它还会叠加,所以在OnGUI中要通过各种条件使其一次就触发一次,不需要的时候则关闭 } } }
void Update(){ print(countDownTitle.ToString() + ",leave seconds:"+leaveSeconds.ToString()); }
IEnumerator DoCountDown(){ while(leaveSeconds > 0){ yield return new WaitForSeconds(1f); leaveSeconds--; } } } 注意上面这段代码黄色背景的两句,由于开始倒计时,都需要经过一秒,才开始减去一秒,所以要先WaitForSeconds(1f);再leaveSeconds--; 若leaveSeconds--写在前,则突然就会减去一秒,不符合逻辑。 不解的是这里yield return 后,后面还继续执行后面的语句. 就当这里是个语法惯例吧。 今天写个东西也用到了类似的东西,在yield return 前执行和yield return后执行却得到了不同的效果。 具体就是测试个scenes传值的demo,这里从Scene1场景传值到Scene2场景。 先声明了一个类,定义了一个静态的变量,挂到Scene1的Camera上,代码: using UnityEngine; using System.Collections;
public class ValuePass: MonoBehaviour { public static int valuePassed ; } Scene1 的camera上挂的数据传值代码为:(详见注释) public class Scene1: MonoBehaviour{ void OnGUI(){ GUI.Button(new Rect(0,0,1024,50),"Scene0");
if(GUI.Button(new Rect(100,100,100,30),"Scene1")){ StartCoroutine(GetValue()); //当然这里完全可以不使用协程来设置值,但是有些情况比如从网络上获得数据就不得不使用协程了 Application.LoadLevel(1); } }
IEnumerator GetValue(){ //ValuePass.valuePassed= 123456; //写在yield return null之前可以顺利传值 yield return null; ValuePass.valuePassed= 123456; //写在yield return null之前传值不过去 } } Scene2的camera上挂的数据传值代码为: public class Scene2: MonoBehaviour{ void OnGUI(){ GUI.Button(new Rect(0,0,1024,50),"Scene1"); if(GUI.Button(new Rect(100,100,100,30),ValuePass.valuePassed.ToString())){ Application.LoadLevel(0); } } } |
|