Unity面试必看系列
时间:2023-07-06 02:36:01 | 来源:网站运营
时间:2023-07-06 02:36:01 来源:网站运营
Unity面试必看系列:
一、 C#语言 1. 重载和重写的区别 1) 所处位置不同 重载在同类中 重写在父子类中
2) 定义方式不同 重载方法名相同 参数列表不同 重写方法名和参数列表都相同
3) 调用方式不同 重载使用相同对象以不同参数调用 重写用不同对象以相同参数调用
4) 多态时机不同 重载时编译时多态 重写是运行时多态
2. 面向对象的三大特点 封装、继承、多态 :
1.继承: 提高代码重用度,增强软件可维护性的重要手段,符合开闭原则。
2.封装: 封装是将数据和行为相结合,通过行为约束代码修改数据的程度,增强数据的安全性,属性 是 C#封装实现的最好体现。
3.多态性: 多态性是指同名的方法在不同环境下,自适应的反应出不同得表现,是方法动态展示的重要手段。
3. 简述值类型和引用类型有什么区别 1.值类型存储在内存栈中,引用类型数据存储在内存堆中,而内存单元中存放的 是堆中存放的地址。
2.值类型存取快,引用类型存取慢。
3.值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针和引用。
4.栈的内存是自动释放的,堆内存是.NET 中会由 GC 来自动释放。
5.值类型继承自 System.ValueType,引用类型继承自 System.Object。
4. 请简述 private,public,protected,internal 的区别 public:对任何类和成员都公开,无限制访问
private:仅对该类公开
protected:对该类和其派生类公开
internal:只能在包含该类的程序集中访问该类
protected internal:protected + internal
5. C#中所有引用类型的基类是什么 引用类型的基类是 System.Object 值类型的基类是 System.ValueType 同时,值类型也隐式继承自 System.Object
6. 请简述 ArrayList 和 List<Int>的主要区别 1.ArrayList 不带泛型 数据类型丢失
2.List<T> 带泛型 数据类型不丢失
3.ArrayList 需要装箱拆箱 List<T>不需要
7. 请简述 GC(垃圾回收)产生的原因,并描述如何避免? GC 为了避免内存溢出而产生的回收机制
避免:1)减少 new 产生对象的次数
2)使用公用的对象(静态成员)
3)将 String 换为 StringBuilder
8. 请描述 Interface 与抽象类之间的不同 1.接口不是类 不能实例化 抽象类可以间接实例化
2.接口是完全抽象 抽象类为部分抽象
3.接口可以多继承 抽象类是单继承
9. 下列代码在运行中会产生几个临时对象? 其实在 C#中第一行是会出错的(Java 中倒是可行)。应该这样初始化:
string b = new string(new char[]{'a','b','c'});
忽略错误的话:
1."abc"
2.a.ToUpper()
3."123"
4.a.ToUpper()+"123"
10.下列代码在运行中会发生什么问题?如何避免? 会产生运行时错误,因为 foreach 是只读的。不能一边遍历一边修改。
11.请简述关键字 Sealed 用在类声明和函数声明时的作用 类声明时可防止其他类继承此类,在方法中声明则可防止派生类重写此方法。
12.反射的实现原理? 可以在加载程序运行时,动态获取和加载程序集,并且可以获取到程序集的信息 反射即在运行期动态获取类、对象、方法、对象数据等的一种重要手段
主要使用的类库:System.Reflection
核心类:
1.Assembly 描述了程序集
2.Type 描述了类这种类型
3.ConstructorInfo 描述了构造函数
4.MethodInfo 描述了所有的方法
5.FieldInfo 描述了类的字段
6.PropertyInfo 描述类的属性
通过以上核心类可在运行时动态获取程序集中的类,并执行类构造产生类对象,动态获取对象的字段 或属性值,更可以动态执行类方法和实例方法等。
13. .Net 与 Mono 的关系? .Net 是一个语言平台,Mono 为.Net 提供集成开发环境,集成并实现了.NET 的编译器、CLR 和基础类 库,使得.Net 既可以运行在 windows 也可以运行于 linux,Unix,Mac OS 等。
14.在类的构造函数前加上 static 会报什么错?为什么? 构造函数格式为 public+类名如果加上 static 会报错(静态构造函数不能有访问修饰符)
原因:静态构造函数不允许访问修饰符,也不接受任何参数;无论创建多少类型的对象,静态构造函 数只执行一次;运行库创建类实例或者首次访问静态成员之前,运行库调用静态构造函数;静态构造 函数执行先于任何实例级别的构造函数;显然也就无法使用 this 和 base 来调用构造函数。
15.C# String 类型比 stringBuilder 类型的优势是什么? 如果是处理字符串的话,用 string 中的方法每次都需要创建一个新的字符串对象并且分配新的内存地 址,而 stringBuilder 是在原来的内存里对字符串进行修改,所以在字符串处理 方面还是建议用 stringBuilder 这样比较节约内存。但是 string 类的方法和功能仍然还是比 stringBuilder 类要强。
string 类由于具有不可变性(即对一个 string 对象进行任何更改时,其实都是创建另外一个 string 类的 对象),所以当需要频繁的对一个 string 类对象进行更改的时候,建议使用 StringBuilder 类, StringBuilder 类的原理是首先在内存中开辟一定大小的内存空间,当对此 StringBuilder 类对象进行更改 时, 如果内存空间大小不够, 会对此内存空间进行扩充,而不是重新创建一个对象,这样如果对一个 字符串对象进行频繁操作的时候,不会造成过多的内存浪费,其实本质上并没有很大区别,都是用来 存储和操作字符串的,唯一的区别就在于性能上。String 主要用于公共 API,通用性好、用途广泛、读取性能高、占用内存小。 StringBuilder 主要用于拼接 String,修改性能好。 不过现在的编译器已经把 String 的 + 操作优化成 StringBuilder 了, 所以一般用 String 就可以了 String 是不可变的,所以天然线程同步。 StringBuilder 可变,非线程同步。
16.C# 函数 Func(string a, string b)用 Lambda 表达式怎么写? (a,b) => {};
17.数列 1,1,2,3,5,8,13...第 n 位数是多少?用 C#递归算法实现 public int CountNumber(int num) {
if (num == 1 || num == 2) {
return 1;
} else { return CountNumber(num -1) + CountNumber(num-2);
}
}
18.冒泡排序(手写代码) public static void BubblingSort(int[]array) {
for (int i = 0; i < array.Length; i++){
for (int j = array.Length - 1; j > 0; j--){
if (array[j] < array[i]) {
int temp = array[j];
array[j] = array[j-1];
array[j - 1] = temp;
} } } }
19.C#中有哪些常用的容器类,各有什么特点。 List,HashTable,Dictionary,Stack,Queue
List:索引泛型容器 访问速度快 修改速度慢
HashTable/Dictionary:散列表格式 查询效率高 空间占用较大
Stack:后进先出
Queue: 先进先出
20.C#中常规容器和泛型容器有什么区别,哪种效率高? 不带泛型的容器需要装箱和拆箱操作 速度慢 所以泛型容器效率更高 数据类型更安全
21.有哪些常见的数值类? 简单值类型--包括 整数类型、实数类型、字符类型、布尔类型
复合值类型--包括 结构类型、枚举类型
22.C#中委托和接口有什么区别?各用在什么场合? 接口(interface)是约束类应该具备的功能集合,约束了类应该具备的功能,使类从千变万化的具体 逻辑中解脱出来,便于类的管理和扩展,同时又合理解决了类的单继承问题。
C#中的委托是约束方法集合的一个类,可以便捷的使用委托对这个方法集合进行操作。
在以下情况中使用接口:
1.无法使用继承的场合
2.完全抽象的场合
3.多人协作的场合 以上等等
在以下情况中使用委托:多用于事件处理中
23.C#中 unsafe 关键字是用来做什么的?什么场合下使用? 非托管代码才需要这个关键字 一般用在带指针操作的场合
24.C#中 ref 和 out 关键字有什么区别? ref 修饰参数,表示进行引用传递,out 修饰参数也表示进行引用传递,但传递的引用只为带回返回值 ref 又进又出 out 不进只出
25.For,foreach,Enumerator.MoveNext 的使用,与内存消耗情况 for 循环可以通过索引依次进行遍历,foreach 和 Enumerator.MoveNext 通过迭代的方式进行遍历。内存 消耗上本质上并没有太大的区别。但是在 Unity 中的 Update 中,一般不推荐使用 foreach 因为会遗留 内存垃圾。
26.函数中多次使用 string 的+=处理,会产生大量内存垃圾(垃圾碎片),有 什么好的方法可以解决。 通过 StringBuilder 那进行 append,这样可以减少内存垃圾
27.当需要频繁创建使用某个对象时,有什么好的程序设计方案来节省内存? 设计单例模式进行创建对象或者使用对象池
28.JIT 和 AOT 区别 Just-In-Time - 实时编译
执行慢 安装快 占空间小一点
Ahead-Of-Time - 预先编译
执行快 安装慢 占内存占外存大
29.给定一个存放参数的数组,重新排列数组 void SortArray(Array arr){Array.Sort(arr);}
30.Foreach 循环迭代时,若把其中的某个元素删除,程序报错,怎么找到那 个元素?以及具体怎么处理这种情况?(注:Try.....Catch 捕捉异常,发送 信息不可行) foreach 不能进行元素的删除,因为迭代器会锁定迭代的集合,解决方法:记录找到索引或者 key 值, 迭代结束后再进行删除。
31.GameObject a=new GameObject() GameObject b=a 实例化出来了 A, 将 A 赋给 B,现在将 B 删除,问 A 还存在吗? 存在,b 删除只是将它在栈中的内存删除,而 A 对象本身是在堆中,所以 A 还存在
32.你拥有 A 块钱,一瓶水 B 块钱,每瓶水可以得到一个瓶盖,每 C 个瓶盖 可以换一瓶水请写出函数求解上面题目,上面题目 ABC 为参数 public static int Buy(int a,int b,int c) {
return a/b + ForCap(c,a/b);
}
public static int ForCap(int c,int d) {
if (d<c) {
return 0;
} else {
return d/c + ForCap(c,d/c + d%c);
}}
33.有一排开关,第一个人把所有的开关打开,第二个人按 2 的倍数的开关, 第三个人按 3 的倍数的开关,以此类推,现在又 n 个开关,k 个人,写函 数求最后等两者的开关,输入参数 n 和 k static void Main(string[] args) {
int n = int.Parse(Console.ReadLine()); int k = int.Parse(Console.ReadLine());
Function(100,100);
}
static void Function(int n, int k) {
int i, j = 0;
bool[] a = new bool[1000]; //初始 false:关灯,true:开灯
for (i = 1; i <= k; i++) //k 个人
for (j = 1; j <= n; j++) //n 个灯
if (j % i == 0)
a[j] = !a[j]; //取反,false 变 true,原来开变关,关变开
for (i = 1; i <= n; i++) //最后输出 a[i]的值就可以了
if (a[i]) //灯亮着
Console.WriteLine(i);
}
34.数制转换,将任意整数转换成 8 进制形式 static void Main(string[] args) {
int n;
n =int.Parse(Console.ReadLine());
Console.WriteLine("输入的 10 进制为:{0}",n);
Console.Write("转换为 8 进制数为: ");
d2o(n);
}
static void d2o(int n) {
if (n > 7) {
d2o(n / 8);
}
Console.Write(n%8);
}
35.找出 200 以内的素数。 static void Main(string[] args) {
int count = 0;
for (int i = 1; i < 200; i++) { //外层循环:要判断的数
for (int j = 2; j <=i; j++){
if (i % j == 0&& i!=j) {
break;
}
if (j == i ) { //结束的条件:最后一个数还没有被整除
count++;
Console.WriteLine(i);
} }
}
Console.WriteLine(count);
}
36.打印杨辉三角形 public static void YHSJ(){
int [][]a= new int[7][] ;
a[0] = new int[1]; //a[0][0]=1;
a[1] = new int[2] ;
for (int i = 0; i < 7; i++) {
a[i] = new int[i+1] ;
a[i][0] =1;
a[i][i]=1;
if(i>1) { //求出中间的数据
for(int j=1;j<i; j++){
a[i][j]= a[i-1][j-1]+a[i-1][j];
}
}
}
for (int i=0; i<a.Length; i++) {
for (int k = 0; k < a.Length-1-i; k++) {
Console.Write("");
}
for(int j=0;j<a[i].Length; j++ ) {
Console.Write(a[i][j] + "");
}
Console.WriteLine();
}
}
37.中国有句俗话“三天打鱼两天晒网”,某人从 2000 年 1 月 1 日起开始 “三天打鱼两天晒网”,问这个人在今后的某天中“打鱼”还是”晒网” public static void Compute(){
Console.WriteLine ((DateTime.Now - DateTime.Parse("2000-01-01")).Days%5<3?"打鱼":"晒网");
}
38.假设当前市场价一只鸡 10 元,一只鸭 12 元 5 角。请写一个函数 ShowPrice,输入参数分别为鸡和鸭的个数(非负整型),功能为显示出总 价钱,精确到分。例如调用 ShowPrice(5,10)后输出 175.00。请注意程 序的可读性和易于维护性。 static void ShowPrice(int num_chicken, int num_duck) {
float totalPrice = 0.00f;
float price_chicken = 10f;
float price_duck = 12.5f;
totalPrice = num_chicken * price_chicken + num_duck * price_duck;
Console.WriteLine("总价钱为:{0:0.00}", totalPrice);
}
39.请写一个函数,用于返回 n!(阶乘)结果末尾连续 0 的个数,如 GetZeroCount(5)返回 1,因为 5! = 120,末尾连续 1 个 0 static void Main(string[] args) {
int fac = Factorial(5);
Console.WriteLine(CountZero(fac));
}
public static int Factorial(int n) {
if (n == 1) {
return 1;
} else {
return n * jiecheng(n - 1);
}
}
//求连续的 0 的个数
public static int CountZero(int num) {
int result = 0; // 最后的结果
String numStr = num.ToString();
for (int i = numStr.Length - 1; i >= 0; i--) {
if (numStr[i] == '0') {
result ++;
} else {
break;
}
}
return result;
}
二、 Unity 编辑器基础 40.请描述游戏动画有几种,以及其原理。 主要有关节动画、单一网格模型动画(关键帧动画)、骨骼动画。关节动画把角色分成若干独立部分, 一个部分对应一个网格模型,部分的动画连接成一个整体的动画,角色比较灵活 Quake2 中使用了这 种动画。单一网络模型动画由一个完整的网格模型构成, 在动画序列的关键帧里记录各个顶点的原位 置及其改变量,然后插值运算实现动画效果,角色动画较真实。骨骼动画,广泛应用的动画方式,集 成了以上两个方式的优点,骨骼按角色特点组成一定的层次结构,由关节相连,可做相对运动,皮肤 作为单一网格蒙在骨骼之外,决定角色的外观。皮肤网格每一个顶点都会受到骨骼的影响,从而实现 完美的动画。(骨骼动画是由关节动画发展而来的,如今基本都使用骨骼动画来实现角色动画)
41.物体发生碰撞的必要条件 物体 A 必须带有(collider+rigidbody)或者 CharacterController,另一个物体也必须至少带有 collider
42.GUI 与 UGUI 的优点和缺点 GUI 不方便控制,UGUI 所见即所得,方便控制。GUI 使用在生命周期函数 OnGUI 中使用,脚本来书写 控制。UGUI 使用 Canvas 画布和事件系统。UGUI 适应屏幕上比 GUI 简单。
43.一个场景放置多个 carmera 并同时处于活动状态,会发生什么 实际看到的画面由多个 camera 的画面组成,由 depth、Clear Flag、Culling Mask 都会影响最终合成效果。
44.使用过哪些第三方插件? 一、界面制作 推荐:NGUI
二、2D 游戏制作 推荐:2D Toolkit //[ˈtu:lkɪt] 工具包,工具箱
三、可视化编程 推荐:PlayMaker
四、插值插件 推荐:iTween,HOTween
五、路径搜寻 推荐:Simple Path
六、美术及动画制作 推荐:RageSpline,Smooth Moves
七、画面增强 推荐:Bitmap2Material,Strumpy Shader Editor
八、摄像机管理 推荐:Security Camera
九、资源包 推荐:Nature Pack
十、造路插件 EasyRoads3D
45.U3D 中用于记录节点空间几何信息的组件名称,及其父类名称 Transform 父类是 Component
46.为何大家都在移动设备上寻求 U3D 原生 GUI 的替代方案 不美观,OnGUI 很耗费时间,使用不方便 ,DrawCall
47.请简述如何在不同分辨率下保持 UI 的一致性 NGUI 很好的解决了这一点,屏幕分辨率的自适应性,原理就是计算出屏幕的宽高比跟原来的预设的屏 幕分辨率求出一个对比值,然后修改摄像机的 size。
48.为什么 dynamic font 在 unicode 环境下优于 static font Unicode 是国际组织制定的可以容纳世界上所有文字和符号的字符编码方案。使用动态字体时,Unity 将不会预先生成一个与所有字体的字符纹理。当需要支持亚洲语言或者较大的字体的时候,若使用正 常纹理,则字体的纹理将非常大。
49.Render 的作用?描述 MeshRender 和 SkinnedMeshRender 的关系与不 同 Mesh 就是指模型的网格(同名组件是用于调整网格属性的),MeshFilter 一般是用于获得模型网格的 组件,而 MeshRender 是用于把网格渲染出来的组件
50. 简述 SkinnedMesh 的实现原理 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 空间变换到骨骼空间。
51.Prefab 的作用?如何在移动环境的设备下恰当地使用它? 在游戏运行时实例化,prefab 相当于一个模版,对你已有的素材、脚本、参数做一个默认配置,以便 于以后修改,同时 prefab 打包的内容简化了导出的操作,便于团队的交流。
52.如何销毁一个 UnityEngine.Object 及其子类 Destory
53.为什么 Unity3D 中会发生在组件上出现数据丢失的情况? 组件上绑定的对象被删除了
54.MeshCollider 和其他 Collider 的一个主要不同点? Meshcollider 是基于顶点的。建议还是用 boxcollider,boxcollider 本身是基于算法,没有面的概念。
55.当一个细小的高速物体撞向另一个较大的物体时,会出现什么情况?如何 避免? 穿透(碰撞检测失败)(碰撞体变大,FixedUpdate, 代码限制)
56.MeshRender 中 material 和 sharedmaterial 的区别? 修改 sharedMaterial 将改变所有物体使用这个材质的外观,并且也改变储存在工程里的材质设置。 不推荐修改由 sharedMaterial 返回的材质。如果你想修改渲染器的材质,使用 material 替代。
57.用 u3d 实现 2d 游戏,有几种方式? 1.利用引擎自带的 GUI 和 2D 系统
2.把摄像机设为 Orthographic,用面片作为 2d 元素
3.利用第三方插件:NGUI、2dToolkit
58.u3d 中碰撞器和触发器的区别? collider 碰撞器会有碰撞的效果,IsTrigger = false, 可以调用 OnCollisionEnter/Stay/Exit 函数 trigger 触发器 没有碰撞效果, isTrigger = true,可以调用 OnTriggerEnter/stay/exit 函数
59.CharacterController 和 Rigidbody 的区别 Rigidbody 具有完全真实物理的特性, 而 CharacterController 可以说是受限的 Rigidbody,具有一定的物 理效果但不是完全真实的。
60.什么叫做链条关节 Hinge Joint ,他可以模拟两个物体间用一根链条连接在一起的情况,能保持两个物体在一个固定距离 内部相互移动而不产生作用力,但是达到固定距离后就会产生拉力。 (简单说就是弹簧)
61.unity3d 提供了几种光源,分别是什么 平行光:Directional Light
聚光灯:Spot Light
点光源:Point Light
区域光源:Area Light(只用于烘培)
62.u3d 下如何安全的在不同工程迁移 asset 数据 方法 1,可以把 assets 目录和 Library 目录一起迁移,
方法 2,导出包
方法 3,用 unity 带的 assets server 功能
63. Unity3d 中的碰撞器和触发器的区别? 触发器只是碰撞器身上的一个属性,碰撞器是触发器的载体。
碰撞器有碰撞的效果,IsTrigger=false,可以调用 OnCollisionEnter/Stay/Exit 函数;
触发器没有碰撞效果,IsTrigger=true,可以调用 OnTriggerEnter/Stay/Exit 函数。
a.如果不想让碰撞检测影响物体移动但是又想检测到碰撞这时用到触发器(Trigger)
b.触发器用来检测一个物件是否经过空间中的某个区域
64.动画层(Animation Layers)的作用是什么? 动画层作为一个具有层级动画编辑概念的工具, 可以用来制作和处理任何类型的动画
65.Material 和 Physic Material 区别? PhysicMaterial 物理材质:物理材质描述,如何处理物体碰撞(摩擦,弹性)。Material 材质(材质类) 为了获得一个对象使用的材质,可以使用 Renderer.materia 属性
66.什么是导航网格(NavMesh)? 一种用于实现自动寻路的网格
67.请简述 NGUI 中 Panel 和 Anchor 的作用 Anchor 包含 UIAnchor 脚本。 UIAnchor 的功能是把对象锚定在屏幕的边缘 (左上, 左中,左下,上, 中,下,右上,右中,右下),或缩放物体使其匹配屏幕的尺寸 Panel 对象有 UIPanel 脚本,UIPanel 是一个容器,它将包含所有 UI 小部件,并负责将所包含的部件组 合优化,以减少绘制命令的调用。
68.Unity 摄像机有几种工作方式,分别是什么? perspective 透视摄像机和 orthographic 正交摄像机
69.LayerMask.NameToLayer()这个方法有什么作用? LayerMask 的使用是按位操作的,LayerMask.NameToLayer(“Players”) 返回该 Layer 的编号。
70.NGUI 与 UGUI 的优点和缺点 1) NGUI 还保留着图集,需要进行图集的维护。而 UGUI 没有图集的概念,可以充分利用资源,避免重 复资源。
2) UGUI 出现了锚点的概念,更方便屏幕自适应。
3) NGUI 支持图文混排,UGUI 暂未发现支持此功能。
4) UGUI 没有 UIWrap 来循环 scrollview 内容。
5) UGUI 暂时没有集成 Tween 组件。
71.是否熟悉 UGUI 熟悉,之前在一些项目用 UGUI 做过界面,和 NGUI 很相似。
72.会写插件么? 了解过,但在公司这块用的比较少,没怎么写过,不过我能很快学会。
73.UGUI 和 NGUI 的区别?为什么不使用 NGUI? 1、uGUI 的 Canvas 有世界坐标和屏幕坐标,NGUI 有 2D 和 3D 区别。
2、uGUI 的 Image 可以使用 material。
3、UGUI 通过 Mask 来裁剪,而 NGUI 通过 Panel 的 Clip
4、NGUI 的渲染前后顺序是通过 Widget 的 Depth,而 UGUI 渲染顺序根据 Hierarchy 的顺序,越下面渲 染在顶层。
1) 、UGUI 不需要绑定 Colliders,UI 可以自动拦截事件。
2) 、UGUI 的 Anchor 是相对父对象,没有提供高级选项,个人感觉 uGUI 的 Anchor 操作起来比 NGUI 更方便
7、UGUI 没有 Atlas 一说,使用 Sprite Packer。
8、UGUI 的 Navgation 在 Scene 中能可视化。
9、UGUI 的事件需要实现事件系统的接口,但写起来也算简单。
10、NGUI 功能更丰富一些 之所以不用 NGUI 是因为 UGUI 是 Unity 官方推出的,慢慢会成为制作 UI 的主要工具,配套的插件也越 来越多,但是具体使用 NGUI 还是 UGUI 还要看公司这边,因为这两个我都用过一段时间。
74.UI 用的是 NGUI 还是 UGUI? 两个都用过。之前用的 NGUI 后来用了 UGUI。
75.Unity3d 中 static batching 和 dynamic batching 各有什么用? Dynamic Batching 不需要任何操作,只要共享材质(即使是不同的 Mesh 模型也可以),就会自动被合并。 可以自由移动旋转。但有以下使用要求:
(1) 模型文件共计点数不超过 900。(重复使用同一个 Mesh 不计)
(2) 单个物体可以不超过 300 点,Shader 可以有法线 UV。 但如果 Shader 使用了 UV0 UV1 两套 UV,或者 Tangent 切线的话,单个物体只能不超过 180 点
(3)游戏对象使用相同模型和材质时,只有相同缩放(即 xyz 等比缩放,浮点尾数可以有细微差)的会被合
并。如 (1,1,1)与(1,1,1) (2,2,2)与(2,2,2) (0.5,0.5,0.5)与 (0.5,0.5,0.5) (2,2,2)与(2,2,2.0001)
(4)场景烘焙:烘焙后同材质将不会被烘焙。lightmap 有隐藏的材质参数:offset/scale, 所以使用
lightmap 的物体不会被合并
(5)Shader 不能使用多 Pass:多 Pass 的 Shader 会破坏 Dynamic Batching Static Batching
原理:运行游戏后将一组游戏对象的多个模型会被动态合并为 1 个。这组游戏对象所有使用同一材质 的在一个 DrawCall 来完成。这些游戏对象运行后无法移动缩放旋转。但是 Drawcall 一定是最大化合并 的,并且不受动态合并的诸多限制(见下文详述)。
注意:即使物体都使用了同样的模型,在 batch 后每一个物体都会创建一份模型对应的 geometry,在新 的 Combined Mesh 里。所以过多的 batch 会增加内存占用。例如场景里的树群就不适合 Static Batch, 而适合动态合并。实现方法:
(1)MeshRenderer 勾选 Batching Static: 勾了即可
(2)代码中使用 UnityEngine.StaticBatchingUtility 实现(可以在任何平台调用):
1)将所有要合并的静态物体(不须勾 Batching Static)放入统一一个 root
2)StaticBatchingUtility.Combine(root); 之后就合并好了!
区别:勾选 Batching Static:完全自动合并,在 MeshFilter 里显示的是 Combined Mesh(root:scene)。合并 后不能移动
StaticBatchingUtility:合并到一个游戏对象下。合并后可以移动父节点游戏对象"
76.Unity3d 中 Awake 和 Start 谁先执行,update 和 fixedUpdate 有什么区 别? Awake 先执行。Update 是在每次渲染新的一帧的时候才会调用,FixedUpdate,是在固定的时间间隔执 行,不受游戏帧率(fps)的影响 ,FixedUpdate 的时间间隔可以在项目设置中更改,Edit->Project Setting->time 找到 Fixed timestep。就可以修改了
77.Unity 引擎中以下对 Mesh Renderer 组件描述正确的是哪一项? C A.Mesh Renderer 组件决定了场景中游戏对象的位置,旋转和缩放
B.为场景中的某一游戏对象增添物理的特性,需要为该游戏对象添加 Mesh Renderer 组件
C.Mesh Renderer 组件从 Mesh Filter 组件中获得网格信息,病根据物体的 Transform 组件所定义的位 置进行渲染
D.Mesh Renderer 是从网格资源中获取网格信息的组件
78.哪种实时光源是 Unity 中没有的?D A:点光源
B:方向光
C:聚光灯
D:日光灯
79.如何在 Unity 中创建地形系统?A A:Terrain->Create Terrain
B:Component->Create Terrain
C:Asset->Create Terrain
D:Windows->Create Terrain
80.以下哪种操作步骤可以在场景中添加“Wind Zone”?B A:Terrain -> Wind Zone
B:GameObject -> Create Other -> Wind Zone
C:Component -> Physics -> Wind Zone
D:Assets -> Create -> Wind Zone
81.在 Unity 编辑器中创建一个 Directional Light,以下步骤正确的是? B A:Edit -> Rendering Setting -> Directional Light
B:GameObject -> Create Other -> Directional Light
C:Component -> Rendering -> Directional Light
D:Assets -> Directional Light
82.下列哪一项不属于 Camera 中的“Clear Flags”?D A:Skybox
B:Solid Color
C:Depth Only
D:Background
83.以下哪种脚本语言是 Unity 编辑器所不支持的? D A:JavaScript
B:C#
C:Boo
D:Perl
84.对于 Prefab,以下说法错误的是? D A:Prefab 资源可以在项目中多次重复使用
B:由 Prefab 实例出的 GameObject,其在 Hierarchy 视图中表现为蓝色
C:Prefab 上的组件信息一经改变,其实例出的 GameObject 也会自动改变
D:实例出的 GameObject 上的组件信息一经改变,其对应的 Prefab 也会自动改变
85.下面哪种做法可以打开 Unity 的 Asset Store? A A:Windows -> Asset Store
B:Edit -> Asset Store
C:File -> Asset Store
D:Assets -> Asset Store
86.在哪个面板中可以修改物体的空间属性,如位置、朝向、大小等?B A:Project
B:Inspector
C:Hierarchy
D:Toolbar
87.如何为一个 Asset 资源设定一个 Label,从而能够方便准确的搜索到? D A:在 Project 窗口中选中一个 Asset,右键->Create->Label
B:在 Project 窗口中选中一个 Asset,右键->Add Label
C:在 Project 窗口中选中一个 Asset,在 Inspector 窗口中点击添加 Label 的图标
D:在 Project 窗口中选中一个 Asset,在 Inspector 窗口中点击按钮“Add Label”
88.Mecanim 系统中,Body Mask 的作用是?D A:指定身体的某一部分是否参与骨骼动画
B:指定身体的某一部分是否参与物理模拟
C:指定身体的某一部分是否可以输出骨骼信息
D:指定身体的某一部分是否参与渲染
89.以下哪种操作步骤可以打开 Unity 编辑器的 Lightmapping 视图? C A:File --> Lightmapping
B:Assets --> Lightmapping
C:Windows --> Lightmapping
D:Component --> Lightmapping
90.下列关于光照贴图,说法错误的是? C A:使用光照贴图比使用实时光源渲染要快
B:可以降低游戏内存消耗
C:可以增加场景真实感
D:多个物体可以使用同一张光照贴图
91.如何为物体添加光照贴图所使用的 UV? B A:不用添加,任何时候都会自动生成
B:更改物体导入设置,勾选“Generate Lightmap UVs”C:更改物体导入设置,勾选“Swap UVs”
D:更改物体导入设置,在 UVs 选项中选择“Use Lightmaps”
92.在哪个模块下可以修改 Render Path? A A:Camera
B:Light
C:Render Settings
D:Project Settings->Quality
93.以下哪项技术不是目前 Unity 所支持的 Occlusion Culling 技术? D A:PVS only
B:PVS and dynamic objects
C:Automatic Portal Generation
D:Dynamic Only
94.关于 Vector3 的 API,以下说法正确的是? C A:Vector3.normalize 可以获取一个三维向量的法线向量;
B:Vector3.magnitude 可以获取一个三维向量的长度;
C:Vector3.forward 与 Vector3(0,0,1)是一样的意思;
D:Vector3.Dot(向量 A,向量 B)是用来计算向量 A 与向量 B 的叉积
95.下列那些选项不是网格层属性的固有选项? A A:Default
B:Walkable
C:Not Walkable
D:Jump
96.什么是导航网格(NavMesh)? D A:一种用于描述相机轨迹的网格
B:一种被优化过的物体网格
C:一种用于物理碰撞的网格
D:一种用于实现自动寻路的网格
97.以下哪一个选项不属于 Unity 引擎所支持的视频格式文件 D A.后缀名为 mov 的文件
B.后缀名为 mpg 的文件
C.后缀名为 avi 的文件
D. 后缀名为 swf 的文件
98.Unity 引擎使用的是左手坐标系还是右手坐标系? A A.左手坐标系
B.右手坐标系
C.可以通过 Project Setting 切换左右手坐标系
D.可以通过 Reference 切换左右手坐标系
99.以下哪组摄像机中 Normalized View Port Rect 的数值设置可以使得摄像 机显示的画面位于 1280*720 分辨率的屏幕画面的右上角 D A. x = 640, Y = -360 , W = 360,H = 360
B. x =640, Y = -360 , W = 360,H = 360
C. x =0.5, Y = 0 , W = 0.5,H = 0.5
D0. x =0.5, Y = 0.5 , W = 0.5,H = 0.5
100. 以下哪个组件是任何 GameObject 必备的组件 B A.Mesh Renderer
B.Trtansform
C.Game Object
D.Main camera
101. 在 Unity 编辑器中,停止对 Game 视图进行预览播放的快捷键操作是 以下哪一项 A A.CTRL/CMD + P
B.CTRL/CMD + Shift +P
C.CTRL/CMD + Alt +P
D.CTRL/CMD + S
102. 在 Unity 引擎中,Depth 属性值最大的摄像机会比 Depth 属性值小的 摄像机更晚绘制么? A A.是
B.否
103. 下列选项中有关 Animator 的说法错误的是 D A.Animasstor 是 Unity 引擎内置组件
B.任何一个具有动画状态机功能的 GameObject 都需要一个 Animator 组件
C.它主要用于角色行为的设置,包括 StateMachines,混合 Blend trees 以及通过脚本控制的事件
D.Animator 同 Animation 组件的用法是相同的
104. 下列哪个视图主要用于显示和编辑所选游戏对象或资源的相关属性 C A.Scene
B.Project
C.Inspector
D.Hierarchy
105. 简述 Prefab 的使用?Editor 下动态创建 Prefab 的方式 "u3d 里动态 创建对象,需要使用 prefab 而创建的时候 MonoBehaviour.Instantiate (GameObject orignal) 需要一个作为原型的对象。三种方式获得prefab 对象。 方式一:使用脚本的 public 字段直接在 Project 视图里找到做好的 prefab,将其拖拽到指定脚本的指定 public GameObject 字段。
方式二:Resource 类
1、在 Assets 目录下的任意位置创建一个名为 resources 的文件夹,将做好的 prefab 放到这个文件夹下, path 形式如下: Assets/..../resources/prefabName.prefab
2、在代码里使用 Resource.Load 或 LoadAll 函数,获得原型对象。指定 prefab 时不需要指定扩展名 (.prefab),形式如下:GameObject prototype = Resource.Load(“prefabName”) as GameObject; 可有任 意数量的 resources 文件夹,怀疑是 Resource 类初始化的时候会搜集所有 resources 文件夹里的文件名。
方式三:加载到场景
一般我们制作 Perfab 的时候,都是在 Hierarchy 视图里创建 GameObject,然后再搭建 Prefab。事后根 据需要删除这个原始的 GameObject。因此我们可以保留这个 GameObject,然后在场景加载后 Find 这 个对象(代码方式),或者使用脚本 public 字段(编辑器方式)
106. NGUI 的自适应性是?如果此时屏幕比例变化,屏幕出现黑边怎么办? (注:改变 NGUI 和 UGUI 的 Fixed size with Screen 不可行) NGUI 根目录的 UIRoot 组件自带了根据高度自适应分辨率的功能。
Scaling Style 属性可选择三种不同的缩放策略。
PixelPerfect 完美像素:直接显示设定好的像素。当屏幕高度低于 minimum Height 时按比例缩小,当屏 幕高度大于 maximum Height 时按比例扩大。
FixedSize 按比例缩放:在设定好 的基础上,直接按比例缩放。
FixedSizeOnMobiles 合体版,android 和 ios 为 FixedSize 方式,其它按照 PixelPerfect 方式。
三、 Unity 脚本基础 107. Unity3D 中的协程(coroutine)和 C#线程之间的区别是什么? 多线程程序同时运行多个线程 ,而在任一指定时刻只有一个协程在运行,并且这个正在运行的协同程 序只在必要时才被挂起。除主线程之外的线程无法访问 Unity3D 的对象、组件、方法。 Unity3d 没有多线程的概念,不过 unity 也给我们提供了 StartCoroutine(协同程序)和 LoadLevelAsync(异步加载关卡)后台加载场景的方法。 StartCoroutine 为什么叫协同程序呢,所谓协同,就是当你在 StartCoroutine 的函数体里处理一段代码时,利用 yield 语句等待执行结果,这期间不影响主程序的继 续执行,可以协同工作。而 LoadLevelAsync 则允许你在后台加载新资源和场景,所以再利用协同,你 就可以前台用 loading 条或动画提示玩家游戏未卡死,同时后台协同处理加载的事宜
108. 简述 Unity3D 支持的作为脚本的语言的名称 Unity 的脚本语言基于 Mono 的.Net 平台上运行,可以使用.NET 库,这也为 XML、数据库、正则表达式 等问题提供了很好的解决方案。 Unity 里的脚本都会经过编译,他们的运行速度也很快。这三种语言实际上的功能和运行速度是一样的, 区别主要体现在语言特性上。 JavaScript:和网页中常用的 JavaScript 不一样,它编译后的运行速度很快,语法方面也会有不少区别。 C# Boo:可以看做是 Python 语言的变种,又糅合了 Ruby 和 C#的特性,它是静态类型语言
109. Unity3D 是否支持写成多线程程序?如果支持的话需要注意什么? 仅能从主线程中访问 Unity3D 的组件,对象和 Unity3D 系统调用
110. 支持:如果同时你要处理很多事情或者与 Unity 的对象互动小可以用 thread,否则使用 coroutine。 注意:C#中有 lock 这个关键字,以确保只有一个线程可以在特定时间内访问特定的对象
111. OnEnable、Awake、Start 运行时的发生顺序?哪些可能在同一个对象周 期中反复的发生? Awake -》OnEnable-》Start OnEnable 在同一周期中可以反复地发生
112. 、请简述 OnBecameVisible 及 OnBecameInvisible 的发生时机,以及这 一对回调函数的意义? 当物体是否可见切换之时。可以用于只需要在物体可见时才进行的计算。
113. Unity3D 如何获知场景中需要加载的数据? Resource.Load
AssetBundle.Load
114. 物体发生碰撞时,有几个阶段,分别对应的函数 三个阶段,OnCollisionEnter/ /Exit 函数
115. u3d 中,几种施加力的方式,描述出来 rigidbody.AddForce/AddForceAtPosition,都是 rigidbody 的成员函数
116. 物体自旋转使用的函数叫什么 transform.Rotate
117. 物体绕某点旋转使用函数叫什么 transform.RotateAround
118. u3d 提供了一个用于保存读取数据的类,(playerPrefs),请列出保存读取 整形数据的函数 PlayerPrefs.SetInt 与 PlayerPrefs.GetInt
119. unity3d 从唤醒到销毁有一段生命周期,请列出系统自己调用的几个重要 方法。 Awake –>OnEnable –> Start –> Update –> FixedUpdate –> LateUpdate –>OnGUI –> Reset –>
OnDisable –> OnDestroy
120. 物理更新一般在哪个系统函数里? FixedUpdate,每固定帧绘制时执行一次,和 update 不同的是 FixedUpdate 是渲染帧执行,如果你的渲 染效率低下的时候 FixedUpdate 调用次数就会跟着下降。FixedUpdate 比较适用于物理引擎的计算,因 为是跟每帧渲染有关。Update 就比较适合做控制。
121. 移动相机动作在哪个函数里,为什么在这个函数里。 LateUpdate,,是在所有 update 结束后才调,比较适合用于命令脚本的执行。官网上例子是摄像机的跟 随,都是在所有 update 操作完才跟进摄像机,不然就有可能出现摄像机已经推进了,但是视角里还未 有角色的空帧出现。
122. 为什么 u3d 会出现组件上数据丢失的情况 一般是组件上绑定的物体对象被删除了
123. 什么是协同程序? 在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行。换句话说,开启协程就是开启一 个线程。可以用来控制运动、序列以及对象的行为。
124. 反向旋转动画的方法是什么? 反转动画,讲动画的速度调到-1,碰撞时,被碰撞物体与碰撞物体有 collider 组件,碰撞物体有刚体组 件,或角色碰撞得包含角色组件 OR 改变 animation.speed
125. 用代码实现第三角色控制器 public class Player : MonoBehaviour {
public Transform _cameraTrans;
private Vector3 _cameraOffset;
void Awake() {
_cameraOffset = transform.position - _cameraTrans.position;
}
void Update() {
_cameraTrans.position = transform.position - _cameraOffset;
}
}
126. 实现吊机吊物体的功能 吊机吊物体需要节点挂接和坐标系转换
127. 获取、增加、删除组件的命令分别是什么 获取:GetComponent
增加:AddComponent
删除:Destroy
128. Animation.CrossFade 命令作用是:C A. 动画放大 B.动画转换 C.动画的淡入为其他动画
129. Application.loadLevel 命令为:A A. 加载关卡 B.异步加载关卡 C.加载动作
130. 调试记录到控制台的命令是什么? Debug.Log();
131. 编辑器类存放路径是什么? 工程目录下的 Assets/Editor 文件夹下。
132. 使用原生 GUI 创建一个可以拖动的窗口命令是什么? GUI.DragWindow();
133. localPosition 与 Position 的使用区别? localPosition:自身位置,相对于父级的变换的位置。 Position:在世界坐标 transform 的位置
134. 含义 Mathf.Round, Mathf.Clamp, Mathf.Lerp Mathf.Round 四舍五入
Mathf.Clamp 限制
Mathf.Lerp 插值
135. 写一个计时器工具,从整点开始计时,格式为:00:00:00 private float timer = 0f;
private int h = 0;
private int m = 0;
private int s = 0;
private string timeStr = string.Empty;
void Update () {
timer += Time.deltaTime;
if (timer >= 1f) {s++; timer = 0;}
if (s >= 60) {m++;s = 0;}
if (m >= 60) {h++;m = 0;}
if (h >= 99) {h = 0;}
}
void OnGUI(){
timeStr = string.Format ("{0:D2}:{1:D2}:{2:D2}", h, m, s);
GUI.Label (new Rect (10, 10, 100, 200), timeStr);
}
136. 写出 Animation 的五个方法 AddClip 添加剪辑、Blend 混合、Play 播放、Stop 停止、Sample 采样
137. 用鼠标实现在场景中拖动物体,用鼠标滚轮实现缩放(用一个 Cube 即可)。 在场景中添加一个 Plan,Camera,Directional Light,Cube。添加两个脚本 scrollerScirpt(挂在 Camera), CubeDragScript(挂在 Cube 上)。
1.鼠标滚轮实现缩放:将摄像机的镜头拉近或者拉远,调整摄像机的视角就可以实现,主要实现代码
如下:
void Update () {
//鼠标滚轮的效果
if (Input.GetAxis("Mouse ScrollWheel") < 0) {
if (Camera.main.fieldOfView <= 100)
Camera.main.fieldOfView += 2;
if (Camera.main.orthographicSize <= 20)
Camera.main.orthographicSize += 0.5F;
}
//Zoom in
if (Input.GetAxis("Mouse ScrollWheel") > 0) {
if (Camera.main.fieldOfView > 2)
Camera.main.fieldOfView -= 2;
if (Camera.main.orthographicSize >= 1)
Camera.main.orthographicSize -= 0.5F;
}
}
2.鼠标实现在场景中拖动物体:
解决思路就是将世界坐标转换成屏幕坐标,然后计算物体与鼠标之间移动量,循环鼠标被按下操 作,得到鼠标的当前位置,加上计算好的移动量,将新的坐标赋值给物理就行了。主要是开启一个协 同程序(Corountine)来处理。
主要代码如下:
// Use this for initialization
void Start () {
StartCoroutine(OnMouseDown());
}
IEnumerator OnMouseDown() {
//将物体由世界坐标系转换为屏幕坐标系
Vector3 screenSpace = Camera.main.WorldToScreenPoint(transform.position);
//完成两个步骤 1.由于鼠标的坐标系是 2 维,需要转换成 3 维的世界坐标系
//2.只有 3 维坐标情况下才能来计算鼠标位置与物理的距离,offset 即是距离
//将鼠标屏幕坐标转为三维坐标,再算出物体位置与鼠标之间的距离
Vector3 offset = transform.position
Camera.main.ScreenToWorldPoint(new
Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z));
while (Input.GetMouseButton(0)) {
//得到现在鼠标的 2 维坐标系位置
Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenSpace.z);
//将当前鼠标的 2 维位置转换成 3 维位置,再加上鼠标的移动量
Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset; //curPosition 就是物体应该的移动向量赋给 transform 的 position 属性
transform.position = curPosition;
yield return new WaitForFixedUpdate(); //这个很重要,循环执行
}
}
138. NGUI Button 怎样接受用户点击并调用函数,具体方法名称是什么 1、主要是在 UICamera 脚本中用射线判断点击的物体并通过 SendMessage 调用 OnClick() OnPress()等函 数,可以说 NGUI 的按钮是通过发消息这个方式调用的。具体方法名称是 OnClick()
2、void Awake () {
//获取需要监听的按钮对象
GameObject button = GameObject.Find("UI Root/Button3");
//设置这个按钮的监听,指向本类的 ButtonClick 方法中。
UIEventListener.Get(button).onClick = OnButton3Click;
}
private void OnButton3Click(GameObject button) {
Debug.Log("我是按钮 3 被点击了");
}
139. <愤怒的小鸟>给予初速度以后,怎么让小鸟受到重力和空气阻力的影响而绘 制抛物线轨迹,说出具体的计算方法. Vector3 v 代表初速度 v'代表现在的速度, 假设小鸟是沿的 z 轴也就是 transform.forward 方向运动 的质量为 1,那么 v'=v-new Vector3(0,g*t,f*t),transform.Translate(v')做的就是抛物线运动(g 为重力加 速度不要用现实中的需要自己调试,f 为阻力也要自己调试设置,t 为时间)
140. 当游戏中需要频繁创建一个物体时,我们需要怎样做能够节省内存? 1、使用预制物体对象 Prefab
2、使用对象池技术,不使用时关闭,使用时打开
141. 碰撞检测需要物体具备什么属性? 能检测碰撞发生的方式有两种,一种是利用碰撞器,另一种则是利用触发器 【Physics.OverlapSphere 相交球检测碰撞,碰撞检测需要包围盒】
142. Vector3.forward 与 Vector3(0,0,1)是一样的意思对吗? 对
143. 下哪个函数在游戏进入新场景后会被马上调用? MonoBehaviour.OnLevelWasLoaded
144. itween 插件的作用是什么,itween 作用于世界坐标还是局部坐标,请列 举出 3 个其常用方法? iTween 是一个动画库,作者创建它的目的就是最小的投入实现最大的产出。让你做开发更轻松,用它 可以轻松实现各种动画,晃动,旋转,移动,褪色,上色,控制音频等等“方法:
a、MoveTo 物体移动;
b、ColorTo:随着时间改变对象的颜色组;
c、LookTo:随时间旋转物体让其脸部朝向所提供的 Vector3 或 Transform 位置;
145. U3D 中用于记录节点空间几何信息的组件名称,及其父类名称 Transform 父类是 Component
146. NGUI:把子控件放在父控件里面,如何上下边距都是 10。 给子控件设置上下两个锚点为 10
147. 如何使子控件居中,如果使用 UGUI 怎么实现 设置子控件锚点为中心
148. 去掉敏感字的程序(手写程序) String s = "你是坏蛋";
s.Replace("坏蛋", "**");
149. unity3D 从唤醒到销毁有一段生命周期,列出系统自己调用的重要方法。 Awake ()
OnEnable ()
Start()
FixedUpdate()
OnTriggerXXX(Collider other)OnCollisionXXX (Collision collisionInfo)
Update()
LateUpdate ()
OnGUI()
OnDisable ()
OnDestroy ()
150. Unity3d 中 resources 目录一般用来放些什么,打包的时候会有什么影响? resource 一般用来放置一些需要动态加载的资源,打包程序的时候会将 Resource 目录下的全部文件都 加密压缩打进包内,这样再想使用 assetbundle 方式打小包的话就不行了
151. 空间内一物体绕球面固定点(0、1、2)按照固定速度 speed 环绕运动。 public float Speed = 1;
void Update () {
transform.RotateAround (new Vector3(0,1,2),Vector3.up,Speed);
}
152. 以下关于 WWW.LoadFromCacheOrDownload 描述正确的是: C A.可被用于将 Text Assets 自动缓存到本地磁盘
B.可被用于将 Resource 自动缓存到本地磁盘
C.可被用于将 Assets Bundles 自动缓存到本地磁盘
D.可被用于将任意的 Unity 资源文件自动缓存到本地磁盘
153. 以下哪个函数在游戏进入新场景后会被马上调用? C A:MonoBehaviour.OnSceneWasLoaded
B:MonoBehaviour.OnSceneEnter
C:MonoBehaviour.OnLevelWasLoaded
D:MonoBehaviour.OnLevelEnter
154. 关于 MonoBehavior.LateUpdate 函数描述错误的是: B A.当 MonoBehavior 类型应用后,每帧调用一次
B.常被用于处理 RigidBody 的更新
C.在所有 Update 函数执行后才能被调用
D.常被用于实现跟随相机效果,且目标物体的位置已经在 Update 函数中被更新
155. 某个 GameObject 有一个名为 MyScript 的脚本,该脚本中有一个名为 DoSomething 的函数,则如何在该 GameObject 的另一个脚本中国调用该 函数? A A.GetComponent<MyScript>().DoSomething()
B.GetComponent<Script>("MyScript").DoSomething()
C.GetComponent< MyScript >().Call("DoSomething")
D.GetComponent<Script>("MyScript"). Call("DoSomething")
156. 启用 MipMaps 对内存的影响是? A A.增加约 33%的内存
B.减少约 33%的内存
C.增加约 25%的内存
D.减少约 25%的内存
157. 以下关于 MonoBehaviour.OnGUI()的描述的是: D A.如果 MonoBehaviour 没有被启用,则 OnGUI 函数不会被调用
B.用于绘制和处理 GUI events
C.每帧可能会被绘制多次,每次对应于一个 GUI event
D.每帧被调用一次
158. 采用 Input.mousePosition 来获取鼠标在屏幕上的位置,以下表述正确的 是: B A.左上角为原点(0, 0),右下角为(Screen.Width, Screen.Height)
B.左下角为原点(0, 0),右上角为(Screen.Height, Screen.Width)
C.左下角为原点(0, 0),右上角为(Screen.Width, Screen.Height)
D.左上角为原点(0, 0),右下角为(Screen.Height, Screen.Height)
159. 正确排列出下面 Unity 脚本自带的函数执行顺序 Start,Awake,Update, OnUpdate,OnEnable,FixedUpdate,OnGUI,LateUpdate、OnDisable、 OnDestory Awake-->OnEnable-->Start-->Update-->FixedUpdate-->LateUpdate-->OnGUI-->OnDisable -->OnDestory
160. Unity 中销毁 GameObject 的方式,简述 Destroy 和 DestroyImmediate 的区别 Destroy 销毁场景中的物体,但是内存中它还是存在的,只有当内存不够时,机制才会将它销毁并释放 内存。而 DestroyImmediate 会立即将对象销毁,并且将内存释放。
161. Unity 中如何派发事件(消息) 在脚本里的 Update 函数里调用 EventDispatcher.Instance().OnTick();就可以了
162. ScriptObject 的作用和使用方式 ScriptObject 类型经常使用于存储一些 Unity 本身不可以打包的一些 object,比如字符串,一些类对象, 用这个类型的子类型可以用 BuildPipeline 打包成 assetbundle 包共后续使用,非常方便。
163. 如何检测物体是否被其他对象遮挡 使用射线进行检测
164. 写一个角色控制器,鼠标控制屏幕晃动,鼠标控制开枪。 public class Player : MonoBehaviour {
public GameObject _prefabBullet;
private float _angleSpeed = 120f;
void Update() {
float eularY = Input.GetAxis("Mouse X") * _angleSpeed * Time.deltaTime;
transform.Rotate(new Vector3(0, eularY, 0));
if (Input.GetMouseButtonDown(0)) {
Instantiate(_prefabBullet, transform.position, transform.rotation);
}
}
}
165. 敌人 AI,有各种状态,实现各种状态之间的切换。 通过状态机来实现各种状态之间的切换
166. 1.写一个角色控制器,鼠标控制屏幕晃动,鼠标控制开枪。 2.敌人 AI,有各种状态,实现各种状态之间的切换。 3.敌人会和主角对抗,敌人被打到之后,会闪一次红色,然后红色比例提升 10%,10 次攻击之后,成红色。 4.敌人会自动攻击主角,主角也会有颜色变化。 5.敌人会在范围内巡逻。 6.UI,左边显示 8 个 AI 的被攻击次数,右边显示 AI 的攻击次数排序。 public class Player : MonoBehaviour {
public Camera _camera;
public GameObject _prefabBullet;
private float _angleSpeed = 120f;
//生命值
private int _life = 10;
//玩家的状态
private bool _state = false;
//是否被打到
public void IsState() {
if (_state && _life > 0) {
_life -= 1;
_state = false;
} else {
_state = true;
}
}
public void RoleRotate() {
float eularY = Input.GetAxis("Mouse X") * _angleSpeed * Time.deltaTime;
}
//风发射子弹
public void RoleShoot() {
if (Input.GetMouseButtonDown(0)) {
Instantiate(_prefabBullet, transform.position, transform.rotation);
}
}
}
public class Enemy : MonoBehaviour {
//敌人被打到状态
private bool _state = false;
//玩家与敌人距离
private float _distance; //角色
public GameObject _role;
//生命值
private int _life = 10;
//敌人被攻击次数
private int _timeAccack = 0;
//敌人状态
public void EnemyState() {
if (_distance >= 10f) {
if (_life >= 1 && _state == true) {
_life -= 1;
_timeAccack++;
}
_state = false;
}
else if (_distance >= 0 && _state == false) {
_state = true;
}
}
//敌人与玩家距离
public void Distance() {
_distance = Vector3.Distance(transform.position, _role.transform.position);
}
void OnGUI() {
GUI.TextArea(new Rect(20, 50, 80, 30), _timeAccack.ToString());
GUI.TextArea(new Rect(20, 90, 80, 30), _timeAccack.ToString());
GUI.TextArea(new Rect(20, 130, 80, 30), _timeAccack.ToString());
}
}
167. 3D 空间有三个 cube 当做点,有一条鱼的模型,要求在三点之间游动,要 求转向平滑一点,控制鱼的运动朝向(用四元数和欧拉角) 使用 transform.localRotation = Quaternion.Slerp(Quaternion a,Quaternion b,float c)实现物体平滑转向
四、 Unity 性能优化 168. lod 是什么,优缺点是什么 LOD 技术即 Levels of Detail 的简称,意为多细节层次。LOD 技术指根据物体模型的节点在显示环境中所 处的位置和重要度,决定物体渲染的资源分配,降低非重要物体的面数和细节度,从而获得高效率的渲染运算。
优点:可根据距离动态地选择渲染不同细节的模型
缺点:加重美工的负担,要准备不同细节的同一模型,同样的会稍微增加游戏的容量。
169. MipMap 是什么?作用? 在三维计算机图形的贴图渲染中有一个常用的技术被称为 Mipmapping。为了加快渲染速度和减少图像 锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为 MIP map 或者 mipmap。
170. 当游戏中需要频繁创建一个物体对象时,我们需要怎么做来节省内存。 做一个 pool,游戏开始时预先实例化足够的数量,然后用的时候取不用的时候收回
171. 如何优化内存? 有很多种方式,例如
1.压缩自带类库;
2.将暂时不用的以后还需要使用的物体隐藏起来而不是直接 Destroy 掉;
3.释放 AssetBundle 占用的资源;
4.降低模型的片面数,降低模型的骨骼数量,降低贴图的大小;
5.使用光照贴图,使用多层次细节(LOD),使用着色器(Shader),使用预设(Prefab)。
172. 动态加载资源的方式?和区别 1.通过 Resources 模块,调用它的 load 函数:可以直接 load 并返回某个类型的 Object,前提是要把这 个资源放在 Resource 命名的文件夹下,Unity 不关有没有场景引用,都会将其全部打入到安装包中。 Resources.Load();
2.通过 bundle 的形式: 即将资源打成 asset bundle 放在服务器或本地磁盘, 然后使用 WWW 模块 get 下来, 然后从这个 bundle 中 load 某个 object。
3.通过 AssetDatabase.loadasset :这种方式只在 editor 范围内有效,游戏运行时没有这个函数, 它通常 是在开发中调试用的 【AssetDatabase 资源数据库】
区别:Resources 的方式需要把所有资源全部打入安装包,这对游戏的分包发布(微端)和版本升级(patch)是不利的,所以 unity 推荐的方式是不用它, 都用 bundle 的方式替代, 把资源达成几个小 的 bundle, 用哪个就 load 哪个,这样还能分包发布和 patch,但是在开发过程中,不可能没更新一个 资源就打一次 bundle, 所以 editor 环境下可以使用 AssetDatabase 来模拟,这通常需要我们封装一个 dynamic resource 的 loader 模块,在不同的环境下做不同实现。
动态资源的存放
有时我需要存放一些自己的文件在磁盘上,例如我想把几个 bundle 放在初始的安装里, unity 有一个 streaming asset 的概念,用于提供存储接口的访问。我们需要在编辑器建立一个 StreamingAssets 名字 的文件夹,把需要我们放在客户磁盘上的动态文件放在这个文件夹下面,这样安装后,这些文件会放在用户磁盘的指定位置,这个位置可以通过 Application.streamingAssetsPath 来得到。
173. 请简述一下对象池原理,什么情况下使用? 对象池背后的理念其实是非常简单的。我们将对象存储在一个池子中,当需要时在再次使用,而不是 每次都实例化一个新的对象。池的最重要的特性,也就是对象池设计模式的本质是允许我们获取一个“新的”对象而不管它真的是一个新的对象还是循环使用的对象。 对象池通常用于在那些需要经常创建又销毁的对象比如我们场景中的小怪,经常需要创建和销毁,我 们就可以在小怪销毁的时候,不真正的销毁而是,而是把它放入对象池中等到下一次我们需要创建小怪的时候,再从对象池中取出来。
174. 使用 mipmap 有什么好处?什么情况下使用? Mipmap 纹理技术是目前解决纹理分辨率与视点距离关系的最有效途径,它会先将图片压缩成很多逐渐 缩小的图片,例如一张 64*64 的图片,会产生 64*64,32*32,16*16,8*8,4*4,2*2,1*1 的 7 张图片,当屏幕上需 要绘制像素点为 20*20 时,程序只是利用 32*32 和 16*16 这两张图片来计算出即将显示为 20*20 大小 的一个图片,这比单独利用 32*32 的那张原始片计算出来的图片效果要好得多,速度也更快。
175. Unity 内存优化? GC 垃圾回收
176. 你认为 unity 在开发过程中哪些地方比较容易造成内存泄漏和内存泄漏 问题?如何避免? 脚本做载入不删除处理时,往往脚本中还有一些不用的变量,容易导致内容泄漏
177. 使用 NGUI 开发滚动视图,当滚动列表达到几百条的时候,如何才能保 证界面的滚动流畅运行 1. 每个滚动条目都是同一个预设体的实例
2.做缓存,只要实例化视野范围内滚动条目,往上超出视野部分,自动填补到视野的下面
178. 如何解决过多创建和删除对象带来的卡顿问题 对象池,把不用对象缓存到一个对象列表中
179. Unity 资源加载的有几种方式,简述 asset bundie 1. 直接在脚本中 public 一个对象,然后在监视器面板进行赋值
2. 直接在程序中进行 find 查找
3. Resource.load
4. 把资源打成 Assetbudle,然后用的时候 load 进来 assetbundle 就是对资源的打包处理,同时这种资源格式便于从互联网上下载
180. 背包系统中只有 20 个格子,现在有总共有 100 个物体,除了显示在 视野中的 20 个外,对其他的处理方法?(注:将其他隐藏起来不可行,对象池得有具体的说明) 1. 每个滚动条目都是同一个预设体的实例
2. 做缓存,只要实例化视野范围内滚动条目,往上超出视野部分,自动填补到视野的下面
五、 服务器数据库等杂项 181. Unity 连接数据库 需要得到 Mono.Data.Sqlite.dll 文件与 System.Data.dll 文件
182. 如何与服务器交互 做游戏,基本上都避免不了与服务器端交互,与服务器端交互的方式也有几种,总结起来就是长连接模式(Socket)与短链接模式(Http)。
183. 如何处理网络异常下的可玩性 1)为游戏增加单机模式:比如故事模块,网络异常时可以阅读游戏的故事;丰富的技能或卡牌,网络异常时可以了解技能和卡牌;提供单机玩法,玩家可以与 AI 进行游戏等。
2)为游戏提供教程模块,网络异常时可以学习游戏技巧。
184. 怎样反外挂? 对外挂的看法 游戏外挂的原理:外挂分为多种,比如模拟键盘的,鼠标的;修改数据包的;修改本地内存的。
1)对于模拟用户的鼠标键盘输入的外挂,我们可以用网页上常用的验证码的方式来对付。模拟键盘鼠
标的外挂对游戏的影响比加速、修改封包、修改内存、脱机等要小得多,因此被一些人称为绿色外挂。2)让服务器不把在正常情况下玩家看不到的东西的数据传送给客户端。
3)把玩家操作记录发到服务器进行模拟,如果和客户端的计算结果偏差较大可以认为作弊。
185. 你对跨平台的了解。 跨平台就是在一个熟悉的平台上面开发的软件或者程序,直接可以在其他平台上正常的运行显示而不 需要对其原始文件或者原始代码进行修改。
186. 谈谈你们公司的网络编程 在我们公司基本是由服务端人员开发的,我这边只调用他们提供的客户端 SDK 和服务器端通信。服务 器端是公司用 C++自行研发的。
187. 会做数据库吗?有嵌套的数据库能做么? 会。用过关系型数据库 mysql。能做,只是这方面之前在公司没怎么负责这块,有些生疏,稍微熟悉一下就能做。(社区提供持续更新版本)
188. 了解代码管理么?在开发中使用什么代码管理工具?使用的接口多一点还是继承多一点? 了解。使用 SVN 进行代码管理。接口多一点。
189. 公司内部信息传递用的什么安全协议? 1、公司自定义的安全协议 或者 基于 SSL/TLS 协议 或者 SSH 协议
2、我们至少调用基于相关协议的 SDK
3、SSL/TLS 协议
SSL/TLS 协议(RFC2246 RFC4346)处于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。从协议内部的功能层面上来看,SSL/TLS 协议可分为两层:
1. SSL/TLS 记录协议(SSL/TLS Record Protocol),它建立在可靠的传输层协议(如 TCP)之上,为上层协议提供数据封装、压缩、加密等基本功能。2. SSL/TLS 握手协议(SSL/TLS Handshake Protocol),它建立SSL/TLS 记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等初始化协商功能。SSH 是英文 Secure Shell 的简写形式。通过使用 SSH,你可以把所有传输的数据进行加密,这样”中间人”这种攻击方式就不可能实现了,而且也能够防止 DNS 欺骗和 IP 欺骗。使用 SSH,还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。SSH 有很多功能,它既可以代替 Telnet,又可以为 FTP、Pop、甚至为 PPP 提供一个安全的”通道”。
190. 原公司服务器怎么实现多人在线? 使用 socket 基于 TCP 协议开发的多人在线。公司有自行开发的服务端程序
191. 项目问题,和美工想法冲突了怎么办? 找项目主管协调处理
192. 对 unity 的理解 可以做 VR、手游、工艺仿真、端游、页游跨平台的游戏引擎
193. 面试题:VR 相关问题用了哪些设备?接入了哪些 SDK?根据项目问如 何实现手势控制? htc vive 和 oculus, htc vive 用到的是 steam vr 免费插件,Oculus 早期有 SDK,现在 Unity 原生支持
194. 开过什么平台?多线程的理解 PC、Android。
多线程是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。使用线程可以把占据时间长的程序中的任务放到后台去处理用户界面可以更加吸引人,这样比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度,程序的运行速度可能加快,在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下可以释放一些珍贵的资源如内存占用等等。
195. 怎样实现植物的弯曲 1、max 做骨骼动画2、修改 Tree 组件的 Growth Angle 的值
196. 用过什么游戏框架? SimpleFramework,基于 ulua 的框架,支持 ugui 和 ngui 的热更新
197. 模型导入 Unity 后怎么与数据库产生联系?类似打通程序和数据库通 道 例如 mysql 数据库,需要导入两个文件,就可以通过 sql 语句往数据库写数据,数据可以是模型信息
198. 用过什么传输协议,用什么语言 http,tcp(socket) 都是 C# 语言编写
199. 都在什么平台上开发过游戏或软件用的什么框架 Android
200. 会写框架么 设计模式了解一些,但是没写过框架
201. 请简述在客户端开发方面 你最擅长的模块系统,以及你觉得哪些模块 会出现的问题 擅长 UI 模块的制作,我认为热更新模块会出现问题,比如资源依赖不合理,导致资源包过大
202. 如何实现背包系统、宠物系统、装备系统的实时更新? NGUI 做界面,使用 ulua 做热更新。之前公司使用的是 SimpleFramework 这样的框架。
203. 热更新的解决方案(资源以及代码) ulua 框架、simpleFramework 框架 、bundle manager 插件
六、 数据结构算法相关 204. 对数据结构了解吗?说说你常用的数据结构。 了解,数据结构是每个程序员都要会一点的。链表、列表、散列表最常用,队列和栈也经常使用。二叉树偶尔使用。
205. 什么是状态机,什么是行为树 有限状态机系统:是指在不同阶段会呈现出不同的运行状态的系统,这些状态是有限的、不重叠的。这样的系统在某一时刻一定会处于其所有状态中的一个状态,此时它接收一部分允许的输入,产生一部分可能的响应,并且迁移到一部分可能的状态。
1. 基本节点是状态:他包含了一系列运行在该状态的行为以及离开这个状态的条件。
2. 状态可以任意跳转,实现简单,但是对于大的状态机很难维护.状态逻辑的重用性低.
3. 每一个状态的逻辑会随着一些新状态的增加而越来越复杂。维持状态的数量和状态逻辑复杂性是一个很大的难点。需要合理的分割以及重用状态。
4. 状态机状态的复用性很差,一旦一些因素变化导致这个环境发生变化。你只能新增一个状态,并且给这个新状态添加连接他以及其他状态的跳转逻辑。
5. 状态机的跳转条件一旦不满足,就会一直卡在某一个状态。
行为树:一个流行的 AI 技术,涵盖了层次状态机,事件调度,事件计划,行为等一系列技术。
1. 高度模块化状态,去掉状态中的跳转逻辑,使得状态变成一个“行为”。
2. “行为”和”行为”之间的跳转是通过父节点的类型来决定的。比如并行处理两个行为,在状态机里面无法同时处理两个状态。
3. 通过增加控制节点的类型,可以达到复用行为的目的。
4. 可视化编辑。
206. 对 List 的理解 有序的对象列表,属于数据结构的一种:顺序结构
泛型集合类,引入 System.Collections.Generic 命名空间,
常用操作有,Count 属性查看长度,Add()添加,Remove()去除,AddRange()添加集合,Clear()清空集合。
207. 数组和 List 的核心区别 数组在 C#中最早出现的。在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单。
数组存在一些不足的地方。在数组的两个数据间插入数据是很麻烦的,而且在声明数组的时候必须指定数组的长度,数组的长度过长,会造成内存浪费,过段会造成数据溢出的错误。如果在声明数组时我们不清楚数组的长度,就会变得很麻烦。
List<T>是集合,集合元素的数量可以动态变化。增加、插入、删除元素很方便。
208. 数据结构的看法 具有一定关系的数据元素集合,好的数据结构有利于简化算法的编写
209. 深度优化会么 会一点,比如在代码消耗上经常使用 StopWatch 类去优化算法,通常用 IDisposable 去显式的释放资源。
210. 实现二分要什么条件 有序结构
211. c++,socket 网络编程会不会 C++上学的时候学过,工作之后一直没用过。
Socket 就是一套实现双向通信的 API。使用过 C#的 TCP(面向连接、可靠)和 UDP 连接(面向非连接、不可靠)
212. 二叉树的所有遍历方式的原理及优缺点 前序遍历,先访问根节点在访问左节点在访问右节点。
中序遍历,先访问左节点在访问根节点在访问右节点。
后序遍历,先访问左节点在访问右节点在访问根节点。
前中后代表的是访问根节点的时序。
这一点上没有什么本质上的优缺点,要看实际需求决定采用何种遍历方式
采用递归方式和非递归方式。前者优点是直观,编写起来简单,缺点是但其开销也比较大。非递归形式开销小,但编写复杂。
213. 数据结构中数组和链表各有什么特点,什么场合下应该使用数组,什么 场合下应该使用链表 二者都属于一种数据结构
从逻辑结构来看
1. 数组必须事先定义固定的长度(元素个数),不能适应数据动态地增减的情况。当数据增加时,可能超出原先定义的元素个数;当数据减少时,造成内存浪费;数组可以根据下标直接存取。
2. 链表动态地进行存储分配,可以适应数据动态地增减的情况,且可以方便地插入、删除数据项。(数组中插入、删除数据项时,需要移动其它数据项,非常繁琐)链表必须根据 next 指针找到下一个元素从内存存储来看1. (静态)数组从栈中分配空间, 对于程序员方便快速,但是自由度小
2. 链表从堆中分配空间, 自由度大但是申请管理比较麻烦。从上面的比较可以看出,如果需要快速访问数据,很少或不插入和删除元素,就应该用数组;相反,如果需要经常插入和删除元素就需要用链表数据结构了。
七、 设计模式相关 214. 用过哪些设计模式?谈谈自己比较熟悉的设计模式 1、工厂模式 2、代理模式 3、策略模式 4、观察者模式 6、单例模式
工厂模式:简单工厂模式解决的问题是如何去实例化一个合适的对象。
简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程。凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。比如说写技能是一系列类,那么就可以使用工厂模式创建。
代理模式:一个是真正的你要访问的对象(目标类),一个是代理对象,真正对象与代理对象实现同一个接口,先访问代理类再访问真正要访问的对象。代理模式就是多一个代理类出来,替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你做,此处的代理就是这个意思。再如我们有的时候打官司,我们需要请律师,因为律师在法律方面有专长,可以替我们进行操作,表达我们的想法。
代理模式的应用场景:
如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种办法:
1、修改原有的方法来适应。这样违反了“对扩展开放,对修改关闭”的原则。
2、就是采用一个代理类调用原有的方法,且对产生的结果进行控制。这种方法就是代理模式。
使用代理模式,可以将功能划分的更加清晰,有助于后期维护!
其实,简单来讲就一句 使用算法的客户。策略模式的决定权在用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此,策略模式多用在算法决策系统中,外部用户只需要决定用哪个算法即可。
观察者模式很好理解,类似于邮件订阅和 RSS 订阅,当我们浏览一些博客或 wiki 时,经常会看到 RSS 标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。
单例对象(Singleton)是一种常用的设计模式。在 C#应用中,单例对象能保证在一个 CLR 中,该对象
只有一个实例存在。这样的模式有几个好处:
1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。
2、省去了 new 操作符,降低了系统内存的使用频率,减轻 GC 压力。
3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。
(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核
心交易服务器独立控制整个流程。
215. 请说出 4 种面向对象的设计原则,并分别简述它们的含义。 1) 单一职责原则 (The Single Responsiblity Principle,简称
SRP):一个类,最好只做一件事,只有一个引起它的变化.
2) 开放-封闭原则 (The Open-Close Principle,简称
OCP):对于扩展是开放的,对于更改是封闭的
3) Liskov 替换原则(The Liskov Substitution Principle,简称
LSP):子类必须能够替换其基类
4) 依赖倒置原则 (The Dependency Inversion Pricinple, 简称
DIP):依赖于抽象
5) 接口隔离原则 (The Interface Segregation Principle,简称
ISP):使用多个小的专门的接口,而不要使用一个大的总接口。
216. 设计一个状态机类型,状态值为 int 类型,要求: 拥有接口,获取当前状态,切换状态
外部可以监听状态切换事件,参数为切换前状态和切换后状态(使用 delete 和 event)//定义一个状态
public abstract class IAction{
public int StateName;
public IAction(int stateName) {
this.StateName = stateName;
}
public int GetState(){
return StateName;
}
public abstract bool CanGetIn();
public abstract void GetIn();
public abstract void GetOut();
public abstract void Update(float dt);
}
//定义一个状态切换事件
public abstract class IEvent {
public int code;
public IEvent(int code) {
this.code = code;
}
public int GetCode(){
return code;
}
//当前状态事件检测
public abstract bool Check();
}
public class AvatarStateMachine{
//初始化状态机public void InitStateMachine(){}
//注册一个状态
public void AddAction(int action) {}
//注册一个状态切换事件
public void AddEventTransition(int fromAction, int toAction, IEvent byEvent) {}
//更新当前状态,检测能否进入下一个状态
public void UpdateStateMachine(){}
//强行切换状态
public void SwitchTo(int toState) {}
}
217. 如何处理 unity 中界面资源,界面逻辑以及功能模块三者之间耦合关系 这就是在 Unity 使用 MVC 时通常将功能模块尽量脱离脱离 MonoBehavior,同一个模块内 M 只用来操
作数据并发送更新消息,V 只用来接受消息并控制界面显示跳转,使用 C 来处理界面与数据的频繁操
作。
218. 观察者模式的深入理解? 观察者模式:一对多的关系,当被观察这发生改变时会通知所有观察者。让双方都依赖于抽象,使得
各自变化不会影响另一方。
219. MVC 模式 用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和
个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
八、 图形学相关 220. 简述四元数的作用,四元数对欧拉角的优点? 四元数用于表示旋转
A.四元数一般定义如下:q=w+xi+yj+zk 其中 w,x,y,z 是实数。同时,有: i*i=-1 j*j=-1 k*k=-1
B.四元数也可以表示为:q=[w,v] 有多种方式可表示旋转,如 axis/angle、欧拉角(Euler angles)、矩阵
(matrix)、四元组等。 相对于其它方法,四元组有其本身的优点:
a.四元数不会有欧拉角存在的 gimbal lock 问题[万向节死锁]
b.四元数由 4 个数组成,旋转矩阵需要 9 个数
c.两个四元数之间更容易插值
d. 四 元 数 、 矩 阵 在 多 次 运 算 后 会 积 攒 误 差 , 需 要 分 别 对 其 做 规 范 化 (normalize) 和 正 交 化
(orthogonalize),对四元数规范化更容易e.与旋转矩阵类似,两个四元组相乘可表示两次旋转
221. 向量的点乘、叉乘以及归一化的意义? 1)点乘描述了两个向量的相似程度,结果越大两向量越相似,还可表示投影
2)叉乘得到的向量垂直于原来的两个向量
3)标准化向量:用在只关系方向,不关心大小的时候
222. 矩阵相乘的意义及注意点 用于表示线性变换:旋转、缩放、投影、平移、仿射
注意矩阵的蠕变:误差的积累
223. alpha blend 工作原理 实际显示颜色 = 前景颜色*Alpha/255 + 背景颜色*(255-Alpha)/255
224. 写光照计算中的 diffuse 的计算公式 实际光照强度 I= 环境光(Iambient) + 漫反射光(Idiffuse) + 镜面高光(Ispecular);
环境光:Iambient= Aintensity* Acolor; (Aintensity 表示环境光强度,Acolor 表示环境光颜色)
漫反射光:Idiffuse = Dintensity*Dcolor*N.L;(Dintensity 表示漫反射强度,Dcolor 表示漫反射光颜色,N
为该点的法向量,L 为光源向量)
镜面反射光:Ispecular = Sintensity*Scolor*(R.V)^n;(Sintensity 表示镜面光照强度,Scolor 表示镜面光颜色,
R 为光的反射向量,V 为观察者向量,n 称为镜面光指数)
225. 两种阴影判断的方法工作原理 阴影由两部分组成:本影与半影
本影:景物表面上那些没有被光源直接照射的区域(全黑的轮廓分明的区域)
半影:景物表面上那些被某些特定光源直接照射但并非被所有特定光源直接照射的区域(半明半暗区
域)
求阴影区域的方法:做两次消隐过程
一次对每个光源进行消隐,求出对于光源而言不可见的区域 L;
一次对视点的位置进行消隐,求出对于视点而言可见的面 S;
shadow area = L ∩
S
阴影分为两种:自身阴影和投射阴影
自身阴影:因物体自身的遮挡而使光线照射不到它上面的某些可见面
工作原理:利用背面剔除的方法求出,即假设视点在点光源的位置。
投射阴影:因不透明物体遮挡光线使得场景中位于该物体后面的物体或区域受不到光照照射而形成的
阴影工作原理:从光源处向物体的所有可见面投射光线,将这些面投影到场景中得到投影面,再将这些投
影面与场景中的其他平面求交得出阴影多边形,保存这些阴影多边形信息,然后再按视点位置对场景
进行相应处理得到所要求的视图(利用空间换时间,每次只需依据视点位置进行一次阴影计算即可,
省去了一次消隐过程)若是动态光源此方法就无效了。
226. Vertex Shader 是什么?怎么计算? 顶点着色器是一段执行在 GPU 上的程序,用来取代 fixed pipeline 中的 transformation 和 lighting,
Vertex Shader 主要操作顶点。
Vertex Shader 对输入顶点完成了从 local space 到 homogeneous space(齐次空间)的变换过程,
homogeneous space 即 projection space 的下一个 space。在这其间共有 worldtransformation, view
transformation 和 projection transformation 及 lighting 几个过程。
227. 什么是渲染管道? 是指在显示器上为了显示出图像而经过的一系列必要操作。 渲染管道中的很多步骤,都要将几何物体
从一个坐标系中变换到另一个坐标系中去。主要步骤有:
本地坐标->视图坐标->背面裁剪->光照->裁剪->投影->视图变换->光栅化。
228. 怎么判断两个平面是否相交?不能用碰撞体,说出计算方法 对于两个平面 Ax+By+Cz+D=0 与 ax+by+cz+d=0,只要(A,B,C)与(a,b,c)不成比例,这两个平面就是相交的。
229. 法线贴图 、CG 动画 A.法线贴图:是在原物体的凹凸表面的每个点上均作法线,通过 RGB 颜色通道来标记法线的方向, 你
可以把它理解成与原凹凸表面平行的另一个不同的表面,但实际上它又只是一个光滑的平面。
B.CG 动画:原为 Computer Graphics 的英文缩写。随着以计算机为主要工具进行视觉设计和生产的一系
列相关产业的形成,国际上习惯将利用计算机技术进行视觉设计和生产的领域通称为 CG。它既包括技
术也包括艺术,几乎囊括了当今电脑时代中所有的视觉艺术创作活动,如平面印刷品的设计、网页设
计、三维动画、影视特效、多媒体技术、以计算机辅助设计为主的建筑设计及工业造型设计等。
230. 什么是局部坐标,什么是世界坐标? 世界坐标是不会变的,一直以世界坐标轴的 XYZ 为标准。 局部坐标其实就是自身的坐标,会随着物体
的旋转而变化的。
231. 请描述 MeshRender 中 material 和 shader 的区别? Shader(着色器)实际上就是一小段程序,它负责将输入的 Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或
者颜色等,加上对应的 Shader,以及对 Shader 的特定的参数设置,将这些内容(Shader 及输入参数)
打包存储在一起,得到的就是一个 Material(材质)Shader 大体上可以分为两类:表面着色器(Surface
Shader) 、片段着色器(Fragment Shader)
232. 什么是矢量图 矢量图:计算机中显示的图形一般可以分为两大类——矢量图和位图。矢量图使用直线和曲线来描述
图形,这些图形的元素是一些点、线、矩形、多边形、圆和弧线等等,它们都是通过数学公式计算获
得的。例如一幅花的矢量图形实际上是由线段形成外框轮廓, 由外框的颜色以及外框所封闭的颜色决
定花显示出的颜色。由于矢量图形可通过公式计算获得,所以矢量图形文件体积一般较小。矢量图形
最大的优点是无论放大、缩小或旋转等不会失真;最大的缺点是难以表现色彩层次丰富的逼真图像效
果。
233. 四元组是什么? 所谓四元数,就是把 4 个实数组合起来的东西。4 个元素中,一个是实部,其余 3 个是虚部。
234. 你对你的数学知识感觉如何?比如空间向量,图形学 个人感觉还是不错的,空间向量和图形学之前有自学过。只是在实际工作中直接使用的机会比较少,
底层的一些操作有些生疏了。
235. 会写 shader 么 了解一些,但是写的不多
236. 3D 基础相关 2 1 0 1 0 1
1 0 1 × 0 0 0
2 1 1 1 1 1
上述两个矩阵相乘的结果
2 0 2
2 1 2
3 1 3
237. 什么是投影矩阵 投影矩阵是一个典型的缩放和透视矩阵。投影变换将视锥变换成一个直平行六面体的形状。因为视锥的近处比远处小,这样就会对靠近摄像机的对象起到放大的作用,也就将透视应用到了场景当中
238. 什么是 UV UV 坐标是指所有的图象文件都是二维的一个平面。水平方向是 U,垂直方向是 V,通过这个平面的,
二维的 UV 坐标系。我们可以定位图象上的任意一个象素。
239. Cullback,cullfront,culloff 区别 剔除背面、剔除前面、不剔除
240. 什么是顶点程序和片段程序 顶点着色器是一组指令代码,这组指令代码在顶点被渲染时执行。
片段着色器也是在 GPU 上运行的小程序。它们负责输出每个呈现的三角形像素的最终像素颜色。基本
而言,它的工作原理如下:片段着色器以输入的形式收到顶点着色器通过管道传递的所有这些片段。
241. 如何实现以下人物在树丛中部分透明效果? Shader "Custom/PlayerDiffuse" {
Properties {
_NotVisibleColor ("NotVisibleColor (RGB) ", Color) = (0.3,0.3,0.3,1)
_MainTex ("Base (RGB) ", 2D) = "white"{}
}
SubShader {
Tags { "Queue"= "Geometry+500""RenderType"="Opaque"}
LOD 200
Pass {
ZTest Greater
Lighting Off
ZWrite Off
//Color [_NotVisibleColor]
Blend SrcAlpha OneMinusSrcAlpha
SetTexture [_MainTex] { ConstantColor [_NotVisibleColor] combine constant * texture }
}
Pass {
ZTest LEqual
Material {
Diffuse (1,1,1,1)
Ambient (1,1,1,1)
}
Lighting Off SetTexture [_MainTex] { combine texture }
}
}
FallBack "Diffuse"
}
242. 简述 lightmap 的使用 (此为帖子全文,请自己简述)
Unity 完全集成了光照贴图,可以通过编辑器创建完整的光照贴图,你完全不用担心,所有材质会自动
获得光照贴图。光照贴图的意思是,所有灯光的特性将被直接映射到 Beast lightmapper 并烘培到纹理,
以此获得更好的性能。UnityPro 版扩展了全局光照功能,可以烘焙出真实而漂亮的光照,当然这就不
能同时使用实时光照。此外,Unity 专业版带给你天光和发光材质,为你增加更有趣的场景照明。
在此页中,你会发现更深入的描述,可以找到在 Lightmapping 窗口的所有属性。从菜单中 Window –
Lightmapping 打开 Lightmapping 窗口。
物体
物体的烘培设置:灯光、网格渲染和地形 - 取决于当前的选择。
网格渲染器和地形:
·Static 静态
可渲染网格和地形必须标记为静态才能被烘培。
·Scale In Lightmap 光照图比率
(只作用于可渲染网格)特别大的数值将分配给可渲染网格更大的分辨率。最终分辨率比例(光照图
缩放)*(物体世界坐标空间所占面积)*全局分辨率烘培设置)如果设置为 0 物体将不被烘培。(但是
它依旧对其他的物体有影响)
·Lightmap Size 光照图大小
(只作用于地形)光照贴图尺寸是地形实例独有的属性,地形将不和其他物体共用图集。地形光照贴
图将存贮在一个单独的文件中。
·Atlas 图集
图集信息-如果 Lock Atlas(锁定图集)选项没有开启那么这些参数将自动更新。如果 Lock Atlas(锁定
图集)选项开启,这些参数将不会自动编辑。但是你可以手动设置他们。
·Lightmap Index 光照图索引
光照贴图序列中的索引。
·Tiling 平铺
(只作用于可渲染网格)物体光照贴图 UVs 平铺。
·Offset 偏移
(只作用于可渲染网格)物体 UVs 的偏移。
Lights 灯光:
·Lightmapping 光照贴图
光照图模式:仅实时模式,自动模式和仅烘培 模式。查看下面 Dual Lightmaps 的描述。
·Color 颜色
灯光颜色。一些属性只作用于实时光照。
·Intensity 光强度
灯光照明强度。一些属性只作用于实时光照。
·Bounce Intensity 反弹强度
特定光源间接光照强度的倍增值。·Baked Shadows 烘焙阴影
控制当前灯光是否产生阴影。(当选择自动选项时同时影响实施阴影的产生)
·Shadow Radius 阴影半径
(只作用于点光源和聚光灯)增加这个值将得到一个较柔和的阴影。增加这个值的大小影响阴影覆盖
面积范围的计算(不会影响到灯光照射范围)。
·Shadow Angle 阴影角度
(只影响平行光)增加这个值将会得到一个比较柔和的阴影-增加灯光阴影覆盖角度范围的计算。(不
会影响到灯光照射范围)
·Shadow Samples 阴影采样
如果你将阴影半径或者角度设置为大于 0 的值,增加阴影采样值能得到一个比较好的结果。高采样值
将消除半影中中的噪点。
Bake 烘焙
全局烘焙设置。
·Mode 模式
控制离线烘培和实时光照模式。在 Dual Lightmaps 模式下近端和远端光照图都将被烘培;只有延迟光
照渲染方式式才能更好的支持双重光照图。Single Lightmaps 模式仅烘培远端光照图。在延迟渲染方式
下也可以强制使用单光照图模式。
·Use in forward rendering 使用正向渲染
(Dual lightmaps only) 在正向渲染中启用 dual lightmaps。要注意的是这需要你创建自己的 shader 来达到
目的。
·Quality 质量
高质量(比较好的效果)和低质量(计算速度快)的预设值。它们将影响最终聚集光线数量和对比度
的数值以及其他有关最终聚集和抗锯齿的设置。
·Bounces 反弹
控制全局光照模拟中光线反弹的次数。如果想得到一个比较柔和的相对真实的光照至少需要将此数值
设置为 1.如果设置为 0 那么只会计算直接光照。
·Sky Light Color 天光颜色
天光是模拟从天球向所有方向发射光线照射场景-在烘培室外场景的时候开启天光将得到一个非常好的
效果。
·Sky Light Intensity 天光强度
天光的强度 - 0 代表禁用天光。
·Bounce Boost 反弹增强
增强间接光, 可用来增加场景中渲染太快没有烘焙出灯光的反弹量。
·Bounce Intensity 反弹强度
间接光照的强度倍增器。
·Final Gather Rays 最终聚集光线
控制从最终聚集点发射的光线数量-较高的数值能得到更好的效果 。
·Contrast Threshold
对比度阈值
颜色对比度根据采样运算规则控制哪些最终聚集点被创建。较高的数值可以使 Beast 处理物体表面灯
光照明时有很大的改善,从而得到一张平滑的光照贴图但是会牺牲一些照明细节。较低的数值需要最
终聚集光线数量要高于对比度阈值这样被过滤掉的最终聚集点才能被创建出来。
·Interpolation 插值
控制最终聚集点颜色的插值。设置 0 为线性插值,设置 1 为基于梯度的高级插值。多数情况下推荐使
用后者。
·Interpolation Points 插值点设置最终聚集点颜色的插值的参考点。高数值可以获得比较平滑的结果,但是会牺牲一些光照细节。
·Ambient Occlusion
环境光遮挡
烘培光照图时产生一定数量的环境阻光。环境阻光计算物体每一点被一定距离内的其他物体或者一定
距离内自身物体的遮挡程度(用来模拟物体表面环境光及阴影覆盖的比例,达到全局光照的效果),所
以和所有的灯光设置没有太大关系。
·Max Distance 最大距离
Beyond this distance a ray is considered to be unoccluded. 0 stands for infinitely long rays.
超出这个距离的光线将不被遮挡。0 表示无限长的光线。
·Contrast 对比度
控制完全阻光和不阻光之间的过度。
·Lock Atlas 锁定图集
当锁定图集被打开。自动图集功能将不执行,物体光照图索引,平铺和偏移将不能编辑。
·Resolution 分辨率
每世界单位中光照图分辨率的大小。因此当设置分辨率为 50 的一个 10 单位乘以 10 单位的平面将产
生一张 500*500 像素的光照贴图。
Maps 贴图所有光照贴图的可编辑数组。
·Compressed 压缩
控制是否压缩所有当前场景中的光照贴图。
·Array Size 数组大小
光照贴图数组的大小(
0~254)。
·Lightmaps Array 光照贴图数组
当前场景被烘培的所有光照图的可编辑序列。没有被指定的通道将被处理为黑色光照图。索引相当于
网格渲染和地形中所使用的光照图编号。除非锁定图集被开启否则序列将自动初始化并分配给你烘培
的贴图。
Lightmap Display 光照贴图显示
在编辑器中控制光照图如何显示的工具。光照图显示是在场景视口中的一个子窗口。可见只要光照图
窗口可见。
·Use Lightmaps 使用光照贴图
是否渲染光照图。
·Shadow Distance 阴影距离
根据过度到只使用远端光照图时哪些设置为自动模式的灯光被关闭的距离。这里的设置覆盖其他面板
中相关设置。但是不能覆盖质量设置中的阴影距离设置。
·Show Resolution 显示分辨率
切换在场景中是否显示光照图分辨率。开启这项设置你可以在你的场景中直接预览静态物体光照图的
分辨率大小。
Details 细节
Dual Lightmaps 双重光照贴图
双光照贴图是 Unity 中的光照贴图可以同高光贴图,法线贴图和适当混合的实时阴影一起渲染的工具。
同时它也可以让你的光照贴图看起来效果更好,即使设置的光照分辨率较低。
双光照贴图默认情况下只能用于延迟光照渲染路径。但通过编写自定义着色器就可能让双光照贴图用
于前向渲染路径中(使用 dualforward 表面着色指令)。
双光照贴图即意为使用两套光照贴图:
·远 :包含全部照明
·近 :包含标记为自动模式的灯光所产生的的间接照明,和标记为仅烘焙模式的灯光,发光材质和天
光的所有照明。设置为仅实时的灯光永远不会被烘培。近端光照图作用于质量设置中的相对摄像机最小阴影距离范围
内。
在这个距离范围内,自动模式的灯光将实时渲染高光,凹凸和阴影,(它们的阴影与实时模式的等光的
阴影融为一体),间接光则来自近端光照贴图。 若超出阴影距离自动模式灯光就不再进行实时渲染,
而全部照明都由光照贴图产生(仅实时模式灯光仍然产生照明,但不产生阴影)。
下面的场景包含一个默认设置为为自动模式的平行光,一些烘培完光照贴图的静态物体(建筑物,障
碍物,其他静态物体)和一些动态的移动或可移动物体(持枪的假人,桶)。 该场景在双重光照贴图
模式中烘焙和渲染:阴影距离以外的建筑物完全由光照贴图产生照明,而两个假人由实时灯光产生动
态光照,但是不投射阴影; 阴影距离范围内的建筑物和地面被即时光照亮并投下实时阴影,但柔和的间
接光是来自于近端光照贴图产生。
243. Shader 的代码实现?大概写一下 Shader "Custom/NewSurfaceShader"{
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB) ", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG }
FallBack "Diffuse"
}
244. 游戏中要怎么实现矩阵相乘? //矩阵相乘
public static float[][] Mul(float[][] a, float[][] b) {
//确保矩阵 a 的列数和 b 的行数相等
if(a[0].length != b.length) {
return null;
}
//用来存放结果的矩阵,axb 的结果为 a 的行数和 b 的列数
float[][] result = new float[a.length][b[0].length];
//对 a 的每行进行遍历
for(int i=0; i<a.length; i++) {
//对 b 的每列进行遍历
for(int j=0;j<b[0].length; j++) {
//c 为每一个点的值
float c = 0;
//第 i 行 j 列的值为 a 的第 i 行上的 n 个数和 b 的第 j 列上的 n 个数对应相乘之和,其中 n 为 a
的列数,也是 b 的行数,a 的列数和 b 的行数相等
for(int k=0; k<a[0].length; k++) {
c += (a[i][k]*b[k][j]);
}
result[i][j] = c;
}
}
return result;
}
九、 逻辑题 245. 也许是因为我太善良,我上的当是要比别人多一些。D A. 非常同意 B.比较同意 C.比较不同意 D.非常不同意
246. 现在生活中老实人总是吃亏。D A. 非常正确 B.比较正确 C.比较不正确 D.非常不正确
247. 社会上很多不法分子逍遥法外 D A.非常正确 B.比较正确 C.比较不正确 D.非常不正确
248. 如果我家很小,如带客人来家我会有伤自尊 D A.非常同意 B.比较同意 C.比较不同意 D.非常不同意
249. 我多数娱乐活动都是和学生一起进行的 A A.非常同意 B.比较同意 C.比较不同意 D.非常不同意
250. 如果有件小事(如头痛或家务事),使我感到烦恼时,我会向别人倾诉 C A.非常同意 B.比较同意 C.比较不同意 D.非常不同意
251. 根据如下图形中的规律,问号代表下列哪个方块? A 252. 观察数字:54321,43215,32154,(),15432,第四个数字是多少? 21543
253. 在下列分数中,选出不同类的一项: C 可以约分 A.3/5 B.3/7 C.3/9
254. 小赵的店里来了一位顾客,挑了 20 元的货,顾客拿出 50 元,小赵没 有零钱找不开,就到隔壁小韩的店里把这 50 元换成零钱,回来给顾客找 了 30 元零钱,过了一会儿,小韩来找小赵,说刚才的是假钱,小赵马上 给小韩换成了一张真钱,问:在这一过程中小赵赔了多少钱? D A.50 元 B.60 元 C.70 元 D.80 元
255. 观察 3、3、8、8 这一组数字,不改变数字顺序,加入运算符号和括号, 将这些数字组成一个算式,使结果等于 27 答案:(3+3/8)*8=27
256. 图形共有 2000 个,按照下面的规律排列: △□□□△□□□△□□ □……第 1995 个图形是什么? 1995 % 4 = 3 所以是方块
257. 用三根火柴要摆成一个最小的数(不许把火柴折断或者弯曲),这个数 是什么? -11
258. 根据逻辑关系在方框内填出空缺处图形。
259. 说一个岛上有 100 个人,其中 5 个红眼睛,95 个蓝眼睛。这个岛上有 三个奇怪的宗教规则。 他们不能照镜子,不能看自己眼睛的颜色。
他们不能互相交流眼睛颜色的问题,也不能告诉别人对方的眼睛是什么颜色。
一旦有人知道了自己眼睛的颜色,他就必须在当天夜里自杀。
注:虽然题设了 5 个红眼睛,但岛民是不知道具体数字的。
岛民一直过着宁静的生活,相安无事。某天,有个旅行者到了这个岛上,由于不知道这里的规矩,所
以一起狂欢的时候,不留神就说了一句:你们这里有红眼睛的人。
最后的问题是:
1)假设这个岛上的人够聪明,每个人都可以做出缜密的逻辑推理。请问这个岛上将会发生什么?
2)为什么旅行者看似无意义的一句话改变了岛上的格局?
" 因为自从那个人说了岛上有红眼人后他们开始思考自己眼睛的颜色,假如有一个红眼人,那么他看
到 99 个蓝眼人,他第一天会自杀,如果有两个红眼人,他看到 98 蓝 1 红,如果他发现那个红眼人第
一天没自杀那么他将意识到他也是红眼人,故第二天两个红眼人都将自杀,同理可推知,第五天五个
红眼人将自杀,五个红眼人自杀之后,通过推理,剩下的都是蓝眼人了,所以第六天,剩下的蓝眼人都自杀了
260. 有 4 位好友,其中一个人干了一件好事,不留名,记者来查此事,问 4 位,他们的回答如下: A:不是我
B.是 C
C.是 D
D.他胡说
已知 3 个人说真话,一个人说假话,现在根据以上信息找出做了好事的人(并编程实现)
1.假设 A 讲假话,其馀三人讲真话,则 B 和 C 出现矛盾,所以假设不成立,A 讲真话.
2.假设 B 讲假话,其馀三人讲真话,则 C 和 D 的
说法出现矛盾,所以假设不成立,B 讲真话.
3.假设 C 讲假话,其馀三人讲真话,则 A、B、D 的证供都成立,所以假设成立,C 讲假话.
4.假设 D 讲假话,其馀三人讲真话,则 B 和 C 出现矛盾,所以假设不成立,D 讲真话.
推出,C 是做好事的人.
提示:
第一步:被测者从 1—4
第二步:将被测者代入表达式
第三步:判断 3 个表达式为真吗?是的则打印结果程序结束。不是,判断是否全测完,不是转第一步,
是打印未找到,程序结束。完成下面的程序。
# include <stdio.h>
main(){
int k = 0,sum = 0,g = 0;
char man = ' ';
for(k = 1; k <= 4 && g==10;k++) {
man=64+k;
sum=(man != 'A') + (man == 'C') + (men == 'D') + (men != 'D');
if(sum==3) {
clrscr();
printf("/nman=%c/n", 64 + k);
g = 1;
}
}
if(g != 1)
printf("can't found! ");
getch();
}(社区提供持续更新版本)