如何在Unity中使用collout [可用示例]

制作游戏时,异步处理非常麻烦。例如,在后台在加载屏幕上加载信息时
各种元素在游戏屏幕上交织在一起,例如在完成特定过程时设置动画和更改行为。
许多人会昂首阔步。
因此,这次是Unity的异步处理。我将解释Corroutine。

游戏是异步且痛苦的

顺便说一句,首先要考虑游戏的内容,这是异步处理的一大亮点。
例如,您可以在暂停屏幕上停止所有游戏动作,或者当计时器为零时游戏自动结束。
除了主要的游戏逻辑之外,还有很多东西总是受某些因素影响。
结果,条件分支变得太复杂,并且每个对象变得紧密连接。
例如,当计时器为零时,如要求进行以下处理,如↓

    Update() {
        --timer; 
        // timerがゼロになったら実行してほしいロジック
        if (timer > 0) {
            // いろいろな処理
        } 
    }

如果此if条件增加(例如更改30秒或更短时间内改变音乐的效果),则if语句将以加快的速度增加。
由于Unity的性质,对象必须在Update函数中描述过程,因此依赖于Update函数的对象(例如↑)
以后划分处理变得困难。

此外,由于游戏开发的性质,我实际上会做到这一点-> 遊ぶ ->由于我们将通过添加或更改规格的周期进行开发,
如果您以后不考虑对象的组成,您将严重失望。

顺便说一句,以我的经验,如果我通过合并观察者模式和枚举器来制作出像一个离谱的处理系统,
根据游戏中的多种逻辑,当游戏逻辑发生变化时,您可能希望逃避极大。

统一协程

是Corroutine在手术开发中加入了手术刀。
collout是一种特殊功能,它可以在特定点处停止处理,并在下一帧处恢复处理。

让我们根据计时器的实际实现示例来了解如何使用它。

正常使用

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

public class timer : MonoBehaviour {

	// Use this for initialization
	void Start () {
        // コルーチンを実行
		StartCoroutine("testtimer",10);		
	}
	
	// Update is called once per frame
	void Update () {

	}

	IEnumerator testtimer (int lefttime) {		
		while(lefttime >= 0){
			// 残り時間が0以上の場合はタイマーを更新 
			yield return new WaitForSeconds(1.0f);
			Debug.Log(lefttime);
			--lefttime;
		}
		Debug.Log("end");
	}
}

如果将↑粘贴到适当的游戏对象中并执行

它将以倒数的形式出现。

这次的collout功能是以下部分。

	IEnumerator testtimer (int inittime) {		
		// 残り時間が0以上の場合はタイマーを更新 
		while(inittime >= 0){
			// タイマーを更新してフレームを中断
            yield return new WaitForSeconds(1.0f);
            // 次のフレームでここから再開
			Debug.Log(inittime);
			--inittime;
		}
		Debug.Log("end");
	}
}

让我们详细解释。
collout函数包含以下元素,

  • 返回值为IEnumerator
  • 使用运算符yeild指定返回值
  • 恢复处理的条件由转换后的返回位置确定。
  • 只有这个。

    首先

    	IEnumerator testtimer (int inittime) {		
    

    ↑IEnumerator附加在返回值上,不是吗?这是第一个条件。
    通过使用它,我们定义这是一个使用协程的函数。

    因此,第二个条件yiled运算符为

    			yield return new WaitForSeconds(1.0f); // ここで処理を中断
                // 次のフレームでここから処理を再開する。
    

    这将是其中的一部分。通过指定此返回值,将中断该帧的处理,并下一帧
    处理将恢复。
    然后,您可以通过将特定值返回到该返回值以指定恢复条件来指定恢复处理的条件。
    在这种情况下,处理将在1秒钟后重新开始,因此将1.0f赋给名为WaitForSeconds的对象,该对象将在特定时间后恢复处理。

    最后执行collout功能

    	// Use this for initialization
    	void Start () {
            // コルーチンを実行
    		StartCoroutine("testtimer",10);// 実行		
    	}
    

    将函数名称和函数参数传递给名为StartCoroutine的函数。

    关于收益的返回值

    程序的关键是中断和恢复处理的时间。
    我想您可以从上面的解释中看到。
    因此,我将逐一说明影响时间的collout的返回值和效果。

    停止处理框架

        yield return null;
    

    如果如上所述将返回值设置为null,则该帧中的处理将终止,并且处理将在下一帧中重新开始。

    杀死Corroutine

        yield break;
    

    在特定时间终止正在运行的collout。
    在这种情况下,处理不会恢复。例如,在上面的计时器示例中

    	IEnumerator testtimer (int inittime) {		
    		while(inittime >= 0){
    			// 残り時間が0以上の場合はタイマーを更新 
    			yield return new WaitForSeconds(1.0f);
    			Debug.Log(inittime);
    			--inittime;
    			if(inittime == 5) {
    				yield break;// この時点でコルーチンが終了する
    			}
    		}
    		Debug.Log("end");
    	}
    

    计时器将显示6秒并停止运行。

    等待特定时间

        yiled return new WaitForSeconds(3.0f); // 3秒間待つ
    

    这是Unity提供的名为WaitForSeconds的对象,并且已使用。
    您可以根据代码中提供的值来调整等待时间。

    自定义中断条件

    从上面对返回值的解释中可以看出,collout可以通过返回值来调整重新启动的时间。
    因此,Unity还具有自定义重启时间的功能。
    那就是海关收益指令。

    让我们来看一个例子。这是对官方主页上的代码的一些调整,当按键盘上的A时,它将恢复处理。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ButtonWait : MonoBehaviour {
    
    	// Use this for initialization
    	void Start () {
    		StartCoroutine("routine");
    	}
    	
    	// Update is called once per frame
    	void Update () {
    		
    	}
    
    	IEnumerator routine(){
    		yield return new PushAButton();
    		Debug.Log("A button has push");
    	}
    }
    
    class PushAButton : CustomYieldInstruction{
    
    	public override bool keepWaiting{
    		get {
    			return !Input.GetKeyDown(KeyCode.A);
    		}
    	}
    
    	public PushAButton(){
    		Debug.Log("waiting for press A button");
    	}
    }
    
    

    自定义事件在以下部分中定义。

    class PushAButton : CustomYieldInstruction{
    
    public override bool keepWaiting{
    	get {
    
    		return !Input.GetKeyDown(KeyCode.A); // ここで再開する条件を記述する
    	}
    }
    
    public PushAButton(){
    	Debug.Log("waiting for press A button"); //コルーチンの処理中断直後の処理はここに書く
    }
    }
    
    

    自定义Coroutum事件包含以下条件:

  • 新类继承CustomYieldInstruction
  • class PushAButton : CustomYieldInstruction{
    
  • Overover keepWaiting
  • 当布尔值为true时,keepWaiting重新启动
  • public override bool keepWaiting{
    	get {
    		return !Input.GetKeyDown(KeyCode.A);
    	}
    }
    
  • 在构造函数中定义中断时的处理
  • public PushAButton(){
    	Debug.Log("waiting for press A button");
    }
    

    其实使(淡出)

    让我们做一些可以在实际版本中实际使用的东西。
    我认为视觉效果最容易理解,因此请淡化过渡效果

    逻辑

    首先让我们了解逻辑。

    1.在相机前面放置一个特定的精灵对象
    2.逐渐降低精灵颜色的Alpha值

    只有这个。

    这次,我将在2部分中使用collout实现它。

    制备

    首先,让我们准备一个对象。
    首先,准备要在相机整个表面上显示的图像。
    让我们使用UI面板。

    用户界面喜欢图片->从面板创建面板对象并传递它。

    然后将代码粘贴到该面板上的对象中。

    实作

    现在让我们实际编写源代码。

    您可以使用此属性来播放Sprite的颜色,因此
    使用此实现以下内容。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    
    
    public class Fade : MonoBehaviour {
    
    	public Image fadeTarget;// fadeoutするスプライトの対象
    
    	// Use this for initialization
    	void Start () {
    		StartCoroutine("fadeout",3);
    	}
    	
    	// Update is called once per frame
    	void Update () {
    		
    	}
    
    	IEnumerator fadeout (int fadeValuePerSeconds) {		
    		float alpha = 1f;
    		while(alpha >= 0){
    			// 残り時間が0以上の場合はタイマーを更新 
    			yield return new WaitForSeconds(0.3f);
    			alpha -= 0.03f;
    			Color nextColor = new Color(fadeTarget.color.r,fadeTarget.color.g,fadeTarget.color.b, alpha);
    			this.fadeTarget.color = nextColor;
    		}
    		Debug.Log("end");
    	}
    }
    

    将此粘贴到适当的对象中,然后将要淡入淡出的对象附加到公共Image fadeTarget上。
    您会看到它随着时间逐渐消失。

    这次我尝试在适当的时候淡出,
    例如,当与这次引入的自定义collout结合使用时,触发条件是按下了按钮。
    您也可以淡出
    如果您在collout的淡出部分中创建了一个称为“要动画多少秒”的函数,
    它可以作为简单资产重用。
    另外,为方便起见,为简化实现,我如上所述编写了该脚本,因此淡入淡出并不平滑,有些淡淡。
    因此,如果要调整这些值,请使用一个名为lerp的函数使其平滑。

    概要

    认真制作游戏->実際に遊ぶ->問題点を洗い出す ->它包含一个重新进行的循环。
    而且由于这个周期的数量直接关系到游戏的质量,因此要尽可能避免花时间在制作上
    让我们编写可以使用诸如corroutine之类的技术轻松更改的代码。

    撰写本文的人

    assa

    我是京都的工程师。记住assa或eh。 我的主要业务是在网上玩我的业余爱好。有什么好的