Unity中协程的使用+自定义

本文探讨了Unity中的协程,介绍了协程在游戏编程中的优势,如简化跨帧逻辑,提高代码可维护性。Unity通过每帧运行协程来管理,而开发者有时需要自己管理协程,例如在网络同步或特定游戏功能中。文章还提到了如何重写StartCoroutine以实现自定义协程更新,并指出协程遍历的本质是树的深度遍历。
摘要由CSDN通过智能技术生成

Unity中的协程是模拟操作系统线程的(名称很相近),使用的感觉也相近。不同之处是:线程是操作系统管理的,而协程是Unity管理并运行在主线程中(每帧运行一次,每秒运行30或60次);

协程的优势

协程的使用方便且强大,在游戏编程中很常见。游戏编程的很多逻辑需要跨帧才能完成(尤其涉及到动画表现相关的逻辑),在不用协程的情况下,可能需要在Update的逻辑中进行(其中逻辑状态需要存放为类变量);而改用协程,代码就会变得很简单,且状态只需要维护为方法变量;举例:

1)Update的方法:

public class MyAnim1 : MonoBehaviour {
    public Vector3 startPos, endPos;
    public float speed;

    // 状态
    private float progress;

    void Start () {
        progress = 0;
    }
	
    void Update () {
        progress += Time.deltaTime * speed;
        transform.position = Vector3.Lerp(startPos, endPos, progress);
    }
}

2)用协程的方法:

public class MyAnim2 : MonoBehaviour {
    public Vector3 startPos, endPos;
    public float speed;

    void Start() {
        StartCoroutine(doAnim()); // 启动协程
    }

    private IEnumerator doAnim() { 
        var progress = 0f; // 状态
        while (true) {
            yield return null; // 等待一帧
            progress += Time.deltaTime * speed;
            transform.position = Vector3.Lerp(startPos, endPos, progress);
        }
    }
}

这个例子虽然简单,但是Update的方法的progress的维护要分散在代码的3处,而协程就在一个方法内,这就体现了协程的优势;如果动画有多个的话,使用协程的方便性和可维护性就会更加明显。

Unity的协程管理

 Unity管理协程的方式基于两点:1)游戏引擎每秒更新30帧(或则60帧等);2)C#语言对协程的支持;

自己管理协程

在游戏开发中,有些时候需要自己管理协程。运用场景举例:
1)一些帧同步的网游,驱动逻辑更新的源头是网络上过来的“逻辑帧”(非游戏刷新帧),网络上每到来一“逻辑帧”,逻辑就需要更新一次(帧同步频率一般会低于游戏刷新帧---比如帧同步频率是15帧/秒。但由于网络卡顿延迟,会把延后“逻辑帧”积累起来一起发送,这样游戏的一个刷新帧内会到来多个“逻辑帧”)。

2)自己想用协程的方式来管理一些游戏功能,比如状态机的简化处理等(以后有时间会写一些相关文章); 

在项目中,有的时候需要手动控制协程的更新,也就是重写StartCoroutine方法。具体如下:

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

public class CoroutineManager {
    public Clock clock { get; private set; }
    private HashSet<CoroutineIter> cIters ;
    private List<CoroutineIter> itAddTemp;
    private List<CoroutineIter> itDelTemp;

    private CoroutineManager() {
        cIters = new HashSet<CoroutineIter>();
        itAddTemp = new List<CoroutineIter>();
        itDelTemp = new List<Cor
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值