1.消息定长,比如定一个100,那么读取端每次读取数据就截取100个长度的数据,然后交给业务成去做解析
2.在消息的尾部加一些特殊字符,那么在读取数据的时候,只要读到这个特殊字符,就认为已经可以截取一个完整的数据包了,这种情况在一定的业务情况下实用。
3.读取缓存的数据是不定长的,所以我们把读取到的数据添加到我们自己的一个byte[]数组中,然后根据我们的业务逻辑来找到指定的特殊协议头部,协议长度,协议尾部,然后从我们的byte[]中获取一个完整的数据包,然后再对数据包进行业务解析就可以得到正确结果。
发送的内容可以是数字,字符串 或者是 对象,但是他们在传输的过程中都将被转化为字节流
所谓“心跳包”机制,其实就是服务器端按照固定的频率给客户端发送心跳包,客户端接受到心跳包之后做回应。如果服务器端发送了一个心跳包,客户端没有回应。服务器认为客服端已经不在了,就会断开长连接。
说明: 服务器只是在客户端长时间没有给服务器发送数据的情况下,才会发心跳包。
4如果客户机收到服务器的应答包,则说明服务器正常,删除超时定时器
5如果客户端的超时定时器超时,依然没有收到应答包,则说明服务器挂了
粗略的做法是,当客户端调用send或recv失败,然后WSAGetLastError()判断错误编号,然后关闭socket。再创建一个socket。然后进行connect操作。
调用Socket的sendUrgentData(0xFF)发送1个字节的心跳包
如果socket为null说明断开连接;重建Socket连接,并开启IO
重建连接时如果连接不上,出现异常,那就休眠10秒,之后进入新一轮循环
5.TCP/IP、UDP实现有什么区别?HTTP有什么优势?
TCP连接在客户端和服务端数据通信前,会进行三次确认才会正式建立连接,也即是三次握手。特点是面向连接,适合进行大数据量、持续连接的网络通讯。
UDP连接无连接,不需要确认连接,即可进行数据通信。特点是无连接,适合小数据量,高突发性,高频率的网络通信。
6.AssetBundle是如何打包的?打包的具体步骤有哪些?
https://www.tuicool.com/articles/ieYJBf
打包需要在UnityEditor下编写一些简单的代码,来取出你要打包的资源,然后调用打包方法进行打包
在使用的时候,需要用WWW来加载Bundle,然后再用加载出来的Bundle来Load资源
7.AssetBundle加载资源的过程是如何的,试着写一下。
点了运行之后,将我在StreamAssests下生成的AB包copy一份到C盘中的某个路径
开启更新模式 会从服务器下载一份file.txt和本地进行MD5的比对
若不一样会从服务器下载对应的MD5值文件 放到C盘 完成更新
优点:灵活,可以加载Application.streamingAssetsPath、Application.persistentDataPath目录下的资源,以及从网络上下载资源
3、AssetBundle.CreateFromFile(string path)
优点:同步,可以加载Application.persistentDataPath目录下的AssetBundle
缺点:AssetBundle不能压缩,在Android下不能加载Application.streamingAssetsPath下的AssetBundle
4、AssetBundle.CreateFromMemoryImmediate(byte[] binary)
优点:同步,可以加载Application.persistentDataPath目录下压缩过的AssetBundle
缺点:在Android下不能加载Application.streamingAssetsPath下的AssetBundle
10.NGUI和UGUI有和区别?他们的适配都是如何去做的?为什么不使用NGUI?
3) UGUI通过Mask来裁剪,而NGUI通过Panel的Clip
4) NGUI的渲染前后顺序是通过Widget的Depth,而UGUI渲染顺序根据Hierarchy的顺序,越下面渲染在顶层.
5) UGUI 不需要绑定Colliders,UI可以自动拦截事件
6) UGUI的Anchor是相对父对象,没有提供高级选项,个人感觉uGUI的Anchor操作起来比NGUI更方便
7) UGUI没有Atlas一说,使用Sprite Packer
9) UGUI的事件需要实现事件系统的接口,但写起来也算简单
1) NGUI还保留着图集,需要进行图集的维护。而UGUI没有图集的概念,可以充分利用资源,避免重复资源。
4) UGUI没有 UIWrap 来循环 scrollview 内容。
NGUI更适合做游戏界面UI、游戏背包UI、游戏技能UI等UI
之所以不用NGUI是因为UGUI是Unity官方推出的,慢慢会成为制作UI的主要工具,配套的插件也越来越多,但是具体使用NGUI还是UGUI还要看公司这边,因为这两个我都用过一段时间。
12.如何打Android包?具体的设置、步骤和注意事项有哪些?
1.判断其是否注册 2.生成(点击Lua->Clear wrap files ->确定)
1.如果一个C#方法要被Lua调用,则首先要将其注册到Lua虚拟机中(LuaState.RegisterFunction)。之后,在Lua中就可以通过注册的名称来调用这个C#方法。
(1)首先要在Lua虚拟机中加载该函数(LuaState.DoFile)。
(2)拿到目标函数(LuaState.GetFunction)。
c# 通过Pinvoke方式调用了lua的dll(一个C库),然后这个dll执行了lua脚本。
开发者为了防止代码泄漏,在发布前一般会对脚本进行加密,加密方式有多种, 比如常见的AES, XXTEA .. 等等,在cocos2dx加载加密后的lua文件后,解密之后再 执行.
LOD:全称Level Of Detail,中文翻译“细节级别渐变”,顾名思义,不同的级别展示不同的细节,那么究竟这个技术是如何运用在游戏项目中的呢?通过例子我们来学习一下。关于为什么要使用这个技术,和游戏优化是密不可分的,使用这个技术可以减少需要处理的模型顶点数目,降低GPU性能瓶颈的风险。
原理:当模型离摄像机(可以是人物摄像机或其他摄像机)很远时,然后根据距离的远近使用不同模型级别,远的时候就选择低级别的模型,近的时候选择高细节模型,这样就可以减少模型上面的顶点和面片数量从而提高性能。
LOD 技术即Levels of Detail的简称,意为多细节层次。LOD技术指根据物体模型的节点在显
环境中所处的位置和要度,决定物体渲染的资源分配,降低非重要物体的面数和细节度,
缺点: 加重美工的负担,要准备不同细节的同一模型,同样的会稍微增加游戏的容量
4 正如上面所说,mipmap针对的是纹理贴图,大白话就是,一个模型身上会有贴图,当我们对这个贴图使用了MipMap技术之后,那么在游戏运行中这个模型的贴图会根据摄像机距离模型的远近而调整不同的不同质量的贴图显示。
在这个游戏场景中,我们给一个模型贴了一个木纹贴图,当我们没有对这个贴图使用Mip M ap技术的时候,无论我们摄像机距离模型的位置在哪,这张贴图永远都是显示一样的,这样是完全没有必要的,我们使用这个技术就是为了让当摄像机比较远的时候,你用在精细的贴图我们玩家也看不见,而且还浪费资源,提高了性能瓶颈。
Mipmap技术有点类似于LOD技术,但是不同的是,LOD针对的是模型资源,而Mipmap针对的纹理贴图资源
使用Mipmap后,贴图会根据摄像机距离的远近,选择使用不同精度的贴图。
缺点:会占用内存,因为mipmap会根据摄像机远近不同而生成对应的八个贴图,所以必然占内存!
优点:会优化显存带宽,用来减少渲染,因为可以根据实际情况,会选择适合的贴图来渲染,距离摄像机越远,显示的贴图像素越低,反之,像素越高!
在游戏运行时实例化,prefab 相当于一个模版,对你已有的素材、脚本、参数做一个默认
配置,以便于以后修改,同时 prefab 打包的内容简化了导出的操作,便于团队的交流
优点:当你场景中有大量相似的物体,如游戏中的小怪时就可以用prefab来对这些物体进行统一管理,这样当你需要修改物体属性时,只要修改一个物体,然后apply给prefab其他的物体也就一起改好了。还有当你需要用代码动态创建物体时也是用prefab的
20.数据结构你都了解哪些?对你知道的各数据结构的效率进行排序。
在声明List集合时,我们需要为其声明List集合内数据的对象类型。
而ArrayList会把所以插入其中的数据都当做object来处理
23.MonoBehaviour的生命周期中关键方法有哪些,执行顺序是怎样的?
Awack-->Start-->Update-->LateUpdate-->OnDisable-->OnDestroy
象类是单继承
多线程程序同时运行多个线程 ,而在任一指定时刻只有一个协程在运行,并且这个正在运
行的协同程序只在必要时才被挂起。除主线程之外的线程无法访问 Unity3D 的对象、组件、
Unity3d 没有多线程的概念,不过 unity 也给我们提供了 StartCoroutine(协同程序)和
LoadLevelAsync(异步加载关卡)后台加载场景的方法。 StartCoroutine 为什么叫协同
程序呢,所谓协同,就是当你在 StartCoroutine 的函数体里处理一段代码时,利用 yield
语句等待执行结果,这期间不影响主程序的继续执行,可以协同工作。而 LoadLevelAsync
则允许你在后台加载新资源和场景,所以再利用协同,你就可以前台用 loading 条或动画提
区别:1.值类型存储在内存栈中,引用类型数据存储在内存堆中,而内存单元中存放的
3.值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针和引用。
4.栈的内存是自动释放的,堆内存是.NET 中会由 GC 来自动释放。
5.值类型继承自 System.ValueType,引用类型继承自 System.Object。
2.stack的空间由操作系统自动分配和释放,heap的空间是手动申请和释放的,heap常用new关键字来分配。
1.委托允许直接通过委托去访问相应的处理函数,而事件只能通过公布的回调函数去调用
2.事件只能通过“+=”,“-=”方式注册和取消订户处理函数,而委托除此之外还可以使用“=”直接赋值处理函数。事件只能在当前定义的类结构中调用,不能在外部调用。
30.Unity如何优化刷帧率?如何优化包体?如何优化内存?
35.Unity中的特殊目录有哪些?分别有什么作用?打包要注意什么?
Editor:在这里可以存放一些编辑器扩展脚本,这个目录里面的脚本可以namespace UnityEditor.Editor下面放的所有资源文件或者脚本文件都不会被打进发布包中,并且脚本也只能在编辑时使用。一般呢会把一些工具类的脚本放在这里,或者是一些编辑时用的DLL
Plugins:这里面就是放Native插件的,而引入的其他包不必要放在这里。它应该为目标平台建立子目录:"Plugins/Android"、"Plugins/iOS"等。
Resources:Resources文件夹允许你在脚本中通过文件路径和名称来访问资源。但还是推荐使用直接引用来访问资源。
StreamingAssets:这里的文件会被拷贝到build文件夹中,不会修改(移动和网页版不同,他们会被嵌入到最终build文件中)。它们的路径会因平台而有差异,但都可以通过Application.streamingAssetsPath来访问。
36.函数中多次使用string的+=处理,会产生大量内存垃圾(垃圾碎片),有什么好的方法可以解决
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式
2.定义方式不同 重载方法名相同 参数列表不同 重写方法名和参数列表都相同
3.调用方式不同 重载使用相同对象以不同参数调用 重写用不同对象以相同参数调用
封装是将数据和行为相结合,通过行为约束代码修改数据的程度,增强数据的安全性,属性是C#封装实现的最好体现。
多态性是指同名的方法在不同环境下,自适应的反应出不同得表现,是方法动态展示的重要手段。
45.请简述关键字 Sealed 用在类声明和函数声明时的作用
类声明时可防止其他类继承此类,在方法中声明则可防止派生类重写此方法。
可以在加载程序运行时,动态获取和加载程序集,并且可以获取到程序集的信息
反射即在运行期动态获取类、对象、方法、对象数据等的一种重要手段
通过以上核心类可在运行时动态获取程序集中的类,并执行类构造产生类对象,动态获取对象的字段或属性值,更可以动态执行类方法和实例方法等。
47.在类的构造函数前加上 static 会报什么错?为什么?
构造函数格式为 public+类名如果加上 static 会报错(静态构造函数不能有访问修饰符)
运行库创建类实例或者首次访问静态成员之前,运行库调用静态构造函数;
48.C# String 类型比 stringBuilder 类型的优势是什么?
如果是处理字符串的话,用 string 中的方法每次都需要创建一个新的字符串对象并且分配新的内存地址,而 stringBuilder 是在原来的内存里对字符串进行修改,所以在字符串处理
方面还是建议用 stringBuilder 这样比较节约内存。但是 string 类的方法和功能仍然还是比 stringBuilder 类要强。
string 类由于具有不可变性(即对一个 string 对象进行任何更改时,其实都是创建另外一个 string 类的对象),所以当需要频繁的对一个 string 类对象进行更改的时候,建议使用StringBuilder 类,StringBuilder 类的原理是首先在内存中开辟一定大小的内存空间,当对此 StringBuilder 类对象进行更改时, 如果内存空间大小不够, 会对此内存空间进行扩充,而不是重新创建一个对象,这样如果对一个字符串对象进行频繁操作的时候,不会造成过多的内存浪费,其实本质上并没有很大区别,都是用来存储和操作字符串的,唯一的区别就在于性能上。
String 主要用于公共 API,通用性好、用途广泛、读取性能高、占用内存小。
StringBuilder 主要用于拼接 String,修改性能好。
不过现在的编译器已经把 String 的 + 操作优化成 StringBuilder 了, 所以一般用
List,HashTable,Dictionary,Stack,Queue
HashTable/Dictionary:散列表格式 查询效率高 空间占用较大
50.C#中unsafe关键字是用来做什么的?什么场合下使用?
ref修饰参数,表示进行引用传递,out修饰参数也表示进行引用传递,但传递的引用只为带回返回值 ref又进又出 out不进只出
52.For,foreach,Enumerator.MoveNext的使用,与内存消耗情况
for 循环可以通过索引依次进行遍历,foreach和Enumerator.MoveNext通过迭代的方式进行遍历。
但是在Unity中的Update中,一般不推荐使用foreach 因为会遗留内存垃圾。
53.当需要频繁创建使用某个对象时,有什么好的程序设计方案来节省内存?
54.GameObject a=new GameObject() GameObject b=a 实例化出来了A,将A赋给B,现在将B删除,问A还存在吗?
存在,b删除只是将它在栈中的内存删除,而A对象本身是在堆中,所以A还存在
GUI不方便控制,UGUI所见即所得,方便控制。GUI使用在生命周期函数OnGUI中使用,脚本来书写控制。UGUI使用Canvas画布和事件系统。UGUI适应屏幕上比GUI简单。
56.一个场景放置多个carmera并同时处于活动状态,会发生什么
实际看到的画面由多个 camera 的画面组成,由 depth、Clear Flag、Culling Mask 都会影
二 2D 游戏制作 推荐:2D Toolkit //[ˈtu:lkɪt] 工具包,工具箱三
六 美术及动画制作 推荐:RageSpline,Smooth Moves
七 画面增强 推荐:Bitmap2Material,Strumpy Shader Editor
59.为什么 dynamic font 在 unicode 环境下优于 static font
Unicode 是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。
使用动态字体时,Unity 将不会预先生成一个与所有字体的字符纹理。当需要支持亚洲语言
或者较大的字体的时候,若使用正常纹理,则字体的纹理将非常大。
60.Render 的作用?描述 MeshRender 和 SkinnedMeshRender 的关系与不同
Mesh 就是指模型的网格(同名组件是用于调整网格属性的),MeshFilter 一般是用于获得
模型网格的组件,而 MeshRender 是用于把网格渲染出来的组件
Skinned Mesh 中文一般称作骨骼蒙皮动画.这种动画中包含骨骼( Bone )和蒙皮 (Skinned Mesh) 两个部分, Bone 的层次结构和关节动画类似, Mesh 则和关节动画不同:关节动画中是使用多个分散的 Mesh, 而 Skinned Mesh 中 Mesh 是一个整体,也就是说只有一个 Mesh, 实际上如果没有骨骼让 Mesh 运动变形, Mesh 就和静态模型一样了。Skinned Mesh 技术的精华在于蒙皮,所谓的皮并不是模型的贴图。而是 Mesh 本身,蒙皮是指将 Mesh 中的顶点附着(绑定)在骨骼之上,而且每个顶点可以被多个骨骼所控制,这样在关节处的顶点由于同时受到父子骨骼的拉扯而改变位置就消除了裂缝。可以理解为具有蒙皮信息的 Mesh 或可当做皮肤用的 Mesh ,这个皮肤就是 Mesh 。而为了有皮肤功能, Mesh 还需要蒙皮信息,即 Skin 数据,没有 Skin 数据就是一个普通的静态 Mesh 了。 Skin 数据决定顶点如何绑定到骨骼上。顶点的 Skin 数据包括顶点受哪些骨骼影响以及这些骨骼影响该顶点时的权重 (weight) ,另外对于每块骨骼还需要骨骼偏移矩阵 (BoneOffsetMatrix) 用来将顶点从 Mesh 空间变换到骨骼空间。
62.当一个细小的高速物体撞向另一个较大的物体时,会出现什么情况?如何避免?
穿透(碰撞检测失败)(碰撞体变大,FixedUpdate, 代码限制)
63.MeshRender 中 material 和 sharedmaterial 的区别?
修改 sharedMaterial 将改变所有物体使用这个材质的外观,并且也改变储存在工程里的材质设置。
不推荐修改由 sharedMaterial 返回的材质。如果你想修改渲染器的材质,使用 material替代。
64.CharacterController 和 Rigidbody 的区别
Rigidbody 具有完全真实物理的特性, 而 CharacterController 可以说是受限的 Rigidbody,
Hinge Joint ,他可以模拟两个物体间用一根链条连接在一起的情况,能保持两个物体在
一个固定距离内部相互移动而不产生作用力,但是达到固定距离后就会产生拉力。 (简单说
67.动画层(Animation Layers)的作用是什么?
动画层作为一个具有层级动画编辑概念的工具, 可以用来制作和处理任何类
68.Material 和 Physic Material 区别?
PhysicMaterial 物理材质:物理材质描述,如何处理物体碰撞(摩擦,弹
性)。Material 材质(材质类)为了获得一个对象使用的材质,可
69.请简述 NGUI 中 Panel 和 Anchor 的作用
Anchor 包含 UIAnchor 脚本。 UIAnchor 的功能是把对象锚定在屏幕的边缘 (左上, 左中,
左下,上,中,下,右上,右中,右下),或缩放物体使其匹配屏幕的尺寸
Panel 对象有 UIPanel 脚本,UIPanel 是一个容器,它将包含所有 UI 小部件,并负责将
70.LayerMask.NameToLayer()这个方法有什么作用?
LayerMask 的使用是按位操作的,LayerMask.NameToLayer("Players") 返回该 Layer
Unity 的脚本语言基于 Mono 的.Net 平台上运行,可以使用.NET 库,这也为 XML、数据
Unity 里的脚本都会经过编译,他们的运行速度也很快。这三种语言实际上的功能和运行速
JavaScript:和网页中常用的 JavaScript 不一样,它编译后的运行速度很快,语法方面也
Boo:可以看做是 Python 语言的变种,又糅合了 Ruby 和 C#的特性,它是静态类型语言
72.Unity3D 是否支持写成多线程程序?如果支持的话需要注意什么?
仅能从主线程中访问 Unity3D 的组件,对象和 Unity3D 系统调用
支持:如果同时你要处理很多事情或者与 Unity 的对象互动小可以用 thread,否则使用
注意:C#中有 lock 这个关键字,以确保只有一个线程可以在特定时间内访问特定的对象
FixedUpdate,每固定帧绘制时执行一次,和 update 不同的是 FixedUpdate 是渲染帧执行,
如果你的渲染效率低下的时候 FixedUpdate 调用次数就会跟着下降。FixedUpdate 比较适用
于物理引擎的计算,因为是跟每帧渲染有关。Update 就比较适合做控制。
LateUpdate,,是在所有 update 结束后才调,比较适合用于命令脚本的执行。官网上例子是
摄像机的跟随,都是在所有 update 操作完才跟进摄像机,不然就有可能出现摄像机已经推
75.Application.loadLevel 命令为:(A)
79.localPosition 与 Position 的使用区别?
localPosition:自身位置,相对于父级的变换的位置。 Position:在世界坐标 transform
80.含义 Mathf.Round Mathf.Clamp Mathf.Lerp
AddClip 添加剪辑、Blend 混合、Play 播放、Stop 停止、Sample 采
82.用鼠标实现在场景中拖动物体,用鼠标滚轮实现缩放(用一个 Cube 即可)。
在场景中添加一个Plan,Camera,Directional Light,Cube。添加两个脚本一个挂在Camera上,另一个挂在Cube上。
1.鼠标滚轮实现缩放:将摄像机的镜头拉近或者拉远,调整摄像机的视角就可以实现
2.鼠标实现在场景中拖动物体:解决思路就是将世界坐标转换成屏幕坐标,然后计算物体与鼠标之间移动量,循环鼠标被按下操作,得到鼠标的当前位置,加上计算好的移动量,将新的坐标赋值给物理就行了。
具体代码实现:http://www.cnblogs.com/hewencong/p/4299722.html
83.NGUI Button 怎样接受用户点击并调用函数,具体方法名称是什么
1、主要是在UICamera脚本中用射线判断点击的物体并通过SendMessage调用OnClick() OnPress()等函数,可以说NGUI的按钮是通过发消息这个方式调用的。具体方法名称是OnClick()
GameObject button = GameObject.Find("UI Root/Button3");
//设置这个按钮的监听,指向本类的ButtonClick方法中。
UIEventListener.Get(button).onClick = OnButton3Click;
private void OnButton3Click(GameObject button)
MonoBehaviour.OnLevelWasLoaded
85.itween 插件的作用是什么,itween 作用于世界坐标还是局部坐标,请列举出 3 个其常
iTween 是一个动画库,作者创建它的目的就是最小的投入实现最大的产出。让你做开
发更轻松,用它可以轻松实现各种动画,晃动,旋转,移动,褪色,上色,控制音频等等“
方法:a、MoveTo 物体移动 ;b、ColorTo:随着时间改变对象的颜色组; c、LookTo: