当前位置: 首页 > 工具软件 > Unity3D > 使用案例 >

unity 3d

章增
2023-12-01

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方法(做物理游戏时是必须的)。

 类似资料: