最新文章
Cocos2d-x游戏开发实例详解7:对象释放时机
03-25 13:59
Cocos2d-x游戏开发实例详解6:自动释放池
03-25 13:55
Cocos2d-x游戏开发实例详解5:神奇的自动释放
03-25 13:49
Cocos2d-x游戏开发实例详解4:游戏主循环
03-25 13:44
Cocos2d-x游戏开发实例详解3:无限滚动地图
03-25 13:37
Cocos2d-x游戏开发实例详解2:开始菜单续
03-25 13:32
unity3d本地数据存放路径
最近在做移动平台的版本控制时,涉及到 Unity3D 本地数据存放路径的问题,在此将相关内容分享给大家。我们的操作流程是先从服务器端加载资源,将其读取到本地,之后再从本地读取资源。以 PC 平台为例,手机、平板等移动平台的操作类似,仅需对路径进行简单修改。
不同平台路径的预编译
不同平台下 StreamingAssets 的路径有所不同,以下是相应的预编译代码:
// 不同平台下 StreamingAssets 的路径是不同的,这里需要注意一下。
public static readonly string PathURL =
#if UNITY_ANDROID // 安卓
"jar:file://" + Application.dataPath + "!/assets/";
#elif UNITY_IPHONE // iPhone
Application.dataPath + "/Raw/";
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR // windows 平台和编辑器环境
"file://" + Application.dataPath + "/StreamingAssets/";
#else
string.Empty;
#endif
操作步骤
1. 创建脚本
创建一个名为 Text.cs 的脚本,并将其拖放到 MainCamera 中。以下是脚本的详细代码:
using UnityEngine;
using System.Collections;
using System.IO;
using System.Collections.Generic;
using System;
public class Text : MonoBehaviour {
// 文本中每行的内容
ArrayList infoall;
// 皮肤资源,这里用于显示中文
public GUISkin skin;
void Start () {
print("当前文件路径:" + Application.persistentDataPath);
// 删除文件
DeleteFile(Application.persistentDataPath, "FileName.txt");
// 创建文件,共写入 3 次数据
CreateFile(Application.persistentDataPath, "FileName.txt", "dingxiaowei");
CreateFile(Application.persistentDataPath, "FileName.txt", "丁小未");
// CreateFile(Application.persistentDataPath, "Filename.assetbundle", "丁小未");
// 下载模型
StartCoroutine(loadasset("http://192.168.1.180/3DShowResource/Products/AssetBundles/HX_DY02.assetbundle"));
// 得到文本中每一行的内容
infoall = LoadFile(Application.persistentDataPath, "FileName.txt");
}
// 写入模型到本地
IEnumerator loadasset(string url) {
WWW w = new WWW(url);
yield return w;
if (w.isDone) {
byte[] model = w.bytes;
int length = model.Length;
// 写入模型到本地
CreateModelFile(Application.persistentDataPath, "Model.assetbundle", model, length);
}
}
void CreateModelFile(string path, string name, byte[] info, int length) {
// 文件流信息
Stream sw;
FileInfo t = new FileInfo(path + "/" + name);
if (!t.Exists) {
// 如果此文件不存在则创建
sw = t.Create();
} else {
// 如果此文件存在则直接返回
return;
}
// 写入信息
sw.Write(info, 0, length);
// 关闭流
sw.Close();
// 销毁流
sw.Dispose();
}
/**
* path:文件创建目录
* name:文件的名称
* info:写入的内容
*/
void CreateFile(string path, string name, string info) {
// 文件流信息
StreamWriter sw;
FileInfo t = new FileInfo(path + "/" + name);
if (!t.Exists) {
// 如果此文件不存在则创建
sw = t.CreateText();
} else {
// 如果此文件存在则打开
sw = t.AppendText();
}
// 以行的形式写入信息
sw.WriteLine(info);
// 关闭流
sw.Close();
// 销毁流
sw.Dispose();
}
/**
* 读取文本文件
* path:读取文件的路径
* name:读取文件的名称
*/
ArrayList LoadFile(string path, string name) {
// 使用流的形式读取
StreamReader sr = null;
try {
sr = File.OpenText(path + "/" + name);
} catch (Exception e) {
// 路径与名称未找到文件则直接返回空
return null;
}
string line;
ArrayList arrlist = new ArrayList();
while ((line = sr.ReadLine()) != null) {
// 一行一行的读取
// 将每一行的内容存入数组链表容器中
arrlist.Add(line);
}
// 关闭流
sr.Close();
// 销毁流
sr.Dispose();
// 将数组链表容器返回
return arrlist;
}
// 读取模型文件
IEnumerator LoadModelFromLocal(string path, string name) {
string s = null;
#if UNITY_ANDROID
s = "jar:file://" + path + "/" + name;
#elif UNITY_IPHONE
s = path + "/" + name;
#elif UNITY_STANDALONE_WIN || UNITY_EDITOR
s = "file://" + path + "/" + name;
#endif
WWW w = new WWW(s);
yield return w;
if (w.isDone) {
Instantiate(w.assetBundle.mainAsset);
}
}
/**
* path:删除文件的路径
* name:删除文件的名称
*/
void DeleteFile(string path, string name) {
File.Delete(path + "/" + name);
}
void OnGUI() {
// 用新的皮肤资源,显示中文
GUI.skin = skin;
// 读取文件中的所有内容
foreach (string str in infoall) {
// 绘制在屏幕当中
GUILayout.Label(str);
}
if (GUILayout.Button("加载模型")) {
StartCoroutine(LoadModelFromLocal(Application.persistentDataPath, "Model.assetbundle"));
}
}
}
代码解释
上述代码涉及文件流操作,使用了 Application.persistentDataPath 而未使用 Application.dataPath。因为 Application.dataPath 在移动平台可能无法正常访问,而 Application.persistentDataPath 是所谓的沙盒文件路径,具有读写权限。
运行效果
运行代码后,演示了读取操作文本和打包文件的功能。如果切换到移动平台,可能会出现中文字体无法显示的问题,此时需要对字体进行相应设置。后续会继续进行版本控制的相关工作。