文章目录
- 5.1 不要把玩具乱丢
- 5.2 Unity工程目录结构
- 5.3 Resources.Load实战测试
- 5.3.1 资源下载与导入
- 5.3.2 目录整理
- 5.3.3 代码动态加载资源
- 5.3.4 运行效果
简介:我是一名Unity
游戏开发工程师,皮皮是我养的猫,会讲人话,它接到了喵星的特殊任务:学习编程,学习Unity
游戏开发。
于是,发生了一系列有趣的故事。
5.1 不要把玩具乱丢
我:“老皮,你看你,又把玩具弄得到处都是,玩具玩完要放回原来的盒子里,不然下次找不到了。”
我捡起墙角的小球和椅子底下的铃铛,放回收纳盒中。
皮皮:“家里就这么点地,不会不见的。”
我:“那就不买新玩具了,我每天都要收拾,玩具越多,收拾起来就越花时间了。”
皮皮:“两脚怪,你怎么可以这样对一只猫,我收拾便是。”
我:“作为一个程序员,你一定要养成这样的习惯,物品分门别类,按照规定的位置,收纳摆放整齐,贴好标签,这样提升搜索效率,方便管理维护。”
皮皮:“比我们猫的规矩还多。”
我:“养成这样的好习惯,对你成为一名优秀的游戏开发工程师也是必要的。一个好的项目架构在前期的开发和后期的维护方面,都会带来极大的好处,直接关系到后面多人协作开发时的效率。另外,Unity
的工程目录结构,都是有规范的目录格式,存放文件也是有讲究的,特别是工程做大了之后,资源量是特别大的,所以务必要规划好工程目录结构,不然后期维护工程就是一场人间灾难啊。”
皮皮:“啊,这么重要,快教教我。”
5.2 Unity工程目录结构
Assets
为主目录,其他所有文件都在Assets
目录下,如下
皮皮:“为什么我的工程里没有这些目录?”
我:“刚创建的空工程,是没有这些目录的,要自己手动创建,而且,目录名字是有规范的,比如Editor
、Gizmos
、Plugins
、Resource
、StreamingAssets
等目录,这些名字的目录都是有特殊用途的。”
皮皮:“那RawAssets
、GameAssets
、Scenes
、Scripts
、Shaders
这些目录呢?”
我:“这些是我自定义的,就像收纳盒一样,有的放文具,有的放药品,有的放零食等等。”
皮皮:“别卖关子,这些目录到底具体作用是什么?”
我:“看表。”
皮皮:“现在是下午15点24分46秒。”
我:“我是说看这个表格。”
目录 | 说明 |
Editor | 编辑器目录,该目录下的代码可调用Unity Editor 的API,存放扩展编辑器的代码。该目录中的代码不会被打进最终的包内。比如自定义打包工具,打包工具的代码就放在Editor目录中。 |
Gizmos | Gizmos绘图相关的资源放这里,Gizmos绘制的效果不会在Game视图中显示,除非在Game视图中勾选Gizmos。该目录的资源不会被打进最终的包内。 |
Plugins | 插件目录,项目中很可能需要接一些第三方SDK,比如微信开放平台的SDK,对应的SDK库文件就是放这个目录中(子目录Plugins/Android和Plugins/iOS)。还有你可能会用到一些第三方库,比如HoTween.dll、Zxing.dll、Ionic.Zip.Unity.dll等,都是放在Plugins中。 |
Resources | 资源目录,需要动态加载的资源放在这里,这个文件夹里的所有文件,不管有没有使用,都会统统自动打进包内,并且Unity会执行资源压缩。该目录下的资源文件通过Resources.Load接口进行加载。它是一个只读的文件夹,程序运行时只能读不能写。实战项目中一般只会放必要的少量资源在这个目录中,大部分资源会放在别的目录下,打成AssetBundle文件放在StreamingAssets目录中。 |
StreamingAssets | 流式资源目录,这个文件夹里的所有文件,不管有没有使用,都会统统自动打进包内,与Resources不同的是,该目录下的文件打包时不会被压缩,会原封不动打进包内。它是一个只读的文件夹,程序运行时只能读不能写,它在各个平台下的路径是不同的,我们可以使用Application.streamingAssetsPath访问该路径。实战项目中一般会把资源打成AssetBundle放在该目录中。 |
Scripts | 脚本目录,我们的c#游戏脚本放在这个目录中,注意,如果是编辑器工具类的c#脚本,则放在Editor目录中。 |
Scenes | 场景目录,我们的场景文件放在这个目录中,包括场景的Lighting灯光烘焙数据、Navigation导航数据等。 |
Shaders | 着色器目录,存放shader文件,shader一般是技术美术来写,它涉及到一些艺术表现效果,不过技多不压身,能自己学会自己写shader最好,有不少程序员也是很有艺术天分的。 |
RawAssets | 生肉资源目录,这个目录是我自定义的,用来存放生肉资源。生肉就是未加工的意思,比如一只老鼠模型,它依赖了骨骼、动画、贴图、材质等资源文件,老鼠模型我们会包装成预设,预设是熟肉资源,相对应的,骨骼、动画、贴图、材质等是生肉资源。这里的生肉资源和熟肉资源概念是我自己创造的,仅做方便理解。 |
GameAssets | 熟肉资源目录,这个目录是我自定义的,用来存放熟肉资源。熟肉资源就是已加工过的资源,一般我们会把游戏资源包装成预设,这些预设就是熟肉资源。实战项目中一般会把该目录中的资源打成AssetBundle放在StreamingAssets目录中。在编辑器环境下,我们可以使用AssetDatabase.LoadAssetAtPah直接加载该目录中的资源。 |
皮皮:“好多新名词啊。”
我:“不要怕,先混个脸熟,后面你会经常与这些名词打交道的,慢慢你就熟络了。”
5.3 Resources.Load实战测试
我:“光说不练假把式,现在我们来实战一下。”
皮皮:“我想试验下Resources.Load
资源加载。”
我:“没问题。”
5.3.1 资源下载与导入
打开浏览器,登录Untiy
的资源商店,资源地址:https://assetstore.unity.com/packages/3d/props/free-christmas-presents-low-poly-24356 点击添加至我的资源
。
此时会弹出如下提示,点击在Unity中打开
。
此时会跳回到Unity
的Package Manager
窗口,如果跳转不成功,可以手动在Unity
中打开。
菜单:Window - Package Manager
窗口左上角的Package
选择My Assets
,即可看到自己收藏的资源。
选择要导入的资源,点击Download
。
等待下载完毕,然后点击Import
。
导入成功后,目录如下
5.3.2 目录整理
整理一下目录,创建RawAssets
和Resources
目录,生肉资源放在RawAssets
目录中,熟肉资源放在Resources
目录中。
皮皮:“我又忘了熟肉和生肉的区别了。”
我:“生肉资源就是未加工的原始零散资源,比如骨骼、材质、贴图,熟肉就是已加工完毕的成品资源,比如最终成品的预设。”
我:“看,这个Teddybear
预设,它就是我们要通过Resources.Load
加载的资源。”
5.3.3 代码动态加载资源
代码要放在Scripts
目录中,所以先创建一个Scripts
目录,然后创建一个ResTest
脚本。
ResTest.cs
代码如下
using UnityEngine;
/// <summary>
/// 资源加载测试
/// </summary>
public class ResTest : MonoBehaviour
{
void Start()
{
// 通过Resources.Load从Resources目录中加载资源
// 注意不要到文件格式后缀
var bearPrefab = Resources.Load<GameObject>("Teddybear");
// 实例化预设,实例化为一个GameObject
var bearGo = Object.Instantiate<GameObject>(bearPrefab);
// 设置坐标
bearGo.transform.position = Vector3.zero;
}
}
皮皮:“Resources.Load
不是已经得到资源的GameObject
了吗?为什么还要实例化一下?”
我:“这也是初学者容易搞错的一个地方,以为执行了Resources.Load
就完事了,结果运行后场景中没有看到对应的资源,还以为是加载失败了。”
我喝了口水继续说,“Resources.Load
是从磁盘中加载资源进内存中,等于在内存中有一份镜像,由于它只是在内存中,没有挂到场景上,所以我们在场景中看不到它。我们需要从内存中将它实例化到游戏场景中,这个Object.Instantiate
就是将资源从内存中执行一次拷贝,实例化到游戏场景中。”
皮皮:“这样不是挺浪费内存的吗,实例化的这个对象也会占内存吧?这样不是占了两份内存空间?”
我:“小伙子,已经能够理解到这个层面啦,如此可教也。Unity
这么设计,是为了方便实例化的时候都是资源的原始镜像,如果没有一份原始镜像,那么只能实例化已挂到场景中的对象,但挂到场景中的对象很可能已经被我们修改了,它不是原始状态了,这时候想实例化原始资源就得重新从磁盘中去读取,而磁盘读写操作是比内存的拷贝要慢很多的,所以Unity
才这样设计,在内存中有一份原始资源的镜像。”
皮皮:“原来如此呀。接下来是不是要挂组件啦?”
我:“不错嘛,你就知道挂组件。”
皮皮抢过我手中的鼠标,在Main Camera
上点击了Add Component
,将ResTest
脚本挂了上去。
5.3.4 运行效果
点击运行,效果如下
《学Unity的猫》——第六章:探索GameObject游戏对象