视频教程:http://www.bilibili.com/video/av3246302/
https://www.bilibili.com/video/av6271851/
作者:风农
面向对象开发教程
属性
属性是比公共变量更好的访问类内部变量的方法。其本身类似于变量,在其内部封装了一些变量(域),封装可以更好的控制域被访问的过程。标准形式如下:
private int exp;
public int Exp
{
get
{
return exp;
}
set
{
exp=value;
}
}
或
public int exp{get;set;}
这样做的好处是,可以通过不写get或set控制变量只读或只写,或在get和set函数中进行计算。
Static
静态成员和方法属于类本身,被所有类的实例所共享,可以通过类名直接访问。unity也有很多静态方法如Input.getAxis。
注意:静态方法中不能使用非静态变量。
静态类不能有实例,是一个完全由静态变量和函数组成的类。
泛型
//泛型方法定义
public T GenericMethod<T,U,V>(T param)where T:
{
return param;
}
//调用
myClass.GenericMethod<int>(5);
可以在“where T:”后面加上对类型T的限定。
也可以声明泛型类,然后在类内部正常的使用类型T:
//类定义
public class GenericClass<T>
{
T item;
public void UpdateItem(T i);
}
//初始化类对象
GenericClass<int> myClass=new GenericClass<int>();
myClass.UpdateItem(5);
泛型常应用于集合,如字典、列表等。
接口
接口是功能的一种约定,实现接口的类必须实现接口规定的所有函数和属性。
接口的好处在于可以跨越类型,定义常用的功能,并且根据接口大致知道这个类能做什么。并且类可以实现多个接口,但只能继承一个父类,实现接口比继承父类更加灵活。
接口没有自己的实例。
接口名通常是大写字母I开头的,经常以able结尾,如IDamageable。
扩展方法Extension Methods
用来给类型增加功能,而不用创建一个衍生类型或修改原类型,因此很适用于需要增加类功能,但不能修改类本身的情况。
拓展方法必须放在无泛型的静态类中。
//定义
public static class ExtensionMethods
{
public static void ResetTransformation(this Transform trans)
{
}
}
第一个参数要用this关键字修饰,这个参数指明了方法会成为哪个类的一部分,调用函数的时参数隐含的变成transform的实例,不需要再提供。后面的参数就不再需要this关键字了。
现在这个方法已经视为transform类的一部分。
//调用
transform.ResetTransformation();//直接使用就好,也不用传参。
命名空间
主要目的是作为类的容器帮助整理脚本,避免脚本间冲突。
列表和字典Lists&Dictionaries
list是动态大小的数组,可以像数组一样访问。(System.Colletions.Generic)
对于实现了IComparable接口的类,list还可以用sort函数进行排序。
字典是存储键值对的数据结构,其主要目的是查询。注意:如果键不存在会抛出异常,因此如果不确定是否会抛出异常就使用TryGetValue函数,如:
if(guys.TryGetValue("birds",out temp))//不过这样做性能差一点
{
}
协程Coroutine
是间隔调用的函数,用yield声明将代码执行流程跳到函数外,yield的返回值控制何时恢复协同程序从刚刚的位置继续向下执行。
//定义
IEnumerator MyCoroutine(Transform target)
{
while(Vector3.Distance(transform.position,target.position)>0.05f)
{
transform.position=Vector3.Lerp(transform.position,target.position,smoothing*Time.DeltaTime);
yield return null;
}
print("reached");
yield return new WaitForSeconds(3f);
print("myRoutine now finished");
}
//调用
StartCoroutine(MyCoroutine(target));
委托Delegate
可以简单的视为函数的容器,可以像变量一样传递和赋值函数。
在delegate脚本中,首先定义一个模板,模板定义了什么类型的函数可以赋值到委托中。如玩家受伤、攻击等事件发生时就可以广播给所有订阅了事件的函数知道。注意不用了之后取消订阅非常重要,否则会造成内存泄漏和一些错误。
delegate void MyDelegate(int num);
MyDelegate myDelegate;
void Start()
{
myDelegate=PrintNum;//将函数赋值给delegate,然后像函数一样使用delegate
myDelegate(50);
myDelegate=DoubleNum;
myDelegate(50);
myDelegate+=PrintNum;//一个delegate可以包含多个函数
myDelegate-=PrintNum;//从delegate中除去一个函数
}
void PrintNum(int num)
{
}
void DoubleNum(int num)
{
}
属性Attributes
可以在声明时对函数、变量或类添加额外信息。
如:
[Range(0,100)]//限定某个变量的范围
public int speed=0;
事件Events
是一种特殊的委托。可以视为一个健壮灵活的广播系统,任何对事件感兴趣的类都可以向事件订阅,以在事件发生时调用注册的函数。广播系统本身对注册函数完全不了解,注册函数之间也完全不了解,只需关注触发事件。
注意:写订阅的时候要注意在对象销毁的时候注销订阅。