1.在编辑器中动态读取文件

在实际的游戏开发中,其实有相当一部分的静态数据是可以放在客户端的,所以自然而然地产生了动态读取这些文件的需求,比如csv、xml等,不管是用什么系统做Unity的开发,如果想要实现这种效果,显然要先在编辑器中实现基本的功能,然后再去各个移动平台去测试,所以要读取外部文件的第一步,显然要再电脑端实现这个共嫩南瓜(编辑器)
下面举一个读取xml的例子-----读取xml文件并动态生成一个类

举例:

<?xml version="1.0" encoding="UTF-8"?>
<test><name>chenjd</name><blog>http://www.cnblogs.com/murongxiaopifu</blog><organization>Fanyoy</organization><age>25</age></test>

这是我们要加载的xml文件
将这个文件放在任意地方,通过指定地址,将其读取

public class Test2 : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){XElement result = LoadXML("Assets/xml-to-egg/Test.xml");Debug.Log(result.ToString());}private XElement LoadXML(string v){XElement xml = XElement.Load(v);return xml;}// Update is called once per framevoid Update(){}
}

读取效果如下:

待考虑的问题
1.不规范的地址,如果地址参数如上写,跨平台一定不对,出现的问题就是再移动端的Unity中找不到目标文件夹
2.使用的是电脑上传统的读取资源的做法,没有使用unity提供的方法,可能会找到文件,但是不一定能正确读取文件内容
以上是可能导致造成一东莞读取资源失败的原因,接下来先看一下第一个问题(关于不同移动平台上的资源路径问题)

2.移动平台的资源路径问题

我们知道,如果你想要读取一个文件,自然要找到这个文件,下表是unity中资源路径以及他们的介绍

unity3D中的路径 介绍
Application.dataPath 用于返回程序的数据文件所在的文件及的路径
Application.streamingAssetsPath 用于返回流数据的缓存目录,返回路径为相对路径
Application.persistentDataPath 用于返回一个持久化的数据储存目录的路径,可以在此路径下储存一些持久化的数据文件
Application.temporaryCachePath 返回临时数据的缓存目录
Android平台 具体路径
Application.dataPath /data/app/xxx.xxx.apk
Application.streamingAssetsPath jar:file:///data/app/xxx.xxx.apk/!assets
Application.persistentDataPath /data/data/xxx.xxx.xxx/files
Application.temporaryCachePath /data/data/xxx.xxx.xxx/cache
IOS平台 具体路径
Application.dataPath Application/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data
Application.streamingAssetsPath xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw
Application.persistentDataPath xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents
Application.temporaryCachePath xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches

是不是感觉很奇怪,我们知道再Unity编辑器中默认的资源文件存放路径就是Assets,怎么会出来这么多路径呢?
要解决这个疑问,先来看看unity中资源处理种类
再unity中涉及到的资源位置有以下几个类----------Resources、StreamingAssets、AssetBundle、PersistentDataPath
Resources:作为unity的保留文件夹出现的,也就是说,如果你创建的文件夹的名字与这个名字重名,那么在打包的时候里面的内容同要会被无条件的打包到发布包中,其特点有:
1.只读(不能修改)
2.会将文件夹中的内容打包集成到.assets中,建议放一些Prefab
3.主线程加载
4.资源读取用Resources.load()

StreamingAssets:与Resources很像,同样作为保留文件夹出现,但是不同的是,前者会被压缩和加密,erStreamingAssets不会,它主要用来放一些二进制文件,特点如下
1.只读不可写
2主要存放二进制文件
只能用WWW类来读取

AssetBundle:简而言之就是把Prefab或者二进制文件封装成AssetBundle文件(也是一种二进制)需要注意的是在移动端无法更新脚本
特点如下:
1.unity定义的二进制类型
2.最好将Prefab分装成AssetBundle,但是刚才说移动端无法更新脚本又是怎么回事?只要这个prefab上面挂载的是本地脚本是可以的
3.使用www加载

persistentDataPath:看上去它 就是一个路径,实际上在在这个路径下是可读可写的
特点:内容可读可写,不过只能运行时才能写入或者读取,提前将数据存入这个路径是不行的
2.无内容限制,你可以从StreamingAsset中读取二进制文件就或者从AssetBundle读取文件来写入这里
3.写下的文件是可以在电脑上查看,同样可以清理掉

介绍完这几个资源处理种类下面举几个例子来实现读取外部资源的过程

1.利用Resources读取
在unity中创建文件夹Resources,将Test.xml复制一份,通过Respurces读取
代码如下

using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using UnityEngine;public class Test3 : MonoBehaviour
{private string _result;// Start is called before the first frame updatevoid Start(){LoadXML("Test");}private void LoadXML(string v){_result = Resources.Load(v).ToString();XmlDocument doc = new XmlDocument();doc.LoadXml(_result);}private void OnGUI(){GUIStyle titlestyle = new GUIStyle();titlestyle.fontSize = 20;titlestyle.normal.textColor = new Color(0, 1, 1);GUI.Label(new Rect(400, 10, 500, 20), _result, titlestyle);}// Update is called once per framevoid Update(){}
}

绘制结果如下

2.利用StreamingAssets
创建StreamingAssets文件夹,并将xml文件复制一份
加载代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test4 : MonoBehaviour
{string _result;// Start is called before the first frame updatevoid Start(){StartCoroutine(LoadXML());}IEnumerator LoadXML(){string sPath = Application.streamingAssetsPath + "/Test.xml";WWW wWW = new WWW(sPath);yield return wWW;_result = wWW.text;}private void OnGUI(){GUIStyle titlestyle = new GUIStyle();titlestyle.fontSize = 20;titlestyle.normal.textColor = new Color(0, 1, 1);GUI.Label(new Rect(400, 10, 500, 20), _result, titlestyle);}// Update is called once per framevoid Update(){}
}

上文说过,必须使用www来进行加载,否则会报空异常的错误
运行结果

利用AssetBundle
1.创建一个空的Prefab,命名Cube,然后创建一个Cube,将其拉到刚创建好的Prefab
2.新建一个脚本ExportAssetBundles.cs(代码来自官方文档),保存在Asset/Editor目录下

//在Unity编辑器中添加菜单
[MenuItem("Assets/Build AssetBundle From Selection")]
static void ExportResourceRGB2()
{  // 打开保存面板,获得用户选择的路径  string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "assetbundle");  if (path.Length != 0)  {  // 选择的要保存的对象  Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);  //打包  BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows);  }
}

3.选中预设Cube,运行Build AssetBundle From Selection。这时会弹出一个保存框,将其命名为cube.unity3d(这里为了测试方便,放在c盘。实际项目中,我们是需要将他们放在web服务器,供所有客户端下载更新)
4.新建一个场景scene1.unity,上面放置几个模型,然后保存
5.选中该场景,在之前的ExportAssetBundles.cs脚本中添加打包场景的函数,运行Assets->Build Scene,保存为scene1.unity3d(这里为了测试方便,也放在c盘)

[MenuItem("Assets/Save Scene")]
static void ExportScene()
{  // 打开保存面板,获得用户选择的路径  string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");  if (path.Length != 0)  {  // 选择的要保存的对象  Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);  string[] scenes = {"Assets/scene1.unity"};  //打包  BuildPipeline.BuildPlayer(scenes,path,BuildTarget.StandaloneWindows,BuildOptions.BuildAdditionalStreamedScenes);  }
}

a.AssetBundle的保存后缀名可以是assetbundle或者unity3d
b.BuildAssetBundle要根据不同的平台单独打包,BuildTarget参数指定平台,如果不指定,默认的webplayer

加载assetbundle

using System;
using UnityEngine;
using System.Collections;  public class Load: MonoBehaviour
{  private string BundleURL = "file:///C:/cube.assetbundle";  private string SceneURL = "file:///C:/scene1.unity3d";  void Start()  {  //BundleURL = "file//"+Application.dataPath+"/cube.assetbundle";  Debug.Log(BundleURL);  StartCoroutine(DownloadAssetAndScene());  }  IEnumerator DownloadAssetAndScene()  {  //下载assetbundle,加载Cube  using (WWW asset = new WWW(BundleURL))  {  yield return asset;  AssetBundle bundle = asset.assetBundle;  Instantiate(bundle.Load("Cube"));  bundle.Unload(false);  yield return new WaitForSeconds(5);  }  //下载场景,加载场景  using (WWW scene = new WWW(SceneURL))  {  yield return scene;  AssetBundle bundle = scene.assetBundle;  Application.LoadLevel("scene1");  }  }
}

这样就可以加载外部或者服务器上的资源了

使用Resources类加载资源
通过Resources类何以轻易的找到并访问我们想要得到的资源对象,例如使用这个类的FindObjectsTypeAll来获取当前场景中的资源信息
签名如下

public static object[] FindObjectsOfTypeAll(Type type)

它只需要返回一个Type类型的参数typr,用来搜寻资源时和获取与type相匹配的类型,并且返回一个Object数组,它能够获取的对象类型包括了Unity3d能够加载的所有资源类型,如游戏对象,预制体、材质、Mesh、贴图等,需要注意的是,这个方法运行消耗较大,不适合每一帧都调用
举例使用

private void OnGUI(){GUILayout.Label("All" + Resources.FindObjectsOfTypeAll(typeof(UnityEngine.Object)));}

除了这中用法,还有一个静态方法是Load
方法签名如下

public static Object Load(string path);
public static Object Load(string path, [NotNull] Type systemTypeInstance);

需要注意的是,参数path并非是完整路径,而是先对于当前工程中Assets目录下的Resources文佳佳的路径,第二个参数则是用来作为过滤返回的对象,如果提供了第二个参数,那么只有和type类型相同的对象能够被返回

void Start () {GameObject go = GameObject.CreatePrimitive(PrimitiveType.Plane);Renderer rend = go.GetComponent<Renderer>();rend.material.mainTexture = Resources.Load("glass") as Texture;}

利用WWW类的构造函数实现资源下载
www的构造函数有几种重载版本,一般使用的是只有一个string参数的方法,签名如下

public WWWW(string url)

这里面的string参数标识WWW要从URL所提供的地址下载资源,由于这是WWW的构造函数,一旦资源下载完成,就可以通过类对象访问下载的资源对象,除了创建一个新的WWW类的对象意外,该方法还会创建并发送一个GET请求,紧接着一个数据流会被创建并且开始进行下载,此时必须等待整个下载流程完成,然后才可以通过WWW类的对象访问下载得到的资源对象,而由于数据流可以通过yeild关键字被方便的挂起,所以很方便,举例如下

public string url = "http://image.earthcam.com/ec_metros/ourcame/fridays.jpg";IEnumerator Start () {WWW www = new WWW(url);yield return www;Image s = this.GetComponent<Image>();Sprite sprite = Sprite.Create(www.texture,new Rect(0,0,www.texture.width,www.texture.height),new Vector2(0,0));s.overrideSprite= sprite ;Debug.Log("sucess");}

本文介绍了几种再unity开发过程中,实际再读取外部资源的几种操作,当然还有很多别的方式。

unity读取外部资源相关推荐

  1. java读取外部文件_(转)JAVA读取外部资源的方法

    在java代码中经常有读取外部资源的要求:如配置文件等等,通常会把配置文件放在classpath下或者在web项目中放在web-inf下. 1.从当前的工作目录中读取: try{ BufferedRe ...

  2. 匹夫细说Unity3D(一)——移动平台动态读取外部文件全解析

    前言: 一直有个想法,就是把工作中遇到的坑通过自己的深挖总结成一套相同 问题 的解决方案供各位同行拍砖探讨.眼瞅着2015年第一个工作日就要来到了,小匹夫也休息的差不多了,寻思着也该写点东西活动活动大 ...

  3. 慕容小匹夫 Unity3D移动平台动态读取外部文件全解析

    Unity3D移动平台动态读取外部文件全解析 c#语言规范 阅读目录 前言: 假如我想在editor里动态读取文件 移动平台的资源路径问题 移动平台读取外部文件的方法 补充: 回到目录 前言: 一直有 ...

  4. Unity 打包和读取AB资源,并播放打包的AB序列图!

    Unity - 打包和读取AB资源,并播放打包的AB序列图! 一:效果图 二:插件下载 三:插件导入! 三:代码! 四:Demo学习 五:关于AB资源打包的学习和拓展 本文提供详细教程 记录遇到的难点 ...

  5. spark-submit --files 动态加载外部资源文件

    在做spark时,有些时候需要加载资源文件,需要在driver或者worker端访问.在client模式下可以使用IO流直接读取,但是在cluster模式下却不能直接读取,需要如下代码: val is ...

  6. 乐高ev3 读取外部数据_数据就是新乐高

    乐高ev3 读取外部数据 When I was a kid, I used to love playing with Lego. My brother and I built almost all k ...

  7. 利用Python读取外部数据文件

    不论是数据分析,数据可视化,还是数据挖掘,一切的一切全都是以数据作为最基础的元素.利用Python进行数据分析,同样最重要的一步就是如何将数据导入到Python中,然后才可以实现后面的数据分析.数据可 ...

  8. Android热修复技术初探(三):动态加载外部资源

    前面已经介绍了Android平台上的几种ClassLoader,这几种ClassLoader都有各自的使用场景,有了这些基础知识之后,才能更好地理解以及探究Android热修复技术.首先我们来探究怎么 ...

  9. Unity读取项目文件夹图片,PC端

    1.创建场景,添加UI--Canvas,Canvas下添加Scroll View. 如下图 2.在Scroll View下的Content下添加脚本Open,添加Grid Layout Group. ...

  10. Spark动态加载外部资源文件

    Spark动态加载外部资源文件 1.spark-submit --files 动态加载外部资源文件 之前做一个关于Spark的项目时,因项目中需要读取某个静态资源文件,然后在本地IDEA测试一切皆正常 ...

最新文章

  1. 分类算法之朴素贝叶斯分类(Naive Bayesian classification)
  2. 面向对象程序设计案例
  3. 微软开源Power Fx,基于Excel的低代码编程语言
  4. 基于TCP的在线聊天程序
  5. 居然之家完成35亿定增 小米、阿里等认购
  6. JavaScript中document.getElementById和document.write
  7. 優利系統眾裡尋“她”
  8. J2EE开发系列视频教程
  9. jsoup抓取网页+具体解说
  10. WPS快捷键之 通用基础
  11. 拾方易公众号运营成本低么?
  12. ODM、JDM、OEM概念
  13. 视频批量添加滚动字幕,我1分钟就搞定了
  14. 沉默的羔羊--电影影评
  15. cmd 查看端口占用并且结束进程【建议收藏】
  16. C++中的dynamic_cast和static_cast转化
  17. 《网络安全法》及其法律体系介绍
  18. 西泽金融: 银行业的下半场
  19. Unity游戏开发客户端面经——网络(初级)
  20. 【经典密码】移位密码和代换密码的实现

热门文章

  1. opencv保存的avi视频不能打开
  2. DFB发射器件功率要求理论计算
  3. 网易视频云技术干货:分布式搜索elasticsearch集群监控工具bigdesk
  4. 初了解NLP---科大讯飞
  5. 高级同步器:倒计时门闩
  6. FPGA的IO到底是怎么命名的?
  7. mysql进阶-用户的创建_修改_删除
  8. https://aka.ms/ 无法访问的问题
  9. 封条格式用word怎么打_《密封条格式大全》word版.doc
  10. SpringMVC源码总结(十二)ViewResolver介绍