Unity八股总结
这里写目录标题
- OnEnable、Awake、Start运行时的发生顺序?哪些可能在同一个对象周期中反复的发生?
- 动态加载资源的方式?
- Unity3d脚本从唤醒到销毁有着一套比较完整的生命周期,请列出系统自带的几个重要的方法。
- 物理更新一般放在哪个系统函数里?
- 请简述如何在不同分辨率下保持UI的一致性
- 简述四元数的作用,四元数对欧拉⻆的优点?
- 画布的三种模式.缩放模式
- 异步加载
- shader基础
- 协程
OnEnable、Awake、Start运行时的发生顺序?哪些可能在同一个对象周期中反复的发生?
答:Awake–>OnEnable->Start
OnEnable在同一周期中可以反复地发生!
动态加载资源的方式?
instantiate:最简单的一种方式,以实例化的方式动态生成一个物体。
Assetsbundle:即将资源打成 asset bundle 放在服务器或本地磁盘,然后使用WWW模块get 下来,然后从这个bundle中load某个object,unity官方推荐也是绝大多数商业化项目使用的一种方式。
Resource.Load:可以直接load并返回某个类型的Object,前提是要把这个资源放在Resource命名的文件夹下,Unity不管有没有场景引用,都会将其全部打入到安装包中
AssetDatabase.loadasset :这种方式只在editor范围内有效,游戏运行时没有这个函数,它通常是在开发中调试用的。
Unity3d脚本从唤醒到销毁有着一套比较完整的生命周期,请列出系统自带的几个重要的方法。
Unity生命周期
答:Awake——>Start——>Update——>FixedUpdate——>LateUpdate——>OnGUI——>OnDisable——>OnDestroy
主要执行顺序
编辑器->初始化->物理系统->输入事件->游戏逻辑->场景渲染->GUI渲染->物体激活或禁用->销毁物体->应用结束
主要函数介绍
- Reset 是在用户点击检视面板的Reset按钮或者首次添加该组件时被调用。此函数只在编辑模式下被调用。Reset最常用于在检视面板中给定一个最常用的默认值。
- Awake 用于在游戏开始之前初始化变量或游戏状态。在脚本整个生命周期内它仅被调用一次.Awake在所有对象被初始化之后调用,所以你可以安全的与其他对象对话或用诸如 GameObject.FindWithTag 这样的函数搜索它们。每个游戏物体上的Awke以随机的顺序被调用。因此,你应该用Awake来设置脚本间的引用,并用Start来传递信息 ,Awake总是在Start之前被调用。它不能用来执行协同程序。
- OnDisable 不能用于协同程序。当对象变为不可用或非激活状态时此函数被调用。
- Start 在behaviour的生命周期中只被调用一次。它和Awake的不同是Start只在脚本实例被启用时调用。你可以按需调整延迟初始化代码。Awake总是在Start之前执行。这允许你协调初始化顺序。
- FixedUpdate 当MonoBehaviour启用时,其在每一帧被调用。处理Rigidbody时,需要用FixedUpdate代替Update。例如:给刚体加一个作用力时,你必须应用作用力在FixedUpdate里的固定帧,而不是Update中的帧。(两者帧长不同)。
- OnTriggerEnter 可以被用作协同程序,在函数中调用yield语句。当Collider(碰撞体)进入trigger(触发器)时调用OnTriggerEnter。
- OnCollisionEnter 相对于OnTriggerEnter,传递的是Collision类而不是Collider。Collision包含接触点,碰撞速度等细节。如果在函数中不使用碰撞信息,省略collisionInfo参数以避免不必要的运算。注意如果碰撞体附加了一个非动力学刚体,只发送碰撞事件。可以被用作协同程序。
当鼠标在GUIElement(GUI元素)或Collider(碰撞体)上点击时调用OnMouseDown。 - Update 是实现各种游戏行为最常用的函数。
- yield 一个协同程序在执行过程中,可以在任意位置使用yield语句。yield的返回值控制何时恢复协同程序向下执行。协同程序在对象自有帧执行过程中堪称优秀。协同程序在性能上没有更多的开销。StartCoroutine函数是立刻返回的,但是yield可以延迟结果。直到协同程序执行完毕。
- LateUpdate 是在所有Update函数调用后被调用。这可用于调整脚本执行顺序。例如:当物体在Update里移动时,跟随物体的相机可以在LateUpdate里实现。
- 渲染和处理GUI事件时调用。这意味着你的OnGUI程序将会在每一帧被调用。要得到更多的GUI事件的信息查阅Event手册。如果Monobehaviour的enabled属性设为false,OnGUI()将不会被调用。
- OnApplicationQuit,当用户停止运行模式时在编辑器中调用。当web被关闭时在网络播放器中被调用。
物理更新一般放在哪个系统函数里?
FixedUpdate,每固定帧绘制时执行一次,和Update不同的是FixedUpdate是渲染帧执行,如果你的渲染效率低下的时候FixedUpdate调用次数就会跟着下降。
FixedUpdate比较适用于物理引擎的计算,因为是跟每帧渲染有关。 Update就比较适合做控制。
请简述如何在不同分辨率下保持UI的一致性
多屏幕分辨率下的UI布局一般考虑两个问题:
布局元素的位置,即屏幕分辨率变化的情况下,布局元素的位置可能固定不动,导致布局元素可能超出边界;
布局元素的尺寸,即在屏幕分辨率变化的情况下,布局元素的大小尺寸可能会固定不变,导致布局元素之间出现重叠等功能。
为了解决这两个问题,在Unity GUI体系中有两个组件可以来解决问题,分别是布局元素的Rect Transform和Canvas的Canvas Scaler组件。
简述四元数的作用,四元数对欧拉⻆的优点?
四元数⽤于表示旋转,对旋转⻆度进⾏计算时⽤到四元数
相对欧拉⻆的优点:
1)能进⾏增量旋转
2)避免万向锁
3)给定⽅位的表达⽅式有两种,互为负(欧拉⻆有⽆数种表达⽅式)
画布的三种模式.缩放模式
屏幕空间-覆盖模式(Screen Space-Overlay),Canvas创建出来后,默认就是该模式,该模式和摄像机无关,即使场景内没有摄像机,UI游戏物体照样渲染
- 屏幕空间:电脑或者手机显示屏的2D空间,只有x轴和y轴
- 覆盖模式:UI元素永远在3D元素的前面
屏幕空间-摄像机模式(Screen Space-Camera),设置成该模式后需要指定一个摄像机游戏物体,指定后UGUI就会自动出现在该摄像机的“投射范围”内,和NGUI的默认UI Root效果一致,如果隐藏掉摄像机,UGUI当然就无法渲染
世界空间模式(WorldSpace),设置成该模式后UGUI就相当于是场景内的一个普通的“Cube 游戏模型”,可以在场景内任意的移动UGUI元素的位置,通常用于怪物血条显示和VR开发
Constant Pixel Size、Constant Physical Size实际上他们本质是一样的,只不过 Constant Pixel Size 通过逻辑像素大小调节来维持缩放,而 Constant Physical Size 通过物理大小调节来维持缩放。
异步加载
异步加载是在 Unity 中用于优化游戏性能的一种技术,主要目的是在不阻塞主线程的情况下加载资源。它允许游戏在后台进行资源加载,以保证用户界面的流畅性。
使用场景:常见于场景切换、资源加载(如音频、纹理、模型等)。
实现方式:
使用 AsyncOperation 类,如 SceneManager.LoadSceneAsync() 来异步加载场景。
对于其他资源,可以使用 Resources.LoadAsync() 或 Addressables 系统,通过异步方式加载资源。
shader基础
Shader 是一种程序,用来描述物体表面的外观,影响光照与渲染效果。在 Unity 中,Shader 主要分为两类:Surface Shaders 和 Vertex/Fragment Shaders。
-
Surface Shaders:简化了光照计算,适合常规材料的定义。开发者只需定义一些属性(如颜色、纹理等),Unity 会自动处理光照。
-
Vertex/Fragment Shaders:提供更精细的控制,允许开发者自定义顶点和片段处理,适合复杂的视觉效果。
协程
Unity 协程(Coroutine)到底是什么?