今天是大年初二,在此祝各位程序员朋友身体健康,猪年大吉。闲来无事,把在Unity开发中所使用的C#知识点总结了一下,因为自己在带团队新人的时候,好多知识点它们并不是很清楚,编写代码还是局限于“Hello World”的写法,编写能力一直迟迟得不到提高,另外,只是满足于把分配的功能实现出来就完事了。自己对自己的能力也没有一个清晰的认识,在这里也是为了能够帮助他们,利用休息时间写篇博客,其实在面试的时候,主考官也会问到相关的问题,在项目开发中这些知识点是必备的,掌握了这些知识点,再模块化编程就容易多了。下面我把总结的给读者展示一下:
C#作为面向对象语言,面向对象语言的三大特性就是,继承,封装,多态。继承就是子类继承父类,有单继承,多继承,虚拟继承等等。Unity它自己也为我们提供了很多继承的代码,比如:
它的最顶层是Object,Component,Behaviour,MonoBehaviour,我们自己编写的脚本要挂接到对象上就必须继承MonoBehaviour。封装主要是用于对外提供访问的接口,避免直接修改内部数据。比如我们定义的变量,有两种访问方式:一种是直接访问,另一种是将其放到函数中去获取;第一种不安全会被修改,第二种是安全的,这也是我们说的接口封装。多态,主要是函数的同名不同参。这三种特性是最基本的,必须要掌握的。
它是把物体的共性抽离出来,既可以把共性的方法实现出来,也可以提供子类实现的接口。它的优点是减少代码量,但它不可以new对象。子类可以直接调用抽象类声明的public函数。游戏中比如我们的配置文件的加载读取,举例如下所示:
这样子类可以直接调用我们的Load函数,而子类具体实现OnLoad函数,如下所示:
有partial修饰的类,我们可以协同开发,换句话说,我们多个人可以共同写一个类,如下所示:
只是提供接口,子类具体实现方法,在类的前面加上interface,在游戏中使用的也是比较广泛,示例如下所示:
在游戏中经常使用比如我们加载不同的配置文件,每个配置文件有自己的类结构体,需要具体实现,这样就非常适合使用模板函数解决问题,还有增加组件,也适用于模板等等。当然模板也适合用于模板类,比如我们的单例模板,管理类模板等等。其实Unity它自身的类也大量使用了模板函数,在项目中举个简单的例子,如下所示:
where表示的是条件限制,new表示的必须要有无参数的构造函数。
类似C++中的指针,是一种回调函数。委托是比较常用的,比如我们的UI中使用的Button等响应事件都可以用委托,还有事件监听也常用delegate等等,这个比较常用就不举例子了。
在游戏项目中也经常使用,attribute,Attribute本质上就是一个类,它附着在目标对象上最终实例化,attribute实例化也是有自己的特点:
第一、不通过new操作符来产生实例,而是使用在方括号里调用构造方法来产生实例。
第二、方括号必须紧挨着放置在被附着目标的前面。
第三、不能使用对象初始化器给对象的属性(Property)赋值,必须使用含参构造方法对Attribute实例中的属性赋值。
详情可以参考网址:https://docs.microsoft.com/en-us/dotnet/api/system.attribute?redirectedfrom=MSDN&view=netframework-4.7.2
我们说的用ILRuntime进行热更新同样可以使用Attribute帮助我们解决,下面介绍我们在项目中的应用,我们使用的是自定义属性,注意必须继承System.Attribute。
在上面中的方括号中使用的AttributeUsage就是属性的设置,继续我们自定义的实现,这个是具体实现了。如下所示:
我们自定义的属性写完了如何使用了,截取一段代码给读者简单的展示一下,代码类似如下所示:
component = (Component)Activator.CreateInstance(type);
aAwakeSystem = this.awakeSystems[component.GetType()];
IAwake iAwake = aAwakeSystem as IAwake;
iAwake.Run(component);
我们还可以将其打包成dll库,这样就可以做到热更新了。
public void DownloadResources(Action> downloadComplete, Action downloadProgress, Func filter, params string[] resources)
{
DownloadResources(downloadComplete, downloadProgress, filter, false, resources);
}
前面代码使用了Action不带参数,后面使用了Action带参数的以及Func带参数的。我们将其应用在资源下载,最终在程序中的调用如下所示: