[Unity脚本运行时更新]C#5新特性

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhenghongzhi6/article/details/82797533

洪流学堂,让你快人几步!本文首发于洪流学堂微信公众号。

本文是该系列《Unity脚本运行时更新带来了什么?》的第3篇。
洪流学堂公众号回复runtime,获取本系列所有文章。

Unity2017-2018.2中的4.x运行时已经支持到C#6,Unity2018.3将支持到C# 7.2,看看C#的新特性能给代码带来什么吧。

C#5 新特性

  • Asynchronous methods:异步方法
  • Caller info attributes:调用时访问调用者的信息,可以用于调试

Asynchronous methods 异步方法

C#5中引入了两个新关键字async修饰符和await操作符。这是C#5最重要的更新,可以说让异步编程能达到事半功倍的效果。

使用async修饰的方法被称为异步方法,这个方法调用时应该在前面加上await。下面我们来看看这个新特性对Unity中的异步编程有什么影响。

我们先看一下以前使用异步编程,需要使用协程,代码大概是这个样子:

public class AsyncExample : MonoBehaviour
{
    IEnumerator Start()
    {
        Debug.Log("Waiting 1 second...");
        yield return new WaitForSeconds(1.0f);
        Debug.Log("Done!");
    }
}

有了async-await之后,可以这么写:

public class AsyncExample : MonoBehaviour
{
    async void Start()
    {
        Debug.Log("Waiting 1 second...");
        await Task.Delay(TimeSpan.FromSeconds(1));
        Debug.Log("Done!");
    }
}

Unity中的协程是使用迭代器实现的,本质上不是线程,运行时还是在主线程中运行。
但是,对,但是,由于Unity的API只能在主线程中调用,async的方法在调用时会自动开启一个新的线程去执行,所以在Unity中还是有很大的局限。

目前我们可以将不调用Unity API,但是计算量比较大的方法采用异步的方式进行计算。

另外也可以手动去增加Unity中async-await的支持,但是其实有一个Unity插件已经做的很好了,那就是UniRx。例如:

public class AsyncExample : MonoBehaviour
{
    public Button TestButton;
 
    async void Start()
    {
        await TestButton.OnClickAsObservable();
        Debug.Log("Clicked Button!");
    }
}

关于UniRx这个插件,我们之前在洪流学堂公众号中也已经写过图文版的教程,大家可以在洪流学堂公众号中回复unirx获取。

async-await在Unity中的最佳实践

  • 不要在异步方法中调用Unity的API,就跟不要在子线程中调用Unity的API一样,否则Console中也会报错
  • 异步方法命名应该以Async结尾,这样大家知道调用的时候使用await

Caller info attributes:调用时访问调用者的信息

该功能主要是通过3个Attribute实现:

  • CallerFilePathAttribute 调用方的源码路径(编译时的路径)
  • CallerLineNumberAttribute 调用时的代码行
  • CallerMemberNameAttribute 调用方法或属性的名称

该功能主要是用于调试,示例代码如下:

void Start()
{

    MethodA();
    MethodB();
}

void MethodA()
{
    //InsertLog("MethodA");
    MethodB();
}

void MethodB(
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0)
{
    InsertLog(memberName);
    Debug.Log(sourceFilePath+sourceLineNumber);
}

void InsertLog(string methodName)
{
    Debug.Log(string.Format("{0} called method B at {1}", methodName,
    DateTime.Now));
}

小结

本文讲解了C#5的新特性中对Unity变成有影响的新特性。其中有些概念有些难理解,可以再深入地找一些例子进行强化理解。

洪流学堂公众号回复runtime,获取本系列所有文章。

把今天的内容分享给其他Unity开发者朋友,或许你能帮到他。



《郑洪智的Unity2018课》,倾尽我8年的开发经验,结合最新的Unity2018,带你从入门到精通。

猜你喜欢

转载自blog.csdn.net/zhenghongzhi6/article/details/82797533