using System. Collections;
using System. Collections. Generic;
using UnityEngine;
public class Lesson16 : MonoBehaviour
{
void Start ( )
{
# region 知识点一 工程路径获取
print ( Application. dataPath) ;
# endregion
# region 知识点二 Resources 资源文件夹
print ( Application. dataPath + "/Resources" ) ;
# endregion
# region 知识点三 StreamingAssets 流动资源文件夹
print ( Application. streamingAssetsPath) ;
# endregion
# region 知识点四 persistentDataPath 持久数据文件夹
print ( Application. persistentDataPath) ;
# endregion
# region 知识点五 Plugins 插件文件夹
# endregion
# region 知识点六 Editor 编辑器文件夹
print ( Application. dataPath + "/Editor" ) ;
# endregion
# region 知识点七 默认资源文件夹 Standard Assets
# endregion
}
void Update ( )
{
}
}
using System. Collections;
using System. Collections. Generic;
using UnityEngine;
public class Lesson17 : MonoBehaviour
{
public AudioSource audioS;
private Texture tex;
void Start ( )
{
# region 知识点一 Resources资源动态加载的作用
# endregion
# region 知识点二 常用资源类型
# endregion
# region 知识点三 资源同步加载 普通方法
Object obj = Resources. Load ( "Cube" ) ;
Instantiate ( obj) ;
Object obj2 = Resources. Load ( "Sphere" ) ;
Instantiate ( obj2) ;
Object obj3 = Resources. Load ( "Music/BKMusic" ) ;
audioS. clip = obj3 as AudioClip;
audioS. Play ( ) ;
TextAsset ta = Resources. Load ( "Txt/Test" ) as TextAsset;
print ( ta. text) ;
ta = Resources. Load ( "Tex/TestJPG" , typeof ( TextAsset) ) as TextAsset;
Object[ ] objs = Resources. LoadAll ( "Tex/TestJPG" ) ;
foreach ( Object item in objs)
{
if ( item is Texture)
{
}
else if ( item is TextAsset)
{
}
}
# endregion
# region 知识点四 资源同步加载 泛型方法
TextAsset ta2 = Resources. Load< TextAsset> ( "Tex/TestJPG" ) ;
print ( ta2. text) ;
tex = Resources. Load< Texture> ( "Tex/TestJPG" ) ;
# endregion
# region 总结
# endregion
}
void Update ( )
{
}
private void OnGUI ( )
{
GUI. DrawTexture ( new Rect ( 0 , 0 , 100 , 100 ) , tex) ;
}
}
using System. Collections;
using System. Collections. Generic;
using UnityEngine;
public class Lesson18 : MonoBehaviour
{
private Texture tex;
void Start ( )
{
# region 知识点一 Resources异步加载是什么?
# endregion
# region 知识点二 Resources异步加载方法
print ( Time. frameCount) ;
StartCoroutine ( Load ( ) ) ;
# endregion
# region 总结
# endregion
}
IEnumerator Load ( )
{
ResourceRequest rq = Resources. LoadAsync< Texture> ( "Tex/TestJPG" ) ;
print ( Time. frameCount) ;
print ( Time. frameCount) ;
while ( ! rq. isDone)
{
print ( rq. progress) ;
yield return null;
}
tex = rq. asset as Texture;
}
private void LoadOver ( AsyncOperation rq)
{
print ( "加载结束" ) ;
tex = ( rq as ResourceRequest) . asset as Texture;
print ( Time. frameCount) ;
}
private void OnGUI ( )
{
if ( tex != null)
GUI. DrawTexture ( new Rect ( 0 , 0 , 100 , 100 ) , tex) ;
}
}
实现一个资源异步加载管理器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class ResourcesMgr
{
//这里为了单例
private static ResourcesMgr instance = new ResourcesMgr();
public static ResourcesMgr Instance => instance;
//避免外面进行new对象
private ResourcesMgr()
{
}
public void LoadRes<T>(string name, UnityAction<T> callBack) where T:Object
{
//开启异步加载
ResourceRequest rq = Resources.LoadAsync<T>(name);
//最简单直接的加载,开启线程
//匿名函数,这里的a是形参,是资源加载完成后传进来的参数被a接收,
rq.completed += (a) =>
{
//直接得到 传入的 对象 通过它得到资源内容 然后转换成对应类型 传出去 外面不需要转换 直接使用
callBack((a as ResourceRequest).asset as T);
};
}
}
卸载资源
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson19 : MonoBehaviour
{
private Texture tex;
// Start is called before the first frame update
void Start()
{
#region 知识点一 Resources重复加载资源会浪费内存吗?
//其实Resources加载一次资源过后
//该资源就一直存放在内存中作为缓存
//第二次加载时发现缓存中存在该资源
//会直接取出来进行使用
//所以 多次重复加载不会浪费内存
//但是 会浪费性能(每次加载都会去查找取出,始终伴随一些性能消耗)
#endregion
#region 知识点二 如何手动释放掉缓存中的资源
//1.卸载指定资源
//Resources.UnloadAsset 方法
//注意:
//该方法 不能释放 GameObject对象 因为它会用于实例化对象
//它只能用于一些 不需要实例化的内容 比如 图片 和 音效 文本等等
//一般情况下 我们很少单独使用它
//GameObject obj = Resources.Load<GameObject>("Cube");
//即使是没有实例化的 GameObject对象也不能进行卸载
//Resources.UnloadAsset(obj);
//2.卸载未使用的资源
//注意:
//一般在过场景时和GC一起使用
Resources.UnloadUnusedAssets();
GC.Collect();
#endregion
#region 总结
//Resources.UnloadAsset 卸载指定资源 但是不能卸载GameObject对象
//Resources.UnloadUnusedAssets 卸载未使用资源 一般过场景时配合GC使用
#endregion
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.Alpha1))
{
print("加载资源");
tex = Resources.Load<Texture>("Tex/TestJPG");
}
if(Input.GetKeyDown(KeyCode.Alpha2))
{
print("卸载资源");
Resources.UnloadAsset(tex);
tex = null;
}
}
}
场景加载的方法,同步异步
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class Lesson20 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
#region 知识点一 回顾场景同步切换
//SceneManager.LoadScene("Lesson20Test");
#region 场景同步切换的缺点
//在切换场景时
//Unity会删除当前场景上所有对象
//并且去加载下一个场景的相关信息
//如果当前场景 对象过多或者下一个场景对象过多
//这个过程会非常的耗时 会让玩家感受到卡顿
//所以异步切换就是来解决该问题的
#endregion
#endregion
#region 知识点二 场景异步切换
//场景异步加载和资源异步加载 几乎一致 有两种方式
//1.通过事件回调函数 异步加载
//AsyncOperation ao = SceneManager.LoadSceneAsync("Lesson20Test");
//当场景异步加载结束后 就会自动调用该事件函数 我们如果希望在加载结束后 做一些事情 那么久可以在该函数中
//写处理逻辑
//ao.completed += (a) =>
//{
// print("加载结束");
//};
//ao.completed += LoadOver;
//2.通过协程异步加载
//需要注意的是 加载场景会把当前场景上 没有特别处理的对象 都删除了
//所以 协程中的部分逻辑 可能是执行不了的
//解决思路
//让处理场景加载的脚本依附的对象 过场景时 不被移除
//该脚本依附的对象 过场景时 不会被 移除
DontDestroyOnLoad(this.gameObject);
StartCoroutine(LoadScene("Lesson20Test"));
#endregion
#region 总结
//场景异步加载 和 资源异步加载 一样
//有两种方式
//1.通过事件回调函数
//2.协程异步加载
//他们的优缺点表现和资源异步加载 也是一样的
//1.事件回调函数
//优点:写法简单,逻辑清晰
//缺点:只能加载完场景做一些事情 不能再加载过程中处理逻辑
//2.协程异步加载
//优点:可以在加载过程中处理逻辑,比如进度条更新等
//缺点:写法较为麻烦,要通过协程
#endregion
}
private void LoadOver(AsyncOperation ao)
{
print("LoadOver");
}
IEnumerator LoadScene(string name)
{
//第一步
//异步加载场景
AsyncOperation ao = SceneManager.LoadSceneAsync(name);
//Unity内部的 协程协调器 发现是异步加载类型的返回对象 那么就会等待
//等待异步加载结束后 才会继续执行 迭代器函数中后面的步骤
print("异步加载过程中 打印的信息");
//协程的好处 是异步加载场景时 我可以在加载的同时 做一些别的逻辑
//yield return ao;
//第二步
print("异步加载结束后 打印的信息");
//比如 我们可以在异步加载过程中 去更新进度条
//第一种 就是利用 场景异步加载 的进度 去更新 但是 不是特别准确 一般也不会直接用
//while(!ao.isDone)
//{
// print(ao.progress);
// yield return null;
//}
//离开循环后 就会认为场景加载结束
//可以把进度条顶满 然后 隐藏进度条
//第二种 就是根据你游戏的规则 自己定义 进度条变化的条件
yield return ao;
//场景加载结束 更新20%进度
//接着去加载场景中 的其它信息
//比如
//动态加载怪物
//这时 进度条 再更新20%
//动态加载 场景模型
//这时 就认为 加载结束了 进度条顶满
//隐藏进度条
}
}
自己封装一个场景管理器
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
public class SceneMgr
{
private static SceneMgr instance = new SceneMgr();
public static SceneMgr Instance => instance;
private SceneMgr() { }
public void LoadScene(string name, UnityAction action)
{
AsyncOperation ao = SceneManager.LoadSceneAsync(name);
ao.completed += (a) =>
{
//通过那么大表达式 包裹一层
//在内部 直接调用外部传入的委托即可
action();
};
}
}