1.协程
定义:协程的官方定义是一种具有暂停执行并将控制权返回给Unity,待下一帧时继续执行。通俗点讲就是,协程是一种可以分部执行的函数,即该函数不是每次调用时都会执行函数体内的全部方法,而是只调用其中部分代码。
协程其实与多线程一点关系都没有。协程是在主线程中执行的,且每次只能执行一个协程。
1.启动协程
Coroutine StartCoroutine(string methodName,object value=null);
Coroutine StartCoroutine(IEnumerator routine);
2.停止协程
void StopCoroutine(string methodName);
void StopCoroutine(IEnumerator routine);
其中StopCortouine(string methodName)只能停止由与之相对应的StarCoroutine(string methodName)启动的协程。
还有其它的方法来停止协程,但都不是停止某个指定的协程,而是停止多个协程。
void StopAllCoroutines()
停止该behavior内的全部协程
void SetActive(bool value);
将behavior的active设为false后,其内部的协程也都会停止。
3.返回值
1. null和其它的数值,如0:
和null类似,不过不推荐。因为会存在装箱,拆箱的问题,或多或少会影响性能。
2. WaitForEndOfFrame
等待至所有的Camera和GUI都呈现好了之后执行。
3. WaitForFixedUpdate
等待至所有物理都计算后执行
4. WaitForSeconds
在指定时间段内不执行
5. WWW
等待一个web请求完成
6. 另一个协程
这是比较有意思的一点。因为StartCoroutine的返回值是Coroutine,所以我们可以yield另一个协程。
要注意的是,如果设置Time.timeScale为0时,yield return new WaitForSeconds(x)是不会恢复继续执行。
2.Prefabs
优点:
- Prefab一个重要的优势就是编辑prefab资源后,场景中所有使用Prefab克隆的游戏对象将全部使用新编辑的资源,无需一个一个的给场景中的对象赋值。
- 当游戏中需要频繁创建一个物体时,使用Prefab能够节省内存。
- 不论项目中存在多少实例。仅仅要对Prefab进行了改动。全部Prefab实例都将随之发生变化。
- 能够放到多个场景中。也能够在同一个场景中放置多次
不便之处没查到资料,想了想觉得有以下几点:
1.资源加载分类
2.嵌套关联关系处理
希望知道更多的童鞋能给博主留个言~
3.资源加载
参考链接中有之前写过的关于AssetBundle使用的文章,在此不再多说,只是总结下相关知识
1.加载AssetBundle文件
Unity提供了三种不同的方法来加载AssetBundle,代码如下:
第一种:AssetBundle.LoadAsset
// 通过资源名称标识名做为参数来加载对象
public Object LoadAsset(string name);
第二种:AssetBundle.LoadAssetAsync
//执行方法类似前面的LoadAsset方法,但是在加载资源时不会阻碍主线程
public AssetBundleRequest LoadAssetAsync(string name);
第三种:AssetBundle.LoadAllAssets
// 加载AssetBundle中包含的所有资源对象,并且可以通过对象类型来过滤此资源
public Object[] LoadAllAssets(Type type);
2.卸载AssetBundle文件
卸载AssetBundle文件比加载要容易一些,我们需要使用AssetBundle.Unload方法来卸载AssetBundle创建出来的对象:
// 释放AssetBundle文件内存镜像,但不销毁已经加载好的Assets对象
AssetBundle.Unload(false);
// 释放AssetBundle文件内存镜像,并同时销毁所有已经加载的Assets对象
AssetBundle.Unldoad(true);
3.下载AssetBundle文件
①.AssetBundle.LoadFromMemoryAsync(异步,对应还有同步方法)
②.AssetBundle.LoadFromFile(也有对应的异步方法)
③.WWW.LoadFromCacheOrDownload
④.UnityWebRequest
使用参考链接: https://blog.csdn.net/dengshunhao/article/details/80486774
路径相关知识:
资源文件夹的区别
资源类型 | 注释 |
---|---|
Resources | 是作为一个Unity3D的保留文件夹出现的,也就是如果你新建的文件夹的名 字叫Resources,那么里面的内容在打包时都会被无条件的打到发布包中。 它的特点简单总结一下就是:只读,即不能动态修改。所以想要动态更新 的资源不要放在这里。会将文件夹内的资源打包集成到.asset文件里面。 因此建议可以放一些Prefab,因为Prefab在打包时会自动过滤掉不需要的 资源,有利于减小资源包的大小。主线程加载。资源读取使用 Resources.Load()。 |
StreamingAssets | 要说到StreamingAssets,其实和Resources还是蛮像的。同样作为一 个只读的Unity3D的保留文件夹出现。不过两者也有很大的区别,那就 是Resources文件夹中的内容在打包时会被压缩和加密。而 StreamingAsset文件夹中的内容则会原封不动的打入包中,因此 StreamingAssets主要用来存放一些二进制文件。下面也同样做一个简 单的总结:同样,只读不可写。主要用来存放二进制文件。只能用过 WWW类来读取。 |
AssetBundle | 关于AssetBundle的介绍已经有很多了。简而言之就是把prefab或 者二进制文件封装成AssetBundle文件(也是一种二进制)。但是 也有硬伤,就是在移动端无法更新脚本。下面简单的总结下:是 Unity3D定义的一种二进制类型。最好将prefab封装成AseetBundle, 不过上面不是才说了在移动端无法更新脚本吗?那从Assetbundle中 拿到的Prefab上挂的脚本是不是就无法运了?也不一定,只要这个 prefab上挂的是本地脚本,就可以。使用WWW类来下载。 |
PersistentDataPath | 看上去它只是个路径呀,可为什么要把它从路径里面单独拿出来 介绍呢?因为它的确蛮特殊的,这个路径下是可读写。而且在IOS 上就是应用程序的沙盒,但是在Android可以是程序的沙盒,也可 以是sdcard。并且在Android打包的时候,ProjectSetting页面有一 个选项Write Access,可以设置它的路径是沙盒还是sdcard。下面 同样简单的总结一下:内容可读写,不过只能运行时才能写入或者 读取。提前将数据存入这个路径是不可行的。无内容限制。你可以 从StreamingAsset中读取二进制文件或者从AssetBundle读取文件来 写入PersistentDataPath中。写下的文件,可以在电脑上查看。同样 也可以清掉。 |
Unity中的资源路径
路径字段 | 注释 |
---|---|
Application.dataPath | 此属性用于返回程序的数据文件所在文件夹的路径 。例如在Editor中就是Assets了。 |
Application.streamingAssetsPath | 此属性用于返回流数据的缓存目录,返回路径为相对路径 ,适合设置一些外部数据文件的路径。 |
Application.persistentDataPath | 此属性用于返回一个持久化数据存储目录的路径 ,可以在此路径下存储一些持久化的数据文件。 |
Application.temporaryCachePath | 此属性用于返回一个临时数据的缓存目录。 |
Android中的资源路径
路径字段 | 具体路径 |
---|---|
Application.dataPath | /data/app /xxx.xxx.xxx.apk |
Application.streamingAssetsPath | jar:file:///data/ap p/xxx.xxx.xxx.apk /!/assets |
Application.persistentDataPath | /data/data /xxx.xxx.xxx/files |
Application.temporaryCachePath | /data/data /xxx.xxx.xxx/cache |
Android中有一个小小的注意点:在Android可以是程序的沙盒,也可以是sdcard。并且在Android打包的时候,ProjectSetting页面有一个选项Write Access,可以设置它的路径是沙盒还是sdcard。
IOS中的资源路径
路径字段 | 具体路径 |
---|---|
Application.dataPath | Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data |
Application.streamingAssetsPath | Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.ap p/Data/Raw |
Application.persistentDataPath | Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx x/Documents |
Application.temporaryCachePath | Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx x/Library/Caches |
4.预处理命令(#if #endif)
当C#编译器遇到一个由#if和#endif包围起来的语句块时,会检查#if后面的符号是否已经被定义了,如果已经被定义,那么才会编译语句块之间的代码。而定义一个可以被#if测试的符号需要事先用#define指令定义。(或/define指令,效果一样)
// 使用#define定义了一个DEBUG和MYTEST符号
#define DEBUG
#define MYTEST
using System;
public class MyClass
{
static void Main()
{
#if (DEBUG && !MYTEST) // 不为true 以下代码不编译
Console.WriteLine("DEBUG is defined");
#elif (!DEBUG && MYTEST)
Console.WriteLine("MYTEST is defined");
#elif (DEBUG && MYTEST) // 为true,以下代码编译
Console.WriteLine("DEBUG and MYTEST are defined");
#else
Console.WriteLine("DEBUG and MYTEST are not defined");
#endif
}
}
除了用代码定义宏之外,还可以用:
如果你使用的Visual Studio编辑器,那么也可以在项目中定义全局宏
5.Unity生命周期
(1) Reset(): 组件重设为默认值时(只用于编辑状态)
(2)Awake() : 脚本组件载入时 (调用一次)
(3)OnEnable() : 是在游戏对象可以调用时调用
(4) Start() : 第一个Update发生之前 (调用一次)
(5)FixedUpdate() : 固定时间调用,常用于物理相关的计算,比如对Rigidbody的操作
(6)Update() : 大部分游戏行为代码被执行的地方,除了物理代码
(7)LateUpdate() : 每帧Update调用之后,物理代码一般放在这
(8)OnGUI() : 绘制GUI时调用
(9)OnDisable() : 当对象设置为不可用时
(10)OnDestroy() : 组件销毁时调用
全部生命周期:
生命周期常用简图:
参考链接:
1.协程全解:http://www.cnblogs.com/mezero/p/3953838.html
2.AssetBundle使用 : https://blog.csdn.net/dengshunhao/article/details/80480617
3.AssetBundle分组策略 : https://blog.csdn.net/dengshunhao/article/details/80492836