18.Resources同步加载

18.Resources资源动态加载-Resources同步加载


18.1 知识点

Resources资源动态加载的作用

  • 通过代码动态加载Resources文件夹下指定路径资源
  • 避免繁琐的拖曳操作

常用资源类型

  • 预设体对象——GameObject
  • 音效文件——AudioClip
  • 文本文件——TextAsset
  • 图片文件——Texture
  • 其它类型——需要什么用什么类型

注意:

  • 预设体对象加载需要实例化。
  • 其它资源加载一般直接用。

Resources.Load静态方法 资源同步加载普通方法

  • 在一个工程当中 Resources文件夹 可以有多个,通过API加载时,它会自己去这些同名的Resources文件夹中去找资源。
  • 打包时Resources文件夹里的内容都会打包在一起。

预设体对象

//想要创建在场景上 记住实例化
//第一步:要去加载预设体的资源文件(本质上 就是加载 配置数据 在内存中) 但是并没有创建在场景中
Object obj = Resources.Load("Cube");
//第二步:如果想要在场景上 创建预设体 一定是加载配置文件过后 然后实例化
Instantiate(obj);
//第一步:要去加载预设体的资源文件(本质上 就是加载 配置数据 在内存中) 但是并没有创建在场景中
Object obj2 = Resources.Load("Sphere");
//第二步:如果想要在场景上 创建预设体 一定是加载配置文件过后 然后实例化
Instantiate(obj2);
//注意:Resources文件夹就算不是直接是Assets文件夹的子文件夹,是孙子文件夹或者更深一层,里面的资源也能被加载出来

音效资源

//第一步:就是加载数据
//注意:子文件夹一层一层用/隔开
Object obj3 = Resources.Load("Music/BKMusic");
//第二步:使用数据 我们不需要实例化 音效切片 我们只需要把数据 赋值到正确的脚本上即可
//需要把加载出来的数据as成音频传到音频源
audioSource.clip = obj3 as AudioClip;
audioSource.Play();

文本资源

//文本资源支持的格式
//.txt
//.xml
//.bytes
//.json
//.html
//.csv
//.....
//需要把加载出来的文本资源as成文本资源 装起来就能打印了
TextAsset ta = Resources.Load("Txt/Test") as TextAsset;
//文本内容
print(ta.text);
//字节数据组
print(ta.bytes);

图片

// 把图片as成Texture,可以在GUI里绘制图片测试
Texture tex = Resources.Load("Tex/TestJPG") as Texture;
private void OnGUI()
{
    GUI.DrawTexture(new Rect(0, 0, 100, 100), tex);
}

其它类型

  • 需要什么类型,就用什么类型就行。

问题:资源同名怎么办

//Resources.Load加载同名资源时 无法准确加载出你想要的内容
//可以使用Load方法的重载,第二个参数传入加载的指定类型的资源
//加载指定类型的资源
tex = Resources.Load("Tex/TestJPG", typeof(Texture)) as Texture;
ta = Resources.Load("Tex/TestJPG", typeof(TextAsset)) as TextAsset;
print(ta.text);

Resources.LoadAll静态方法 资源同步加载文件夹中指定名字的所有类型的资源方法

//Resources中的LoadAll静态方法 加载文件夹中指定名字的所有类型的资源
//加载位于 Resources 文件夹中的 path 处的文件夹中的所有资源,或加载位于该处的文件。
//加载指定名字的所有资源
Object[] objs = Resources.LoadAll("Tex/TestJPG");
foreach (Object item in objs)
{
    if (item is Texture)
    {
        print("这是图片");
    }
    else if (item is TextAsset)
    {
        print("这是文本");
    }
}

Resources.Load<T>静态方法 资源同步加载泛型方法

//Resources中的Load静态方法 可以用泛型方法加载资源 就不用as了
//加载存储在 Resources 文件夹中的 path 处的资源。
TextAsset ta2 = Resources.Load<TextAsset>("Tex/TestJPG");
print(ta2.text);
tex = Resources.Load<Texture>("Tex/TestJPG");

总结

  • Resources动态加载资源的方法。
  • 让拓展性更强。
  • 相对拖曳来说,它更加一劳永逸,更加方便。

重要知识点:

  • 记住API。
  • 记住一些特定的格式。
  • 预设体加载出来一定要实例化。

18.2 知识点代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson18_Resources资源动态加载_Resources同步加载 : MonoBehaviour
{
    public AudioSource audioSource;

    private Texture tex;

    void Start()
    {
        #region 知识点一 Resources资源动态加载的作用

        //1.通过代码动态加载Resources文件夹下指定路径资源
        //2.避免繁琐的拖曳操作

        #endregion

        #region 知识点二 常用资源类型

        //1.预设体对象——GameObject
        //2.音效文件——AudioClip
        //3.文本文件——TextAsset
        //4.图片文件——Texture
        //5.其它类型——需要什么用什么类型

        //注意:
        //预设体对象加载需要实例化
        //其它资源加载一般直接用

        #endregion

        #region 知识点三 资源同步加载 普通方法

        //在一个工程当中 Resources文件夹 可以有多个 通过API加载时 它会自己去这些同名的Resources文件夹中去找资源
        //打包时 Resources文件夹 里的内容 都会打包在一起

        //Resources中的Load静态方法 加载资源
        //加载存储在 Resources 文件夹中的 path 处的资源。

        //1.预设体对象
        //想要创建在场景上 记住实例化
        //第一步:要去加载预设体的资源文件(本质上 就是加载 配置数据 在内存中) 但是并没有创建在场景中
        Object obj = Resources.Load("Cube");
        //第二步:如果想要在场景上 创建预设体 一定是加载配置文件过后 然后实例化
        Instantiate(obj);
        //第一步:要去加载预设体的资源文件(本质上 就是加载 配置数据 在内存中) 但是并没有创建在场景中
        Object obj2 = Resources.Load("Sphere");
        //第二步:如果想要在场景上 创建预设体 一定是加载配置文件过后 然后实例化
        Instantiate(obj2);
        //注意:Resources文件夹就算不是直接是Assets文件夹的子文件夹,是孙子文件夹或者更深一层,里面的资源也能被加载出来

        //2.音效资源
        //第一步:就是加载数据
        //注意:子文件夹一层一层用/隔开
        Object obj3 = Resources.Load("Music/BKMusic");
        //第二步:使用数据 我们不需要实例化 音效切片 我们只需要把数据 赋值到正确的脚本上即可
        //需要把加载出来的数据as成音频传到音频源
        audioSource.clip = obj3 as AudioClip;
        audioSource.Play();

        //3.文本资源
        //文本资源支持的格式
        //.txt
        //.xml
        //.bytes
        //.json
        //.html
        //.csv
        //.....
        //需要把加载出来的文本资源as成文本资源 装起来就能打印了
        TextAsset ta = Resources.Load("Txt/Test") as TextAsset;
        //文本内容
        print(ta.text);
        //字节数据组
        print(ta.bytes);

        //4.图片
        //把图片as成Texture 可以在GUI里绘制图片测试
        tex = Resources.Load("Tex/TestJPG") as Texture;

        //5.其它类型 需要什么类型 就用什么类型就行

        //6.问题:资源同名怎么办
        //Resources.Load加载同名资源时 无法准确加载出你想要的内容

        //可以使用Load方法的重载,第二个参数传入加载的指定类型的资源
        //6-1加载指定类型的资源
        tex = Resources.Load("Tex/TestJPG", typeof(Texture)) as Texture;
        ta = Resources.Load("Tex/TestJPG", typeof(TextAsset)) as TextAsset;
        print(ta.text);

        //Resources中的LoadAll静态方法 加载文件夹中指定名字的所有类型的资源
        //加载位于 Resources 文件夹中的 path 处的文件夹中的所有资源,或加载位于该处的文件。
        //6-2加载指定名字的所有资源
        Object[] objs = Resources.LoadAll("Tex/TestJPG");
        foreach (Object item in objs)
        {
            if (item is Texture)
            {
                print("这是图片");
            }
            else if (item is TextAsset)
            {
                print("这是文本");
            }
        }

        #endregion

        #region 知识点四 资源同步加载 泛型方法

        //Resources中的Load静态方法 可以用泛型方法加载资源 就不用as了
        //加载存储在 Resources 文件夹中的 path 处的资源。
        TextAsset ta2 = Resources.Load<TextAsset>("Tex/TestJPG");
        print(ta2.text);
        tex = Resources.Load<Texture>("Tex/TestJPG");

        #endregion

        #region 总结

        //Resources动态加载资源的方法
        //让拓展性更强
        //相对拖曳来说 它更加一劳永逸 更加方便

        //重要知识点:
        //记住API
        //记住一些特定的格式
        //预设体加载出来一定要实例化

        #endregion
    }

    private void OnGUI()
    {
        GUI.DrawTexture(new Rect(0, 0, 100, 100), tex);
    }
}

18.3 练习题

请把之前四元数练习题中,发射散弹等相关逻辑改为动态加载资源并创建

把子弹丢到Resources文件夹后,有两种改法

第一种是不在Inspector窗口拖拽Prefab,直接在Start()里Load,实例化的时候直接使用即可

// 直接在Start()里Load
private GameObject bullet;

void Start()
{
    bullet = Resources.Load<GameObject>("Bullet");
}

第二种是在实例化的时候每次都Resources.Load(“Bullet”)

注意:这样不会造成内存上的浪费,因为Unity加载好的资源放在缓存区,判断Load过了就不重新Load了,但是会造成性能开销

private void Fire()
{
    switch (nowType)
    {
        // 每次实例化的时候都Load,当其实Load了一次不会再Load
        case E_FireType.One:
            Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation);
            break;
        case E_FireType.Two:
            Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position - this.transform.right * 0.5f, this.transform.rotation);
            Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position + this.transform.right * 0.5f, this.transform.rotation);
            break;
        case E_FireType.Three:
            Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation);
            Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation * Quaternion.AngleAxis(-20, Vector3.up));
            Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation * Quaternion.AngleAxis(20, Vector3.up));
            break;
        case E_FireType.Round:
            float angle = 360 / roundNum;
            for (int i = 0; i < roundNum; i++)
                Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation * Quaternion.AngleAxis(i * angle, Vector3.up));
            break;
    }
}

18.4 练习题代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Lesson18_练习题 : MonoBehaviour
{
    #region 练习题一
    //请把之前四元数练习题中,发射散弹等相关逻辑改为动态加载资源并创建

    //把子弹丢到Resources文件夹后 有两种改法
    //第一种是不在Inspector窗口拖拽Prefab,直接在Start()里Load,实例化的时候直接使用即可
    //第二种是在实例化的时候每次都Resources.CoroutineAsynLoad<GameObject>("Bullet")
    //注意:这样不会造成内存上的浪费,因为Unity加载好的资源放在缓存区,判断Load过了就不重新Load了,但是会造成性能开销

    private E_FireType nowType = E_FireType.One;
    public int roundNum = 4;

    //直接在Start()里Load
    private GameObject bullet;
    void Start()
    {
        bullet = Resources.Load<GameObject>("Bullet");
    }
    
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            nowType = E_FireType.One;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            nowType = E_FireType.Two;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            nowType = E_FireType.Three;
        }
        else if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            nowType = E_FireType.Round;
        }

        if (Input.GetKeyDown(KeyCode.Space))
        {
            Fire();
        }
    }

    private void Fire()
    {
        switch (nowType)
        {
            //每次实例化的时候都Load,当其实Load了一次不会再Load
            case E_FireType.One:
                Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation);
                break;
            case E_FireType.Two:
                Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position - this.transform.right * 0.5f, this.transform.rotation);
                Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position + this.transform.right * 0.5f, this.transform.rotation);
                break;
            case E_FireType.Three:
                Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation);
                Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation * Quaternion.AngleAxis(-20, Vector3.up));
                Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation * Quaternion.AngleAxis(20, Vector3.up));
                break;
            case E_FireType.Round:
                float angle = 360 / roundNum;
                for (int i = 0; i < roundNum; i++)
                    Instantiate(Resources.Load<GameObject>("Bullet"), this.transform.position, this.transform.rotation * Quaternion.AngleAxis(i * angle, Vector3.up));
                break;
        }
    }

    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏