unity 3d
1. unity3d脚本从唤醒到销毁有一套完整的生命周期,列出系统自带的几个重要方法?哪些可能在同一个对象周期中反复的发生?
Awake -> OnEnable -> Start -> FixedUpdate -> Update - > LateUpdate-> OnGUI -> OnDisable -> OnDestroy
OnEnable -> FixedUpdate -> Update -> LateUpdate -> OnGUI -> OnDisable
2. 什么是协同程序
协同程序,即在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行。协程很像多线程,但是不是多线程,Unity的协程是在每帧结束之后去检测yield的条件是否满足。
3. 简述哈希表与字典的区别
(1) 相同点:
? 都是以键值对的形式存在,键是唯一的,值不需要唯一,都是无序的键值对
? 存储的个数不受限制
? 方法很相似
(2) 不同点:
? 键与值的类型不同
? 命名空间不同:hashtable是在System.Collections,字典是在System.Collections.Generic
? 实现方式不同
? 添加数据时hashtable快,频繁调用数据时dictionary快
4. string和stringBuilder的区别
string:字符串 stringBuilder:字符串常量
(1) 少量的字符串操作,或者是字符串不经常发生变化时,优先使用string
(2) string创建后分配在栈区,大小不可改变;stringBuilder创建后分配在堆区,大小可自由修改
(3) stringBuilder运行速度比string快
5. 当一个细小的高速物体撞向另一个较大的物体时,会出现什么情况?如何避免?
穿透(碰撞检测失败)
(1) 增大细小物体的碰撞体
(2) 使用射线检测,检测距离 (3) FixedUpdate频率修改,可以physics time减小,不建议这样做 (4) 改变物体的速度,确保rigidbody不超过一定的速度,来达到减速目的,这个也不实用 (5) 将检测方式改为连续检测,rigifdbody.collisionDetectionMode = CollisionDetectionMode.Continuous; 或者动态连续检测( CollisionDetectionMode.ContinuousDynamic) (6) 代码限制,加大计算量提前计算好下一个位置。
6. 请简述GC(垃圾回收)产生的原因,并描述如何避免?
用new创建一个对象时,当可分配的内存不足GC就会去回收未使用的对象,但是GC的操作是非常复杂的,会占用很多CPU时间,对于移动设备来说频繁的垃圾回收会严重影响性能。下面的建议可以避免GC频繁操作。 1)减少用new创建对象的次数,在创建对象时会产生内存碎片,这样会造成碎片内存不法使用 2)使用公用的对象(静态成员,常量),但是不能乱用,因为静态成员和常量的生命周期是整个应用程序。 3)在拼接大量字符串时StringBuilder。在使用注意,创建StringBuilder对象时要设置StringBuilder的初始大小如: StringBuilder sbHtml = new StringBuilder (size); 4)使用object pool(对象池)
7. 请简述ArrayList和List的主要区别?
ArrayList是非泛型列表,存储数据时把所有的数据都当成object类型存储,存在装箱问题,取出来使用的时候存在拆箱问题,装箱拆箱会使性能变差,而且存在数据安全问题,但是优点在于可以让值类型和引用类型互相转换。
List是泛型列表,在使用的时候才去定义数据类型,泛型避免了拆箱装箱的问题,存入读取速度较快,类型也更安全。
8. Prefab的作用?
Prefab我们通常称为预设体(或预制件,预制体)。
作用: 在开发一些功能的时候, 将一些能够复用的对象制作成预设体(可以是模型,窗口,特效等),可以将预设体存放到 Resources 目录之下,通过动态加载的方式加载到场景中并进行实例化。
优点:
1、频繁创建物体时,使用prefab可以节省内存
2、相同的物体进行同样的操作,可以使用prefab直接操作一次就好了
3、使用prefab可以动态的加载已经设置好的物体
9. 射线检测碰撞物的原理是?
射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射
10. 用代码实现第一人称跟随视角的移动
//一:
public class FirstCamera : MonoBehaviour {
private float speed = 5;
private Vector3 rot;
void Start()
{
}
void Update()
{
float mouseX = Input.GetAxis("MouseX")*speed;
float mouseY = Input.GetAxis("MouseY")*speed;
rot.x -= mouseY;
rot.y += mouseX;
rot.z = 0;
transform.eulerAngles = rot;
}
}
//二:
public class FirstPersonCamera : MonoBehaviour {
public float speed = 20;
private Vector3 rot = Vector3.zero;
void Start () {
}
void Update () {
float mouseX = Input.GetAxis("Mouse X") * speed;
float mouseY = Input.GetAxis("Mouse Y") * speed;
rot.x -= mouseY;
rot.y += mouseX;
rot.z = 0;
rot.x = Mathf.Clamp(rot.x, -20, 120);//旋转范围限制
transform.eulerAngles = rot;
}
}
11. 暂停游戏时time.scaletime等于0时,内置函数有什么变化?
(1)物理模拟. FixedUpdate - 当Time.timeScale=0时,FixedUpdate 函数不会被执行。
(2) Coroutines. - Time.timeScale=0 协程函数不会停止,但是会停止WaitForSeconds. 协成函数还是会每一帧都触发,但是WaitForSeconds使用的是当前的Time.deltaTime会变成0
(3) Invoke 和 InvokeRepeating. -延迟一段时间后调用指定函数.
(4)Particle System 粒子系统.
(5)Animations. -动画. 如果我们使用的是Animator,可以设置动画忽略Time.timeScale带来的影响. 只需要把UpdateMode设置为UnScaled Time。
12. 物体发生碰撞的必要条件
(1)两个物体都必须带有碰撞器。
(2)其中一个物体还必须带有刚体。
(3)两个物体有相对的位移。
但是有几点需要特别说明和补充的:
(4)尽量让运动的物体带有刚体,否则在Scene视图下的手动拖拽可能产生不了碰撞,但在Game视图没有问题。
(5)运动的物体带有刚体是因为运动时我们可以使用Rigidbody中的方法来让物体移动而不是transform.Translate方法(做物理游戏时是必须的)。
|