赞
踩
目录
请简述private,public,protected,internal的区别?
描述接口(Interface)与抽象类(abstract class)之间的相同点及区别?如何选择抽象类和接口?(个人理解)
描述结构体(Struct)与类(class)之间的区别?如何选择结构体与类?(个人理解)
Unity中的碰撞器(Collider)和触发器(Trigger)的区别?
值类型和引用类型
值类型:简单数据类型(整数类型:sbyte,short,int,long,byte,ushort,uint,ulong;浮点数类型:float,double;布尔类型:bool;字符类型:char);枚举;结构体
引用类型:对象类;数组类;字符串类(string);接口类;委托类
1.值类型的数据存储在内存的栈上;引用类型的数据存储在内存的堆中;引用类型的变量持有的是数据的引用,引用在栈上
2.值类型存取速度快,引用类型存取速度慢
3.值类型表示的是实际数据,引用类型表示的是指向存储在内存堆中的数据的引用
4.值类型继承System.ValueType;引用类型继承System.Object
1.栈的空间由操作系统自动分配和释放,堆的空间是手动申请和释放的,堆常用new关键字来分配,堆在.NET中会有GC来释放
2.栈的空间有限,堆的空间很大
1.ArrayList存在不安全类型 :ArrayList会把所有插入其中的数据当成Object来处理,装箱拆箱操作费时
2.List是接口,ArrayList是一个实现了该接口的类,可以被实例化
装箱:将值类型转换成引用类型
拆箱:将引用类型转成值类型
sealed修饰的类为密封类,类声明时可以防止其他类继承此类,在方法中声明则防止派生类重写此方法。
private:仅仅对该类公开
public:对任何类都公开
protected:对该类及该类的派生类(子类)公开
internal:只能在包含该类的程序集中访问该类
重写(overriding):子类的方法覆盖父类的方法,要求返回值、方法名和参数都相同。
方法重载(overloading):重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同,
相同点:
1.都可以被继承
2.都不能直接实例化
3.都可以包含方法的声明
4.子类必须实现未实现的方法
5.都遵循里氏替换原则
不同点:
1.抽象类中可以有构造函数,接口不能有
2.抽象类只能被单一继承,接口可以实现多个
3.抽象类中有成员变量,接口中没有
4.抽象类中可以声明成员方法,虚方法,没有实现的抽象方法,静态方法,接口只能声明没有实现的抽象方法
5.抽象类方法可以使用访问修饰符,接口中建议不写,默认为public
选择方式:表示对象的用抽象类,表示行为的用接口,不同对象拥有共同的行为往往使用接口
1.结构体是值类型,类是引用类型
2.结构体存在栈上,类存在堆中
3.结构体成员不能使用protected访问修饰符,类可以
4.结构体成员变量声明不能指定初始值,类可以
5.结构体不能声明无参构造函数,类可以
6.结构体声明有参构造函数后,无参构造函数会被顶掉
7.结构体不能声明析构函数,类可以
8.结构体不能被继承,类可以
9.结构体需要在构造函数中初始化所有成员变量,类随意初始化
10.结构体不能被静态static修饰(不存在静态结构体),类可以
11.结构体不能在自己的内部声明和自己一样的结构体变量,类可以
选择方式:
1.使用继承或者是多态时,选择类
2.对象是数据集合时,考虑结构体,例:坐标,位置等
3.从值类型和引用类型上考虑,存储的数据量大用类,速度快用结构体
ref引用参数和out引用参数的效果一样,都是通过关键字找到内存地址
区别就是使用 ref 进行参数的传递时,该参数在创建时,必须设置其初始值,所以ref 侧重于修改,采用 out 参数传递时,该参数在创建时,可以不设置初始值,但是在方法中必须初始化,所以 out 侧重于输出
1.C#中事件:事件时属于类的成员,所以要放在类的内部,C#事件本质就是对消息的封装,用作对象之间的通信;发送方叫事件发送器,接收方叫事件接收器
2.委托属于一个定义,是和类、接口类似的,通常放在外部,若定义在类的内部,则必须通过调用该类的成员才能取得其委托的引用
GC回收堆上的内存
避免:
1.减少new产生的对象的次数
2.大量修改string时用stringbuilder
3.适当使用静态成员
审查元数据并收集关于它的类型信息的能力。实现原理:在运行时根据程序集及其中的类型得到元数据。
脚本生命周期调用顺序:Awake -> OnEnable -> Start -> FixedUpdate -> Update -> LateUpdate -> OnDisable -> OnDestory;
Awake:脚本实例被载入(将脚本附加给游戏物体(激活))时调用,只调用一次;
OnEnable:当对象变为可用(enabled = true)或激活状态(activeSelf = true)时此函数被调用;(反复启用反复调用)
Start:脚本实例被启用时(脚本前面的勾选上时)调用,只调用一次;
FixedUpdate:物理更新(物理运动),帧率稳定,两帧之间的间隔时间固定是0.02;
Update:当MonoBehaviour启用时,其Update在每一帧被调用;
LateUpdate:晚于Update函数,一般用来摄像机第三人称跟随;
OnDisable:当对象变为不可用或非激活状态时此函数被调用。(反复不可用反复调用);
OnDestroy:当前游戏物体被销毁时调用;
在主线程运行的同时在开启另一段逻辑处理来协助当前程序的执行,协程不是多线程,Unity的协程在每一帧结束以后检测yield的条件是否满足。
两个物体都必须带有碰撞器(Collider)组件 ,其中一个物体还必须带有刚体(Rigidbody)组件,最好是运动的一方带有刚体(Rigidbody)组件。
触发器是碰撞器上的一个属性,当Is Trigger = false时,产生碰撞效果。调用OnCollisionEnter,OnCollisionStay,OnCollisionExit函数,当Is Trigger = true时,禁用碰撞效果,可以调⽤OnTriggerEnter,OnTrrigerStay,OnTrrigerExit函数。
如果既要检测到物体的接触⼜不想让碰撞检测影响物体移动或要检测⼀个物件是否经过空间中的某个区使用触发器
Rigidbody.AddForce/Rigidbody.AddForceAtPosition
LOD多层次细节 ,是常用的游戏优化技术,它按照模型的位置和重要程度决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算。缺点是增加了内存,以空间换时间。
MipMapping是在三维计算机图形的贴图渲染中的技术,目的是为了加快渲染速度,降低图像抗锯齿 ,贴图被处理成由计算机预先计算和优化过的图片,这些图片就被称为MipMap。
LightMap是在三维软件里实现打好灯光,然后把渲染到场景物体各表面的光照输出到贴图上,最后又通过引擎贴到场景上,使物体有光照的效果。
应用阶段 (CPU)-> 几何阶段(GPU) -> 光栅化阶段 (GPU)
应用阶段: 处理顶点数据
几何阶段:顶点着色器 ->曲面细分着色器 ->几何着色器 ->剪裁 ->屏幕映射
光栅化阶段:三角形设置 ->三角形遍历 ->片元着色器 ->逐片元着色器
内存的开销有三大部分:1.资源内存占用;2.引擎模块自身内存占用;3.托管堆内存占用
资源内存占用优化:
1.纹理的优化:降低最大分辨率;对于纹理的压缩;取消勾选Read/Write Enable;禁用多余的MipMap;打包图集
2.模型的优化:禁用掉Reader/Write Enables;不同设备使用不同的模型面数,尽量控制模型的面数;一个网格不要超过3个material
引擎模块自身内存占用优化:
1.保证AssetBundle被清干净,采用www加载了AssetBundle后,要用www.Dispose 及时释放
托管堆内存占用
1.尽量避免代码中的字符串拼接,因为这会给GC带来太多垃圾,拼接字符串StringBuilder
2.用简单的for循环代替foreach循环
3.为所有游戏内的动态物体使用内存对象池,可以减少系统开销和内存碎片,复用对象实例,构建自己的内存管理模式,减少Instantiate和Destory
4.删掉Log输出
待补充~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。