首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Unity面试篇】Unity 面试题总结甄选 |Unity进阶篇 | ❤️持续更新❤️

【Unity面试篇】Unity 面试题总结甄选 |Unity进阶篇 | ❤️持续更新❤️

作者头像
呆呆敲代码的小Y
发布于 2023-07-24 09:00:03
发布于 2023-07-24 09:00:03
3.4K00
代码可运行
举报
运行总次数:0
代码可运行

前言

  • 关于Unity面试题相关的所有知识点:🐱‍🏍2023年Unity面试题大全,共十万字面试题总结【收藏一篇足够面试,持续更新】
  • 为了方便大家可以重点复习某个模块,所以将各方面的知识点进行了拆分并更新整理了新的内容,并对之前的版本中有些模糊的地方进行了纠正。
  • 进阶篇中有些题目在基础篇已经有了,这里划分模块时有些会再加一遍用于加深印象学习。
  • 所以本篇文章就来整理一下Unity进阶篇的面试题,说不准就会面试的时候就会遇到!

🧡Unity进阶知识面试篇

💛物理系统

1. CharacterController和Rigidbody的区别

Rigidbody具有完全真实物理的特性,⽽CharacterController可以说是受限的 Rigidbody,具有⼀定的物理效果但不是完全真实的。

2. 射线检测碰撞物的原理是?

答:射线是3D世界中一个点向一个方向发射的一条无终点的线,在发射轨迹中与其他物体发生碰撞时,它将停止发射 。

3. 什么叫做链条关节?

Hinge Joint,可以模拟两个物体间用一根链条连 接在一起的情况,能保持两个物体在一个固定距 离内部相互移动而不产生作用力,但是达到固定 距离后就会产生拉力。

4. 物体发生碰撞的必要条件?

两个物体都必须带有碰撞器Collider,其中一个物体还必须带有Rigidbody刚体

5. 在物体发生碰撞的整个过程 中,有几个阶段,分别列出对 应的函数 三个阶段
  1. OnCollisionEnter
  2. OnCollisionStay
  3. OnCollis ionExit
6. Unity3d中的碰撞器和触发器的 区别?

碰撞器是触发器的载体,而触发器只是碰撞器身 上的一个属性。

当Is Trigger=false时,碰撞器根据物理引擎引发 碰撞,产生碰撞的效果,可以调用 OnCollisionEnter/Stay/Exit函数; 当Is Trigger=true时,碰撞器被物理引擎所忽略, 没有碰撞效果,可以调用OnTriggerEnter/Stay/ Exit函数。

如果既要检测到物体的接触又不想让碰撞检测影 响物体移动或要检测一个物件是否经过空间中的 某个区域这时就可以用到触发器

7. 射线检测碰撞物的原理是?

射线是3D世界中一个点向一个方向发射的一条无 终点的线,在发射轨迹中与其他物体发生碰撞 时,它将停止发射 。

8. 射线Raycast原理

从一个起点向一个方向发射一条物理射线,返回碰撞到的物体的碰撞信息

9. Unity3d的物理引擎中,有几种 施加力的方式,分别描述出来
  • rigidbody.AddForce;
  • rigidbody.AddForceAtPosition;

都在 rigidbody系列函数中。

10. 当一个细小的高速物体撞向另一个较大的物体时,会出现什么情况?如何避免?

穿透(碰撞检测失败)

11. 物理更新一般放在哪个系统函数里?

FixedUpdate,每固定帧绘制时执行一次,和Update不同的是FixedUpdate是渲染帧执行,如果你的渲染效率低下的时候FixedUpdate调用次数就会跟着下降。

FixedUpdate比较适用于物理引擎的计算,因为是跟每帧渲染有关。 Update就比较适合做控制。


💚UI & 2D 部分

1. UGUI 合批的一些问题

简单来说在一个Canvas下,需要相同的material,相同的纹理以及相同的Z值。例如UI上的字体Texture使用的是字体的图集,往往和我们自己的UI图集不一样,因此无法合批。还有UI的动态更新会影响网格的重绘,因此需要动静分离。

2. Image和RawImage的区别
  • Imgae比RawImage更消耗性能
  • Image只能使用Sprite属性的图片,但是RawImage什么样的都可以使用
  • Image适合放一些有操作的图片,裁剪平铺旋转什么的,针对Image Type属性
  • RawImage就放单独展示的图片就可以,性能会比Image好很多
3. 使用Unity3d实现2d游戏,有几种方式?
  1. 使用本身UGUI,UGUI是duUnity官方推出zhi的最新UI系统,UI就是UserInterface。
  2. 把摄像机的投影改为正交投影,不考虑Z轴.
  3. 使用Untiy自身的2D模式,在2d模式中,层级视图中只有一个正交摄像机,场景视图选择的是2D模式。
  4. 使用2D TooKit插件,2D Toolkit是一组与Unity环境无缝集成的工具,提供高效的2D精灵和文本系统。
4. 将图片的TextureType选项分别选为Texture和Sprite有什么区别

Sprite作为UI精灵使用,Texture作用模型贴图使用。

5. 请简述如何在不同分辨率下保 持UI的一致性

多屏幕分辨率下的UI布局一般考虑两个问题:

  1. 布局元素的位置,即屏幕分辨率变化的情况下,布局元素的位置可能固定不动,导致布局元素可能超出边界;
  2. 布局元素的尺寸,即在屏幕分辨率变化的情况下,布局元素的大小尺寸可能会固定不变,导致布局元素之间出现重叠等功能。

为了解决这两个问题,在Unity UGUI体系中有两个组件可以来解决问题,分别是布局元素的Rect Transform和Canvas的Canvas Scaler组件。

CanvasScaler中UI Scale Mode有三种模式,Constant Pixel Size、Scale With Screen Size、Constant Physical Size,其中第二个就是根据屏幕分辨率来进行缩放适配。在这个模式下,有两个参数,一个是我们在开发过程中的标准分辨率,一个是屏幕的匹配模式,通过这里面的设置,就可以完成多分辨率下的适配问题。

6. 画布的三种模式.缩放模式
  • 屏幕空间-覆盖模式(Screen Space-Overlay),Canvas创建出来后,默认就是该模式,该模式和摄像机无关,即使场景内没有摄像机,UI游戏物体照样渲染
    • 屏幕空间:电脑或者手机显示屏的2D空间,只有x轴和y轴
    • 覆盖模式:UI元素永远在3D元素的前面
  • 屏幕空间-摄像机模式(Screen Space-Camera),设置成该模式后需要指定一个摄像机游戏物体,指定后UGUI就会自动出现在该摄像机的“投射范围”内,和NGUI的默认UI Root效果一致,如果隐藏掉摄像机,UGUI当然就无法渲染
  • 世界空间模式(WorldSpace),设置成该模式后UGUI就相当于是场景内的一个普通的“Cube 游戏模型”,可以在场景内任意的移动UGUI元素的位置,通常用于怪物血条显示和VR开发

缩放模式:

Property:

Function:

UI Scale Mode

Canvas中UI元素的缩放模式

Constant Pixel Size

使UI保持自己的尺寸,与屏幕尺寸无关。

Scale With Screen Size

屏幕尺寸越大,UI越大

Constant Physical Size

使UI元素保持相同的物理大小,与屏幕尺寸无关。

Constant Pixel Size、Constant Physical Size实际上他们本质是一样的,只不过 Constant Pixel Size 通过逻辑像素大小调节来维持缩放,而 Constant Physical Size 通过物理大小调节来维持缩放。

7. Text 和 TMPText的区别 优缺点

Text是像素渲染放大之后就会模糊,使用Text父物体的放大缩小会影响子物体Text的清晰度, TMPText不会,它是网格渲染TMPText会把字体生成一个类似于贴图的东西然后读取贴图的坐标来获取对应的文字,更换文字的消耗会比Text大。 TMPText更适用于不会变动的文字,特别是在量大的情况下,性能比Text高一些,需要经常变动的问题用Text好点,TMPText在字体库很大的情况下查找更换会比较慢。


💙动画系统

1. 请描述游戏动画有哪几种,以及其原理?

主要有关节动画、⻣骼动画、单一网格模型动画(关键 帧动画)。

  • 关节动画:把⻆色分成若干独立部分,一个 部分对应一个网格模型,部分的动画连接成一个整体 的动画,⻆色比较灵活,Quake2中使用这种动画;
  • ⻣骼动画,广泛应用的动画方式,集成了以上两个方 式的优点,⻣骼按⻆色特点组成一定的层次结构,有 关节相连,可做相对运动,皮肤作为单一网格蒙在⻣ 骼之外,决定⻆色的外观;
  • 单一网格模型动画由一个完整的网格模型构成,在动 画序列的关键帧里记录各个顶点的原位置及其改变量,然后插值运算实现动画效果,⻆色动画较真实。
2. Avator的作用

用户提供的模型骨架和Unity的骨架结构进行适配,是一种骨架映射关系。 方便动画的重定向

AnimationType有三种类型 Humanoid人型:可以动画重定向,游戏对象挂载animator,子类原始模型+重定向模型,设置原始模型和使用模型的AnimationType为Humanoid类型 Generic非人型 Legacy旧版 Avator Mask身体遮罩,身体某一部分是否受到动画影响 反向动力学 IK,通过手或脚来控制身体其他部分

3. 反向旋转动画的方法是什么?
  1. 将动画速度调成-1
  2. 改代码animation.speed=-1
4. Animation.CrossFade 是什么?

动画淡入淡出

5. 写出 Animation 的五个方法
  • AddClip 将 clip 添加到名称为 newName 的动画中。
  • Blend 在后续 time 秒中将名称为 animation 的动画向 targetWeight 混合。
  • CrossFade 在后续 time 秒的时间段内,使名称为 animation 的动画淡入,使其他动画淡出。
  • CrossFadeQueued 使动画在上一个动画播放完成后交叉淡入淡出。
  • IsPlaying 名称为 name 的动画是否正在播放?
  • PlayQueued 在先前的动画播放完毕后再播放动画。
  • RemoveClip 从动画列表中移除剪辑。
  • Sample 对当前状态的动画进行采样。
  • Stop 停止所有使用该动画启动的正在播放的动画。
6. 简述 SkinnedMesh 的实现原理

SkinnedMesh蒙皮网格动画 分为骨骼和蒙皮两部分 骨骼是一个层次结构,存储了骨骼的Transform数据 蒙皮是mesh顶点附着在骨骼之上,顶点可以被多个骨骼影响,决定了其权重等, 还有将顶点从Mesh空间变换到骨骼空间~

7. 动画层(Animation Layers)的作用是什么?

动画分层

身体部位动画分层,比如我只想动动头,身体其他部分不发生动画,可以方便处理动画区分

8. Animation和Animator的区别

Animation和Animator 虽然都是控制动画的播放,但是它们的用法和相关语法都是大有不同的。Animation控制一个动画的播放,而Animator是多个动画之间相互切换,并且Animator有一个动画控制器,俗称动画状态机。

Animator利用它做动画的切换是很方便的,但是它有一个缺点就是占用内存比Animation大。


💜协程

1. 简述进程、线程、协程的概念

进程

  • 保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己独立的地址空间,有自己的堆,不同进程间可以进行进程间通信,上级挂靠单位是操作系统。一个应用程序相当于一个进程,操作系统会以进程为单位,分配系统资源(CPU 时间片、内存等资源),进程是资源分配的最小单位。

线程

  • 线程从属于进程,也被称为轻量级进程,是程序的实际执行者。线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条- 线程并行执行不同的任务。一个线程只有一个进程。
  • 每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
  • 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的)。

协程

  • 协程是伴随着主线程一起运行的一段程序。
  • 协程与协程之间是并行执行,与主线程也是并行执行,同一时间只能执行一个协程提起协程,自然是要想到线程,因为协程的定义就是伴随主线程来运行的。
  • 一个线程可以拥有多个协程,协程不是被操作系统内核所管理,而完全是由程序所控制。
  • 协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。
  • 协成是单线程下由应用程序级别实现的并发。
2. 简述协程的作用

在Unity中只有主线程才能访问Unity3D的对象、方法、组件。当主线程在执行一个对资源消耗很大的操作时,在这一帧我们的程序就会出现帧率下降,画面卡顿的现象!

那这个时候我们就可以利用协程来做这件事,因为协程是伴随着主线程运行的,主线程依旧可以丝滑轻松的工作,把脏活累活交给协程处理就好了!简单来说:协程是辅助主线程的操作,避免游戏卡顿。

3. 简述协程的底层原理
  • 协程是通过迭代器来实现功能的,通过关键字IEnumerator来定义一个迭代方法。
  • StartCoroutine 接受到的是一个 IEnumerator ,这是个接口,并且是枚举器或迭代器的意思。
  • yield 是 C#的一个关键字,也是一个语法糖,背后的原理会生成一个类,并且也是一个枚举器,而且不同于 return,yield 可以出现多次。
  • yield 实际上就是返回一次结果,因为我们要一次一次枚举一个值出来,所以多个 yield 其实是个状态模式,第一个 yield 是状态 1,第二个 yield 是状态 2,每次访问时会基于状态知道当前应该执行哪一个 yield,取得哪一个值。

从程序的角度讲,协程的核心就是迭代器。 想要定义一个协程方法有两个因素,第一:方法的返回值为 IEnumerator 。第二,方法中有 yield关键字。 当代码满足以上两个条件时,此方法的执行就具有了迭代器的特质,其核心就是 MoveNext方法。 方法内的内容将会被分成两部分:yield 之前的代码和 yield 之后的代码。yield之前的代码会在第一次执行MoveNext时执行, yield之后的代码会在第二次执行MoveNext方法时执行。 而在Unity中,MoveNext的执行时机是以帧为单位的,无论你是设置了延迟时间,还是通过按钮调用MoveNext,亦或是根本没有设置执行条件,Unity都会在每一帧的生命周期中判断当前帧是否满足当前协程所定义的条件,一旦满足,当前帧就会抽出CPU时间执行你所定义的协程迭代器的MoveNext。 注意,只要方法中有yield语句,那么方法的返回值就必须是 IEnumerator ,不然无法通过编译。

4. 线程与协程的区别
  • 协程:即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态。协程实际上是在一个线程中,只不过每个协程对CPU进行分时,协程可以访问和使用unity的所有方法和component。同一时间只能执行某个协程。开辟多个协程开销不大。协程适合对某任务进行分时处理。
  • 线程:多线程是阻塞式的,每个IO都必须开启一个新的线程,但是对于多CPU的系统应该使用thread,尤其是有大量数据运算的时刻,但是IO密集型就不适合;而且thread中不能操作unity的很多方法和component。同一时间可以同时执行多个线程。开辟多条线程开销很大。线程适合多任务同时处理。

线程和协同程序的主要不同在于:在多处理器情况下,从概念上来讲多线程程序同时运行多个线程;而协同程序是通过协作来完成,在任一指定时刻只有一个协同程序在运行,并且这个正在运行的协同程序只在必要时才会被挂起。

5. 协同程序的执行代码是什么?有何用处,有何缺点?
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
官方案例)
function Start() {
// - After 0 seconds, prints "Starting 0.0"
// - After 0 seconds, prints "Before WaitAndPrint
Finishes 0.0"
// - After 2 seconds, prints "WaitAndPrint 2.0" // 先打印"Starting 0.0"和"Before WaitAndPrint
Finishes 0.0"两句,2秒后打印"WaitAndPrint 2.0" print ("Starting " + Time.time );
// Start function WaitAndPrint as a coroutine. And continue execution while it is running
// this is the same as WaintAndPrint(2.0) as the compiler does it for you automatically
// 协同程序WaitAndPrint在Start函数内执行,可以视 同于它与Start函数同步执行.
StartCoroutine(WaitAndPrint(2.0));
print ("Before WaitAndPrint Finishes " + Time.time );
}
function WaitAndPrint (waitTime : float) {
// suspend execution for waitTime seconds // 暂停执行waitTime秒
yield WaitForSeconds (waitTime);
print ("WaitAndPrint "+ Time.time );
}

启动协程

  1. Startcoroutine(string methodName):通过协程的方法名(字符串形式)启动。
  2. StartCoroutine(string methodName,object values):带参数的通过方法名(字符串形式)进行调用。
  3. Startcoroutine(IEnumerator routine):通过调用方法的形式启动。

停止协程

  1. stopcoroutine (string methodName):通过方法名(字符串)来关闭协程。
  2. stopCoroutine(IEnumerator routine):通过调用方法的形式来关闭协程。
  3. stopCoroutine(Coroutine routine):通过指定的协程来关闭。
  4. stopAllCoroutine() :作用是停止所有该脚本中启动的协程。

作用:一个协同程序在执行过程中,可以在任意位置使 用yield语句。yield的返回值控制何时恢复协同程序向 下执行。协同程序在对象自有帧执行过程中堪称优 秀。协同程序在性能上没有更多的开销。 缺点:协同程序并非真线程,可能会发生堵塞。

更多协程内容:Unity零基础到入门 ☀️| 小万字教程 对 Unity 中的 协程 ❤️全面解析+实战演练❤️


🤎数据持久化 & 资源管理

1. unity常用资源路径有哪些
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//获取的目录路径最后不包含  /
//获得的文件路径开头包含 /
Application.dataPath; //Asset文件夹的绝对路径
//只读
Application.streamingAssetsPath;  //StreamingAssets文件夹的绝对路径(要先判断是否存在这个文件夹路径)
Application.persistentData ; //可读写

//资源数据库 (AssetDatabase) 是允许您访问工程中的资源的 API
AssetDatabase.GetAllAssetPaths; //获取所有的资源文件(不包含meta文件)
AssetDatabase.GetAssetPath(object) //获取object对象的相对路径
AssetDatabase.Refresh(); //刷新
AssetDatabase.GetDependencies(string); //获取依赖项文件


Directory.Delete(p, true); //删除P路径目录
Directory.Exists(p);  //是否存在P路径目录
Directory.CreateDirectory(p); //创建P路径目录

AssetDatabase //类库,对Asset文件夹下的文件进行操作,获取相对路径,获取所有文件,获取相对依赖项
Directory //类库,相关文件夹路径目录进行操作,是否存在,创建目录,删除等操作
2. 如何安全的在不同工程间安全 地迁移asset数据?三种方法
  1. 将Assets目录和Library目录一起迁移
  2. 导出包
  3. 用unity自带的assets Server功能
3. unity 提供了一个用于保存读取数据的类,(playerPrefs),请列出保存读取整形数据的函数

PlayerPrefs类是一个本地持久化保存与读取数据的类 PlayerPrefs类支持3中数据类型的保存和读取,浮点型,整形,和字符串型。

分别对应的函数为:

SetInt();保存整型数据;GetInt();读取整形数据; SetFloat();保存浮点型数据; GetFlost();读取浮点型数据; SetString();保存字符串型数据; GetString();读取字符串型数据;

4. 动态加载资源的方式?
  • instantiate:最简单的一种方式,以实例化的方式动态生成一个物体。
  • Assetsbundle:即将资源打成 asset bundle 放在服务器或本地磁盘,然后使用WWW模块get 下来,然后从这个bundle中load某个object,unity官方推荐也是绝大多数商业化项目使用的一种方式。
  • Resource.Load:可以直接load并返回某个类型的Object,前提是要把这个资源放在Resource命名的文件夹下,Unity不管有没有场景引用,都会将其全部打入到安装包中
  • AssetDatabase.loadasset :这种方式只在editor范围内有效,游戏运行时没有这个函数,它通常是在开发中调试用的。
5. AssetsBundle 打包
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using UnityEditor;
using System.IO;

public class CreateAssetBundles //进行AssetBundle打包
{

    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
 {
    string dir = "AssetBundles";
    if (Directory.Exists(dir) == false)
    {
      Directory.CreateDirectory(dir);
    }
    
    BuildPipeline.BuildAssetBundles(dir, //路径必须创建
    BuildAssetBundleOptions.ChunkBasedCompression, //压缩类型***
    BuildTarget.StandaloneWindows64);//平台***
 }
}

None

Build assetBundle without any special option.(LAMA压缩,压缩率高,解压久)

UncompressedAssetBundle

Don’t compress the data when creating the asset bundle.(不压缩,解压快)

ChunkBasedCompression

Use chunk-based LZ4 compression when creating the AssetBundle.

(压缩率比LZMA低,解压速度接近无压缩)|

6. AssetBundle加载
  1. LoadFromMemory(LoadFromMemoryAsync)
  2. LoadFromFile(LoadFromFileAsync)
  3. UnityWebRequest
  4. LoadAssetsByWWW(LoadFromCacheOrDownload)

第一种

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
IEnumerator Start()
{
  string path = "AssetBundles/wall.unity3d";

  AssetBundleCreateRequest request =AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));

  yield return request;
  
  AssetBundle ab = request.assetBundle;
  
  GameObject wallPrefab = ab.LoadAsset<GameObject>("Cube");
  
  Instantiate(wallPrefab);
}

第二种

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
IEnumerator Start()
{
string path = "AssetBundles/wall.unity3d";

  AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);

  yield return request;

  AssetBundle ab = request.assetBundle;

  GameObject wallPrefab = ab.LoadAsset<GameObject>("Cube");

  Instantiate(wallPrefab);
}

第三种

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
IEnumerator Start()
{

  string uri = @"http://localhost/AssetBundles/cubewall.unity3d";

  UnityWebRequest request =   UnityWebRequest.GetAssetBundle(uri);

  yield return request.Send();

  AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);

  GameObject wallPrefab = ab.LoadAsset<GameObject>("Cube");

  Instantiate(wallPrefab);
}

第四种WWW(无依赖)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private IEnumerator LoadNoDepandenceAsset()
    {
        string path = "";
        
        if (loadLocal)
        {
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
            path += "File:///";
#endif
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
            path += "File://";
#endif
            path += assetBundlePath + "/" + assetBundleName;
            
            //www对象
            WWW www = new WWW(path);
 
            //等待下载【到内存】
            yield return www;
 
            //获取到AssetBundle
            AssetBundle bundle = www.assetBundle;
 
            //加载资源
            GameObject prefab = bundle.LoadAsset<GameObject>(assetRealName);
 
            //Test:实例化
            Instantiate(prefab);
        }

第四种WWW(有依赖)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
 
public class LoadAssetsDemo : MonoBehaviour
{
    [Header("版本号")]
    public int version = 1;
    
    [Header("加载本地资源")]
    public bool loadLocal = true;
    [Header("资源的bundle名称")]
    public string assetBundleName;
    [Header("资源的真正的文件名称")]
    public string assetRealName;
    
    //bundle所在的路径
    private string assetBundlePath;
    //bundle所在的文件夹名称
    private string assetBundleRootName;
 
    private void Awake()
    {
        assetBundlePath = Application.dataPath + "/OutputAssetBundle";
        assetBundleRootName = assetBundlePath.Substring(assetBundlePath.LastIndexOf("/") + 1);
        
        Debug.Log(assetBundleRootName);
    }
 
IEnumerator LoadAssetsByWWW()
 
{
   string path="";
//判断是不是本地加载
   if(loadLocal)// loadLocal=true为本地资源
   {
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
        path+="File:///";
#endif
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
        path+="File://";
#edif
   }
    //获取要加载的资源路径【bundle的总说明文件】
   path+=assetBundle+"/"+assetBundleRootName;
   //加载
   WWW www=WWW.LoadFromCacheOrDownload(path,version);
   yield return www;
   //拿到其中的bundle
   AssetBundle manifestBundle=www.assetsBundle;
   //获取到说明文件
   AssetBundleManifest manifest=manifest.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
   //获取资源的所有依赖
   string[] dependencies=manifest.GetAllDependencies(assetBundleName);
   //卸载Bubdle和解压出来的manifest对象
   manifestBundle.Unload(true);
   //获取到相对路径
   path =path.Remove(path.LastIndexOf("/")+1);
   //声明依赖的Bundle数组
   AssetBundle[] depAssetBundle=new AssetBundle[dependencies.Length];
   
   //遍历加载所有的依赖
   for(int i=0;i<dependencies.Length;i++)
{  //获取到依赖Bundle的路径
   string depPath=path+ dependencies[i];
   //获取新的路径进行加载
   www=WWW.LoadFromCacheOrDownload(depPath,version);
   yield return www;
   //将依赖临时保存
   depAssetBundles[i]=www.assetsBundle;
 
}
   //获取路径
   path+=assBundleName;
   //加载最终资源
   www=WWW.LoadFromCacheOrDownload(path,version);
   //等待下载
   yield return www;
   //获取到真正的AssetBundle
   AssetBundle realAssetBundle=www.assBunle;
   //加载真正的资源
   GameObject prefab=realAssetBundle.LoadAsset<GameObject>(assetBundle);
   //生成
   Instantiate(prefab);
 
   //卸载依赖
   for(int i-0;i<depAssetBundle.Length;i++)
{
   depAssetBundle[i].Unload(true);
}
   realAssetBundle.Unload(true);
}
 
}
7. AssetBundle卸载流程

AssetBundle.Unload(bool),T true卸载所有资源

false只卸载没使用的资源,而正在使用的资源与AssetBundle依赖关系会丢失,调用Resources.UnloadUnusedAssets可以卸载。

或者等场景切换的时候自动调用Resources.UnloadUnusedAssets。

8. ScriptableObejct

ScriptableObject是一个数据容器,它可以用来保存大量数据。

  • 主要的用处就是在项目中通过将数据存储在ScriptableObject对象,避免值拷贝来减少游戏运行中的内存占用。
  • 当你有一个预制体,上面挂了一个存有不变数据的MonoBehaviour 脚本时,每次我们实例化预制体时都将产生一次数据拷贝,这时我们可以使用ScriptableObject对象来存储数据,然后通过引用来访问预制体中的数据。这样可以避免在内存中产生一份拷贝数据。与MonoBehaviour 一样,ScriptableObject也继承自Unity基类object,但是与MonoBehaviour不同的是,ScriptableObject不能和GameObject对相关联,相反,通常我们会将它保存为Assets资源。
  • 在编辑器模式下,我们可以在编辑和运行时将数据保存到ScriptableObject,因为保存ScriptableObject需要用到编辑器空间个脚本,但是在开发模式下不能使用ScriptableObject来保存数据,但是你可以使用ScriptableObject资源中已保存的数据。

更多详细内容可以看下面文章:Unity零基础到进阶 | Unity中Scriptable Object介绍学习




👥总结

  • 全网最全的 Unity进阶篇 面试题都在这里了,希望本篇文章能够让你在面试关卡如鱼得水得到自己想要的工作。
  • 看完觉得有用别忘了点赞收藏哦,如果觉得哪个方面的内容不够丰富欢迎在评论区指出!
  • 如果你的Unity基础知识还不够熟练,也欢迎来 『Unity精品学习专栏⭐️』『Unity 实战100例 教程⭐️』继续学习哦!
  • 如果你还有更好的面试题,欢迎在评论区提出,会整理到文章中去哦!!!
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Suno AI 人人都能成为创作型歌手
2024年3月22日,Suno AI正式发布新版本V3 。目前使用Suno几乎没有任何技术门槛,可以纯粹的通过选择曲风、输入歌词来完成一首歌的创作。接下来这句话直接点,大家可以无门(梯)槛(子)直接打开试试:https://app.suno.ai/
AI科技评论
2024/04/11
6060
Suno AI 人人都能成为创作型歌手
【01】AI制作音乐之三款AI音乐软件推荐,包含AI编曲-AI伴奏-AI混音合成remix等-其次关于音乐版权的阐述-跟随卓伊凡学习如何AI制作音乐
本文是由于最近做视频发现有些配动漫的音乐很难听,至少个人觉得不好听,因此打算再做一些混音,也或者用AI做一些原创音乐,因此本文开始了,接下来可以跟我一步步制作。
卓伊凡
2025/03/06
1.9K1
手把手教你用最新的AI音乐模型,创造一首属于你自己的歌。
跟我说,他们的新音乐模型Mureka v7马上要上线了,他们觉得质量能跟Suno 4.5打一打,而且也是国内为数不多的AI音乐产品,问我要不要一拍即合一下。
数字生命卡兹克
2025/07/24
1740
手把手教你用最新的AI音乐模型,创造一首属于你自己的歌。
当AI视频进入「Q时代」:Vidu Q1如何以双榜第一掀起创作革命?
2025年4月,全球AI视频生成领域迎来历史性时刻——生数科技推出的Vidu Q1在权威测评榜单VBench-1.0文生视频与VBench-2.0图生视频中同时登顶,并以绝对优势超越OpenAI Sora、Runway等国际顶尖模型。与此同时,在国内SuperCLUE的动漫与写实风格图生视频榜单中,Vidu Q1同样斩获双冠。这款以“质量”命名的模型,不仅将AI视频生成推向“电影级工业化”新高度,更以每秒0.3元的超低价格打破技术门槛,让全民创作者得以释放想象力。本文将从产品技术突破、实操指南、行业对比三大维度,深度解析这款“国产之光”的颠覆性价值。
疯狂的KK
2025/04/24
6040
当AI视频进入「Q时代」:Vidu Q1如何以双榜第一掀起创作革命?
音乐界迎来自己的DeepSeek!全球首个音乐推理大模型Mureka O1上线,超越Suno
3 月 26 日,国内「All in AGI 与 AIGC」的科技公司 —— 昆仑万维,发布了最新音乐大模型 Mureka V6 和 O1,给全球音乐圈带来了不小的震撼。
机器之心
2025/03/27
2760
音乐界迎来自己的DeepSeek!全球首个音乐推理大模型Mureka O1上线,超越Suno
一手体验Suno v3.5版本,生成音乐的门槛再一次被AI拉低了。
昨天从深圳回家,上飞机前,顺手看了一眼X,忽然看到AI音乐界的“Chatgpt” - Suno悄悄放了一个视频。
数字生命卡兹克
2025/04/14
1530
一手体验Suno v3.5版本,生成音乐的门槛再一次被AI拉低了。
AI音乐的生成浪潮:技术科普、变革畅想与伦理应对
2023年被誉为「生成式AI元年」。2022年11月,OpenAI 发布以GPT-3.5 模型为内核的ChatGPT。ChatGPT涌现出了上下文学习、思维链等高度智能,被认为具有颠覆式的技术突破、跨领域的应用价值,AI Agent等衍生方向也被认为具有平台和入口级意义。以此为节点,大规模参数、大算力、「暴力求解」风格的大语言模型(LLM)开启了历时性进程。短短几月,大量AI创业公司和科技厂商纷纷入场,LLM领域进入百模大战。
小腾资讯君
2024/05/31
1.2K0
导演、编剧、特效师都要失业?生成式AI正在悄悄重塑影视工业
今天我们不聊数据库、不聊K8S,咱来聊聊生成式AI怎么在“悄悄地、温柔地、但又猛烈地”改变着影视行业。
Echo_Wish
2025/06/30
1630
导演、编剧、特效师都要失业?生成式AI正在悄悄重塑影视工业
一键生成歌曲,腾讯AI Lab开源音乐生成大模型 SongGeneration
6月20日,腾讯AI Lab推出并开源音乐生成大模型SongGeneration,专注解决AIGC音乐中音质、音乐性与生成速度这三大难题,基于LLM-DiT的融合架构,模型在保持生成速度的同时,显著提升了音质表现,生成歌曲准确度相较部分商业闭源模型表现出相当甚至更优的质量,同时在整体表现、旋律、伴奏、音质与结构等维度也优于现有多数开源模型。
腾讯开源
2025/06/24
8380
一键生成歌曲,腾讯AI Lab开源音乐生成大模型 SongGeneration
AI进乐队了,还要不要人写歌了?——聊聊AI在音乐创作里的那些事儿
嘿,朋友们,今天咱不聊代码、不聊大数据、不聊服务器宕机这类“工地现场”。咱今天轻松一点,来聊聊一件更“浪漫”的事儿——AI 是怎么改变音乐创作的。
Echo_Wish
2025/06/26
1310
AI进乐队了,还要不要人写歌了?——聊聊AI在音乐创作里的那些事儿
从 0 到 1,揭秘中国首个 AI 音乐 SOTA 模型
但音乐创作是一件门槛很高的事情,因为音乐创作不是某一个人的独角戏,而一个团队高度协作的过程。从作词、作曲到编曲、混音,再到歌曲录制,每个环节都需要专业音乐人付出努力,并伴随着高昂的成本投入。
AI科技评论
2024/04/26
1.4K0
从 0 到 1,揭秘中国首个 AI 音乐 SOTA 模型
AI文字生成视频工具:从国产到全球创新工具的深度解析
在短视频与影视创作领域,AI技术正以革命性的方式重构内容生产流程。本文将聚焦三款代表性工具——国产巨推管家AI、专业级影视工具Runway Gen-2,以及艺术风格创作平台Kaiber,通过技术拆解与场景化对比,为创作者提供选型参考。
西出长安三万里
2025/08/07
2360
AI文字生成视频工具:从国产到全球创新工具的深度解析
深夜网抑云,5 款 AI 助你自己写歌给自己听
AI音乐创作工具为音乐爱好者和专业人士打开了全新的创作大门,不仅大大简化了创作过程,还为创意注入了无限可能。通过AI的辅助,任何人都可以快速生成高质量的音乐作品,探索新的风格和编曲方式,打破传统创作的瓶颈。
AI科技评论
2024/05/22
9300
深夜网抑云,5 款 AI 助你自己写歌给自己听
国内首款AI音乐大模型一曲封神!核心技术业内首公开,爆改霉霉周杰伦效果惊艳
这不,就在上周,国内首款AI音乐生成大模型「天工SkyMusic」也正式开启内测了!
新智元
2024/04/12
3010
国内首款AI音乐大模型一曲封神!核心技术业内首公开,爆改霉霉周杰伦效果惊艳
孙燕姿回应成真?AI歌手音乐创作软件上线,人类怎么办?
文出自《我的 AI》,上月孙燕姿在社交平台回应自己对 “AI 孙燕姿” 的看法。此前,“AI 孙燕姿” 红遍网络,短短时间拥有超过 1000 首翻唱作品,远高过孙燕姿本人出道 23 年的作品总和。但因未获得本人授权,“AI 孙燕姿” 也饱受争议。
机器之心
2023/08/07
3080
孙燕姿回应成真?AI歌手音乐创作软件上线,人类怎么办?
【AI】『Suno』哎呦不错呦,AI界的周董,快来创作你的歌曲吧!
朋友说他练习时长两天半,用Suno发布了首张AI音乐专辑。震惊之余,第一反应是音乐圈门槛也这么低了,什么妖魔鬼怪都可以进军了嘛!
JavaDog程序狗
2024/10/15
2430
【AI】『Suno』哎呦不错呦,AI界的周董,快来创作你的歌曲吧!
顶级视频生成大模型分析:Seedance 1.0 Pro (字节跳动) - 新晋榜首
2025年,AI视频生成技术迎来了前所未有的发展高峰。从2024年2月OpenAI发布Sora开始,到如今的百花齐放,这个领域正在以前所未有的速度发展。目前市场上已有超过20款主流视频生成大模型,技术水平参差不齐,但顶级模型的能力已经接近专业级别。
蓝葛亮
2025/06/12
1.3K0
顶级视频生成大模型分析:Seedance 1.0 Pro (字节跳动) - 新晋榜首
生成式AI走进小学生「编程第一课」:画条线生成音乐、草图一秒变大作
在经典作品《小王子》中,有这样一幕情节:一个小孩子画下了蛇吞象的样子,他向大人们展示自己的作品,并问他们害不害怕。然而,所有的成年人都说:「一顶帽子有什么可怕的?」
机器之心
2023/09/08
4310
生成式AI走进小学生「编程第一课」:画条线生成音乐、草图一秒变大作
强大的AI网站推荐(第五集)—— Suno
先来欣赏一下我用它创作的歌曲吧,这可是我仅用 2 分钟就完成的,是不是感觉非常不错呢?
LucianaiB
2025/04/17
4110
强大的AI网站推荐(第五集)—— Suno
唱演视频爆火,AI 对口型工具成创作者刚需
现在各种唱演类视频火得一塌糊涂,不管是模仿明星唱歌,还是给动画角色配音演唱,都特别受大家欢迎。但很多人苦恼于自己对口型总是对不准,要么节奏差一点,要么表情不自然。这时候,AI 对口型唱演工具就派上大用场了,能帮我们轻松做出专业级的唱演视频。作为经常捣鼓这类视频的创作者,我用过不少相关工具,今天就来跟大家聊聊。
嘟嘟喂嘟嘟
2025/08/06
1210
唱演视频爆火,AI 对口型工具成创作者刚需
推荐阅读
Suno AI 人人都能成为创作型歌手
6060
【01】AI制作音乐之三款AI音乐软件推荐,包含AI编曲-AI伴奏-AI混音合成remix等-其次关于音乐版权的阐述-跟随卓伊凡学习如何AI制作音乐
1.9K1
手把手教你用最新的AI音乐模型,创造一首属于你自己的歌。
1740
当AI视频进入「Q时代」:Vidu Q1如何以双榜第一掀起创作革命?
6040
音乐界迎来自己的DeepSeek!全球首个音乐推理大模型Mureka O1上线,超越Suno
2760
一手体验Suno v3.5版本,生成音乐的门槛再一次被AI拉低了。
1530
AI音乐的生成浪潮:技术科普、变革畅想与伦理应对
1.2K0
导演、编剧、特效师都要失业?生成式AI正在悄悄重塑影视工业
1630
一键生成歌曲,腾讯AI Lab开源音乐生成大模型 SongGeneration
8380
AI进乐队了,还要不要人写歌了?——聊聊AI在音乐创作里的那些事儿
1310
从 0 到 1,揭秘中国首个 AI 音乐 SOTA 模型
1.4K0
AI文字生成视频工具:从国产到全球创新工具的深度解析
2360
深夜网抑云,5 款 AI 助你自己写歌给自己听
9300
国内首款AI音乐大模型一曲封神!核心技术业内首公开,爆改霉霉周杰伦效果惊艳
3010
孙燕姿回应成真?AI歌手音乐创作软件上线,人类怎么办?
3080
【AI】『Suno』哎呦不错呦,AI界的周董,快来创作你的歌曲吧!
2430
顶级视频生成大模型分析:Seedance 1.0 Pro (字节跳动) - 新晋榜首
1.3K0
生成式AI走进小学生「编程第一课」:画条线生成音乐、草图一秒变大作
4310
强大的AI网站推荐(第五集)—— Suno
4110
唱演视频爆火,AI 对口型工具成创作者刚需
1210
相关推荐
Suno AI 人人都能成为创作型歌手
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档