填补Resources和WWW加载本地资源的坑
总的来说Resources和WWW加载本地资源坑比较多,大多与路径有关。
下面代码构成了一个路径的预读模块:
此模块主要解决的坑是:Resources或WWW加载本地的文件夹中的多个文件时,无法获取文件夹下的文件名称的坑,原因是Resources路径和StreamingAssets路径下打包到安卓安装后路径都不再存在的问题。想要读取Resources路径或StreamingAssets路径某个文件夹下的大量文件,找了好久都没找到方法。后来想了一个绕过此坑的办法,就是在程序未执行前先保存一份路径信息到场景中或保存成预设,运行时就可以访问了。
代码1.多叉树实现目录结构
using System;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 使用多叉树实现目录结构
/// </summary>
[Serializable]
public class PathStruct
{
/// <summary>
/// 目录名称或文件名称(不包含扩展名)
/// </summary>
public string name;
/// <summary>
/// 扩展名都是以“.”开头的
/// </summary>
public string extensionName;
/// <summary>
/// 是否是文件
/// </summary>
public bool isFile;
/// <summary>
/// 父节点
/// </summary>
[NonSerialized]
public PathStruct parent;
/// <summary>
/// 子节点
/// </summary>
public List<PathStruct> children = new List<PathStruct>();
/// <summary>
/// 文件夹结构构造函数
/// </summary>
/// <param name="name"></param>
/// <param name="parent"></param>
/// <param name="children"></param>
public PathStruct(string name, PathStruct parent, List<PathStruct> children = null)
{
this.name = name;
this.parent = parent;
this.children = children;
if (parent != null)
parent.AddChild(this);
if (children == null)
this.children = new List<PathStruct>();
}
/// <summary>
/// 文件结构构造函数
/// </summary>
/// <param name="name"></param>
/// <param name="parent"></param>
/// <param name="extensionName"></param>
public PathStruct(string name, PathStruct parent, string extensionName)
{
this.name = name;
this.parent = parent;
this.extensionName = extensionName;
isFile = true;
if (parent != null)
parent.AddChild(this);
if (children == null)
children = new List<PathStruct>();
}
/// <summary>
/// 放回从父物体到此物体的完整路径,物体间用'/'隔开
/// </summary>
/// <returns></returns>
public override string ToString()
{
if (parent == null || string.IsNullOrEmpty(parent.name))
return name;
return parent +"/"+ name;
}
/// <summary>
/// 输出从根节点到此节点的完整路径(相对完整,并不是绝对路径)
/// </summary>
/// <param name="isContainsExtension">是否包括文件扩展名</param>
/// <returns></returns>
public string ToString(bool isContainsExtension)
{
if(isContainsExtension)
return parent + "/" + name+extensionName;
return ToString();
}
/// <summary>
/// 增加子节点
/// </summary>
/// <param name="pathStruct"></param>
public void AddChild(PathStruct pathStruct)
{
children.Add(pathStruct);
pathStruct.parent = this;
}
/// <summary>
/// 增加子节点
/// </summary>
/// <param name="pathStruct"></param>
public void AddChildren(List<PathStruct> pathStructs)
{
children.AddRange(pathStructs);
foreach (var pathStruct in pathStructs)
{
pathStruct.parent = this;
}
}
/// <summary>
/// 获取该节点下所有子节点的完整路径(相对完整,并不是绝对路径)
/// </summary>
/// <param name="isContainsExtension"></param>
/// <returns></returns>
public List<string> GetChildrenFullPath(bool isContainsExtension)
{
if (children == null || children.Count == 0) return null;
var res = new List<string>(children.Count);
foreach (var pathStruct in children)
{
if (pathStruct.name != null)
{
res.Add(pathStruct.ToString(isContainsExtension));
}
}
return res;
}
/// <summary>
/// 获取该节点下所有子节点的名称(相对完整,并不是绝对路径)
/// </summary>
/// <param name="isContainsExtension"></param>
/// <returns></returns>
public List<string> GetChildrenNames(bool isContainsExtension)
{
if (children == null) return null;
var res = new List<string>(children.Count);
foreach (var pathStruct in children)
{
if (pathStruct.name != null)
{
res.Add(pathStruct.name + (isContainsExtension?extensionName:""));
}
}
return res;
}
/// <summary>
/// 打印出该节点下所有节点
/// </summary>
/// <param name="isFullPath"></param>
/// <param name="isContainsExtension"></param>
public void PrintAll(bool isFullPath = false ,bool isContainsExtension = false)
{
if(isFullPath)
Debug.Log(ToString(isContainsExtension));
else
Debug.Log(name);
if (children != null)
{
foreach (var pathStruct in children)
{
pathStruct.PrintAll(isFullPath, isContainsExtension);
}
}
}
/// <summary>
/// 在子节点中查找符合条件的节点
/// </summary>
/// <param name="condition"></param>
/// <param name="isFindChild"></param>
/// <returns></returns>
public PathStruct Find(Func<PathStruct,bool> condition,bool isFindChild = false)
{
if (children == null) return null;
foreach (var pathStruct in children)
{
if (condition(pathStruct))
return pathStruct;
if (isFindChild)
{
var pathS = pathStruct.Find(condition, isFindChild);
if (pathS != null)
return pathS;
}
}
return null;
}
/// <summary>
/// 在子节点中查找符合条件的节点
/// </summary>
/// <param name="condition"></param>
/// <param name="isFindChild"></param>
/// <returns></returns>
public List<PathStruct> FindAll(Func<PathStruct, bool> condition, bool isFindChild = false)
{
if (children == null) return null;
var res = new List<PathStruct>();
foreach (var pathStruct in children)
{
if (condition(pathStruct))
res.Add( pathStruct);
if (isFindChild)
{
var pathSS = pathStruct.FindAll(condition, isFindChild);
if (pathSS != null)
res.AddRange( pathSS);
}
}
return res;
}
/// <summary>
/// 重新根据子节点信息给各节点装入父节点信息
/// </summary>
public void ResetParent()
{
if (children != null)
foreach (var pathStruct in children)
{
pathStruct.parent = this;
pathStruct.ResetParent();
}
}
}
代码2. 运行在Editor模式下的菜单命令,此代码应该存放在某个Editor目录下
using CommonUtilities;
using UnityEditor;
using UnityEngine;
public class PathStructionBuilder
{
[MenuItem("Path/Create Resouces Path Info To Current Scene")]
static void CreateGObyResources()
{
var resourcesPath = Application.dataPath + "/Resources/";
Debug.Log("resourcesPath: "+ resourcesPath);
ResourcesPathAccess.Instance.root = new PathStruct("",null);
CreatePathStruct(resourcesPath, ResourcesPathAccess.Instance.root);
ResourcesPathAccess.Instance.root.PrintAll(true);
}
[MenuItem("Path/Create StreamingAssets Path Info To Current Scene")]
static void CreateGObyStreamingAssets()
{
var streamingAssets = Application.dataPath + "/StreamingAssets/";
Debug.Log("StreamingAssets: " + streamingAssets);
StreamingAssetAccess.Instance.root = new PathStruct("", null);
CreatePathStruct(streamingAssets, StreamingAssetAccess.Instance.root);
StreamingAssetAccess.Instance.root.PrintAll(true);
}
public static void CreatePathStruct(string path,PathStruct parent)
{
var files = FileHelper.GetFileNames(path);
foreach (var p in files)
{
if (p.Contains(".meta"))
continue;
new PathStruct(GetPathName(p), parent, GetFileExtensionName(p));
Debug.Log("增加文件: " + p);
}
var paths = FileHelper.GetDirectories(path);
foreach (var p in paths)
{
var pathStruct = new PathStruct(GetPathName(p), parent);
Debug.Log("增加路径: " + p);
CreatePathStruct(p, pathStruct);
}
}
private static string GetFileExtensionName(string pathName)
{
return FileHelper.GetExtension(pathName);
}
public static string GetPathName(string path)
{
return FileHelper.GetFileNameNoExtension(path);
}
}
代码3. Resources路径下的信息保存位置
using System;
using System.Collections.Generic;
using UnityEngine;
public class ResourcesPathAccess:SingleBhv<ResourcesPathAccess>
{
public PathStruct root;
public override void Init()
{
base.Init();
root.ResetParent();
}
public List<string> GetFileList(string resourceUri)
{
if (!isInited)
Init();
var ss = resourceUri.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var pathStruct = root;
foreach (var s in ss)
{
if (pathStruct != null)
pathStruct = pathStruct.Find(t => t.name == s);
else
Debug.LogError("resourceUri 错误!");
}
if (pathStruct != null)
{
return pathStruct.GetChildrenFullPath(false);
}
return null;
}
}
代码4. StreamingAssets路径下的信息保存位置
using System;
using System.Collections.Generic;
using UnityEngine;
public class StreamingAssetAccess : SingleBhv<StreamingAssetAccess>
{
public PathStruct root;
public override void Init()
{
base.Init();
root.ResetParent();
}
public List<string> GetFileList(string resourceUri)
{
if(!isInited)
Init();
var ss = resourceUri.Split(new []{'/'},StringSplitOptions.RemoveEmptyEntries);
var pathStruct = root;
List<string> res = new List<string>();
foreach (var s in ss)
{
if (pathStruct != null)
pathStruct = pathStruct.Find(t=>t.name == s);
else
Debug.LogError("resourceUri 错误!");
}
if (pathStruct != null)
{
res = pathStruct.GetChildrenFullPath(true);
}
for (int index = 0; index < res.Count; index++)
{
res[index] = PathTool.Instance.GetSystemHeadPath() + PathTool.Instance.GetStreamAssetsPath() + res[index];
}
return res;
}
}
(其中用到了单例SingleBhv<T>,请参考:http://www.cnblogs.com/fuliufuliu/p/4860685.html)
使用时可以这样:
StreamingAssetAccess.Instance.GetFileList(packageName);
ResourcesPathAccess.Instance.GetFileList(packageName);
遗憾的是在每次编译时和执行时会报红,不过这个错误暂时没发现此红对程序有什么不妥(希望大神指点):
填补Resources和WWW加载本地资源的坑的更多相关文章
- [IOS]UIWebView 请求网络页面或者加载本地资源页面
UIWebView是一个能够显示网页的IOS视图控件,我们可以用它来访问一个网站.下面是具体的实例: 操作步骤: 1.首先在xib文件中拖放一个UIWebView控件到view中 2.将下载的页面以及 ...
- iOS webView 远程html加载本地资源
昨天,一个朋友让我帮他在IOS上弄这样一件事情: webView 调用远程URL,并且让远程的web 通过自定义标签能实现内嵌本地的图片.js 或音频等. 比如:在服务器端 的html文件中 这样写到 ...
- iOS WebView 加载本地资源(图片,文件等)
https://www.cnblogs.com/dhui69/p/5596917.html iOS WebView 加载本地资源(图片,文件等) NSString *path = [[NSBundle ...
- 引入外部 CDN失效时--怎么加载本地资源文件(本文以jquery为例)
相信大家都使用过CDN静态资源库,比如下面 CDN官方静态资源库:https://cdnjs.com/ 七牛前端公开库:http://staticfile.org (vue,react,nl都有) ...
- MFC CDHtmlDialog 加载本地资源
步骤:1.资源视图 项目右击选择资源添加,自定义添加新类型 如:JS(会增加JS文件夹)2. 选择1新建的文件夹右击 添加资源 导入 选择js文件引入3. 在资源文件Resource.h文件夹能找到资 ...
- qt webengineview 加载本地资源方式
一.如果把资源添加到本地资源qrc库里了,请使用 ui->preview->setUrl(QUrl("qrc:/HelloWorld2.html")): 二.如果没有现 ...
- 转:Android Webview 加载外部html时选择加载本地的js,css等资源文件
原文地址:http://m.blog.csdn.net/blog/qduningning/43196819 在使用WebView加载网页的时候,有一些固定的资源文件如js的jquery包,css,图片 ...
- Swift - 网页控件(UIWebView)加载本地数据,文件
使用UIWebView加载本地数据或资源有如下三种方式: 1,使用loadHTMLString方法加载HTML内容 2,使用loadRequest方法加载本地资源(也可用于加载服务器资源) 3,先将内 ...
- 使用three.js加载3dmax资源,以及实现场景中的阴影效果
使用three.js可以方便的让我们在网页中做出各种不同的3D效果.如果希望2D绘图内容,建议使用canvas来进行.但很多小伙伴不清楚到底如何为我们绘制和导入的图形添加阴影效果,更是不清楚到底如何导 ...
随机推荐
- R语言基础
一.扩展包的基本操作语句R安装好之后,默认自带了"stats" "graphics" "grDevices" "utils&qu ...
- Scrapy爬虫导图(持续完善中)
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中.
- JAV07接口与继承之动手动脑问题解决
动手动脑:请自行编写代码测试以下特性:在子类中,若要调用父类中被覆盖的方法,可以使用super关键字. 1.源代码: package Work; class A{ public A(){ System ...
- 做为一名PHP程序员,应该关注的互联网IT大牛!
俗话说:“读万卷书不如行万里路,行万里路不如高人指路”,做为一名新人,以后的路还很长,多年你的成就取决于今天的自己付出,选中自己的方向比什么都重要,关注大牛,向他们学习,才不会迷失自己! 1.惠新宸( ...
- C#验证码的生成
HTML <ul> <li>验证码:</li> <li> <img src="/Login/GetValidateCode?ID=1&q ...
- jfinal基本应用 --报主键重复
在使用jfinal 的Model过程中有一个很怪异的问题,发布到服务器上,只要是往表中添加字段,就报主键重复. 1.我添加表的时候调用了 public void create(Map map){ St ...
- thinkjs中自定义sql语句
一直以为在使用thinkjs时,只能是它自带的sql语句查询,当遇到类似于这样的sql语句时,却不知道这该怎样来写程序,殊不知原来thinkjs可以执行自定义sql语句 SELECT * from a ...
- Python查找当前路径和子路径下指定后缀名的文件
# -*- encoding:utf-8 -*- import os def SearchFile(path,text): try: files=os.listdir(path) for f in f ...
- iOS中 HTTP/Socket/TCP/IP通信协议详解
// OSI(开放式系统互联), 由ISO(国际化标准组织)制定 // 1. 应用层 // 2. 表示层 // 3. 会话层 // 4. 传输层 // 5. 网络层 // 6. 数据链接层 // 7. ...
- PHP分页代码
} <a href="fenye.php?page=<?php echo <?php } <a href="fenye ...