目录
一、目的:
1、想知道:Unity安卓配置文件:读和写
1、想知道:Unity在电脑端找到配置文件可以通过Resources来加载,但是发布到手机上面时候就找到不到这个配置文件了,所以需要一种安卓能读配置文件的方法
二、参考:
1、unity 移动端(仅安卓)读写Xml
1、unity 读写安卓xml配置文件——记录贴
三、注意
1、读取时候有个时间,所以其他的代码延迟一会儿执行,比如使用
四、操作:一:完成:读取没有写入:不使用协程(每次都会创建一次配置文件、不会出现协程中配置文件没有读取完,别的程序就执行的情况)(暂时没有添加修改、保存配置文件的方法)
1、代码:
1、配置文件
1、运行效果:电脑
1、运行效果:手机
四、操作:二:完成:读写功能都有:使用协程:
1、研究了很久,一路上都是坑,终于弄好了安卓读取配置文件的方法,下面是一步步步骤,直接照做就可以实现安卓读取配置文件
1、思路:StreamingAssets里有一个xml文件,persistentDataPath第一次时候需要读取StreamingAssets里的xml文件,如果没有就会在PC或者安卓端创建一个xml,程序都是对persistentDataPath的xml文件进行读写操作
1、代码:
1、解析:
1、xml文件
1、运行效果:电脑端
1、运行效果:安卓端
1、注意
一、目的:
1、想知道:Unity安卓配置文件:读和写
1、想知道:Unity在电脑端找到配置文件可以通过Resources来加载,但是发布到手机上面时候就找到不到这个配置文件了,所以需要一种安卓能读配置文件的方法
二、参考:
1、unity 移动端(仅安卓)读写Xml
- ①总结:good:借鉴了,下面自己写的是详细过程;but:无法全部实现,需要修改
1、unity 读写安卓xml配置文件——记录贴
- ①总结:good:借鉴了,下面自己写的是详细过程;but:无
三、注意
1、读取时候有个时间,所以其他的代码延迟一会儿执行,比如使用
1.Invoke(函数名称字符串,几秒种后执行); 这种调用方法只会执行一次。
2.InvokeRepeating(函数名称字符串,几秒钟后开始,间隔秒数);这种调用
四、操作:一:完成:读取没有写入:不使用协程(每次都会创建一次配置文件、不会出现协程中配置文件没有读取完,别的程序就执行的情况)(暂时没有添加修改、保存配置文件的方法)
1、代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Xml;
/// <summary>
/// 功能:读取所有配置文件
/// </summary>
public class My_test10_config : MonoBehaviour
{
#region["蝴蝶的配置文件"]
/// <summary>蝴蝶飞行的速度</summary>
[HideInInspector]
public float flySpeed = -1;
/// <summary>蝴蝶允许的与目标点最小距离,小于这个距离说明蝴蝶靠近目标点了</summary>
[HideInInspector]
public float allowDistanceMin = -1;
/// <summary>蝴蝶允许的与目标点最小距离,小于这个距离说明蝴蝶靠近目标点了</summary>
[HideInInspector]
public float distanceMinNeedMoveAwayUI = -1;
/// <summary>蝴蝶允许在UI中的最长时间,超过这个时间蝴蝶就要飞走,单位:秒</summary>
[HideInInspector]
public float time_allowAtUIMax = -1;
/// <summary>蝴蝶被点击后多久才消失,单位:秒</summary>
[HideInInspector]
public float time_howLongDestroy = -1;
/// <summary>float类型:蝴蝶诞生的间隔</summary>
[HideInInspector]
public float time_interval_createButterfly = -1;
/// <summary>int类型:蝴蝶在场景中同时出现的总数量</summary>
[HideInInspector]
public int totalNum_butterfly = -1;
#endregion
private string str_configName = "config.xml";
private void Awake()
{
GetPath02();
}
/// <summary>
/// 功能:通过不同的平台,找到配置文件位置
/// 准备修改GetPath的缺点
/// 缺点:
/// 网页:
/// </summary>
public void GetPath02()
{
string localPath;
if (Application.platform == RuntimePlatform.Android)
{
localPath = "jar:file://" + Application.dataPath + "!/assets" + "/test10/" + str_configName; //在Android中实例化WWW不能在路径前面加"file://"
Debug.Log(localPath);
}
else
{
localPath = "file://" + UnityEngine.Application.streamingAssetsPath + "/" + "test10/" + str_configName;//在Windows中实例化WWW必须要在路径前面加"file://"
Debug.Log(localPath);
}
CopyFiles02(localPath);
}
/// <summary>
/// 安卓写xml:
/// 网页:
/// 缺点:第一次运行的时候,会出现没有没有配置文件报错,因为那时候还没有创建配置文件在电脑上面
/// </summary>
private void CopyFiles02(string path)
{
WWW www = new WWW(path);
print("www.bytes"+www.bytes);
// yield return www;
if (www.isDone)
{
string newPath = Application.persistentDataPath + "/" + str_configName;
// string newPath = Application.persistentDataPath + "/" +"test10/"+ str_configName;
if (File.Exists(newPath))
{
//如果缓存的地方有配置文件就将其删除,换成最新的
print("如果缓存的地方有配置文件就将其删除,换成最新的,这样所有的只需要设置一个配置文件就可以了");
File.Delete(newPath);
File.WriteAllBytes(newPath, www.bytes);
}
else if (!File.Exists(newPath))
{
print("缓存的地方没有配置文件");
File.WriteAllBytes(newPath, www.bytes);
}
}
LoadXml();
}
/// <summary>
/// 安卓读xml:
/// 网页:
/// </summary>
public void LoadXml()
{
string path = Application.persistentDataPath + "/" + str_configName;
string strs = File.ReadAllText(path);
Debug.Log(strs);
MyDebug.Add(strs, "");
if (!File.Exists(path))
{
print("配置文件路径错误");
MyDebug.Add("配置文件路径错误", "");
return;
}
else if (File.Exists(path))
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(path);
XmlNodeList node = xmlDoc.SelectSingleNode("config").ChildNodes;
//遍历节点
foreach (XmlElement ele in node)
{
// Debug.Log(ele.Name);
if (ele.Name == "butterfly")
{
//蝴蝶
foreach (XmlElement i1 in ele.ChildNodes)
{
//Debug.Log(i1.Name);
switch (i1.Name)
{
case "flySpeed":
flySpeed = float.Parse(i1.InnerText);
if (flySpeed == -1)
MyDebug.Add("flySpeed:读取失败", "");
break;
case "distanceMinNeedMoveAwayUI":
distanceMinNeedMoveAwayUI = float.Parse(i1.InnerText);
string str1 = "distanceMinNeedMoveAwayUI:"+ distanceMinNeedMoveAwayUI;
MyDebug.Add(str1, "");
if (distanceMinNeedMoveAwayUI == -1)
MyDebug.Add("distanceMinNeedMoveAwayUI:读取失败", "");
break;
case "allowDistanceMin":
allowDistanceMin = float.Parse(i1.InnerText);
if (allowDistanceMin == -1)
MyDebug.Add("allowDistanceMin:读取失败", "");
break;
case "time_allowAtUIMax":
time_allowAtUIMax = float.Parse(i1.InnerText);
if (time_allowAtUIMax == -1)
MyDebug.Add("time_allowAtUIMax:读取失败", "");
break;
case "time_howLongDestroy":
time_howLongDestroy = float.Parse(i1.InnerText);
if (time_howLongDestroy == -1)
MyDebug.Add("time_howLongDestroy:读取失败", "");
break;
case "time_interval_createButterfly":
time_interval_createButterfly = float.Parse(i1.InnerText);
if (time_interval_createButterfly == -1)
MyDebug.Add("time_interval_createButterfly:读取失败", "");
break;
case "totalNum_butterfly":
totalNum_butterfly = int.Parse(i1.InnerText);
if (totalNum_butterfly == -1)
MyDebug.Add("totalNum_butterfly:读取失败", "");
break;
default:
print("配置文件内部有个节点读取失败");
MyDebug.Add("配置文件内部有个节点读取失败", "");
break;
}
}
}
}
}
}
}
1、配置文件
<config>
<butterfly>
<flySpeed>50</flySpeed>
<allowDistanceMin>6</allowDistanceMin>
<distanceMinNeedMoveAwayUI>20</distanceMinNeedMoveAwayUI>
<time_allowAtUIMax> 2</time_allowAtUIMax>
<time_howLongDestroy>0.1</time_howLongDestroy>
<time_interval_createButterfly>4</time_interval_createButterfly>
<totalNum_butterfly>4</totalNum_butterfly>
</butterfly>
</config>
<!--
配置文件修改了:PC端制定文件夹下面的文件也需要修改,因为PC端和移动端不一样的
flySpeed:蝴蝶飞行的速度
allowDistanceMin:蝴蝶允许的与目标点最小距离,小于这个距离说明蝴蝶到达目标点了
distanceMinNeedMoveAwayUI:需要离开目标点的最小距离,当小于这个距离时候,代表手指动了或者摄像头移动了,蝴蝶就要飞走了
time_allowAtUIMax:蝴蝶允许在UI中的最长时间,超过这个时间蝴蝶就要飞走,单位:秒
time_howLongDestroy:蝴蝶被点击后多久才消失,单位:秒
time_interval_createButterfly:蝴蝶诞生的间隔
totalNum_butterfly:蝴蝶在场景中同时出现的总数量
-->
1、运行效果:电脑
①没有运行前,电脑端缓存的地方没有配置文件
①运行后:电脑缓存的地方有了配置文件(目的:到时候安卓端的时候通过这个方法获取的都是缓存地方的配置文件,方便读写)
1、运行效果:手机
四、操作:二:完成:读写功能都有:使用协程:
1、研究了很久,一路上都是坑,终于弄好了安卓读取配置文件的方法,下面是一步步步骤,直接照做就可以实现安卓读取配置文件
1、思路:StreamingAssets里有一个xml文件,persistentDataPath第一次时候需要读取StreamingAssets里的xml文件,如果没有就会在PC或者安卓端创建一个xml,程序都是对persistentDataPath的xml文件进行读写操作
1、代码:
/// <summary>
/// 安卓读写xml:准备使用persistentDataPath读取到最初的xml文件,然后之后都是修改persistentDataPath文件
/// 结果: 成功,
/// 功能:
/// </summary>
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Xml;
using UnityEngine.UI;
public class MyTestXml05 : MonoBehaviour
{
private string xmlPath;
public static string id;
public static string score;
public Text text_xml;
private bool bIsCanShowConfig;//显示或者隐藏config
[HideInInspector]
public Vector3[] targetVec3;//目标3维坐标数组
private int targetNum;//目标个数
private string str_configName = "config02.xml";
/// <summary>
/// 功能:不同平台下不同的路径
/// </summary>
void Awake()
{
GetPath();
}
// Use this for initialization
void Start()
{
bIsCanShowConfig = false;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
{
ModifyConfig(0, 0, 123);
ModifyConfig(1, 1, 234);
ModifyConfig(2, 2, 45);
}
else if (Input.GetKeyDown(KeyCode.R))
{
LoadXml();
}
}
/// <summary>
///
/// 网页:
/// </summary>
public void GetPath()
{
string localPath;
if (Application.platform == RuntimePlatform.Android)
{
localPath = "jar:file://" + Application.dataPath + "!/assets" + "/" + str_configName; //在Android中实例化WWW不能在路径前面加"file://"
Debug.Log(localPath);
}
else
{
localPath = "file://" + UnityEngine.Application.streamingAssetsPath + "/" + str_configName;//在Windows中实例化WWW必须要在路径前面加"file://"
Debug.Log(localPath);
}
StartCoroutine(CopyFiles(localPath));
}
/// <summary>
/// 安卓写xml:
/// 网页:
/// </summary>
IEnumerator CopyFiles(string path)
{
WWW www = new WWW(path);
yield return www;
if (www.isDone)
{
string newPath = Application.persistentDataPath + "/" + str_configName;
if (!File.Exists(newPath))
{
File.WriteAllBytes(newPath, www.bytes);
}
}
// ReadXml();
LoadXml();
}
/// <summary>
/// 安卓读xml:
/// 网页:
/// </summary>
public void LoadXml()
{
string path = Application.persistentDataPath + "/" + str_configName;
string strs = File.ReadAllText(path);
if (File.Exists(path))
{
XmlDocument xmlDoc = new XmlDocument();
//根据路径将XML读取出来
xmlDoc.Load(path);
XmlElement team = (XmlElement)xmlDoc.SelectSingleNode("config");
string teamname = team.GetAttribute("name");
Debug.Log("这是一个名叫" + teamname + "的配置文件:");
XmlNodeList studentlist = team.ChildNodes;
Debug.Log("一共有" + studentlist.Count + "对象");
targetNum = studentlist.Count;
targetVec3 = new Vector3[targetNum];
for (int i = 0; i < studentlist.Count; i++)
{
string str_target_name = "target" + i.ToString();
foreach (XmlNode student in studentlist)
{
if (student.Name == str_target_name)
{
float.TryParse(student.Attributes["x"].Value, out targetVec3[i].x);
float.TryParse(student.Attributes["y"].Value, out targetVec3[i].y);
float.TryParse(student.Attributes["z"].Value, out targetVec3[i].z);
//MyDebug.Add(strs, 0);
text_xml.text = strs;
}
}
}
}
}
/// <summary>
///功能:点击:显示或者隐藏xml信息
/// </summary>
public void OnClick_ShowOrHideXml()
{
if (bIsCanShowConfig == false)
{
bIsCanShowConfig = true;
string path = Application.persistentDataPath + "/" + str_configName;
string strs = File.ReadAllText(path);
text_xml.text = strs;
}
else if (bIsCanShowConfig == true)
{
bIsCanShowConfig = false;
text_xml.text = "";
}
}
/// <summary>
///功能:修改配置文件
///参数: 【参数1:目标,从0开始】【参数2:轴,0=x轴 1=y轴 2=z轴】 【参数3:轴的值】
/// </summary>
public void ModifyConfig(int para_target, int para_axis, int para_value)
{
string path = Application.persistentDataPath + "/" + str_configName;
//string strs = File.ReadAllText(path);
if (File.Exists(path))
{
XmlDocument xmlDoc = new XmlDocument();
//根据路径将XML读取出来
xmlDoc.Load(path);
XmlElement team = (XmlElement)xmlDoc.SelectSingleNode("config");
XmlNodeList studentlist = team.ChildNodes;
string str_target_name = "target" + para_target.ToString();
string str_tmp_value = (para_value).ToString();
foreach (XmlNode student in studentlist)
{
if (student.Name == str_target_name)
{
Debug.Log("str_target_name:" + str_target_name);
switch (para_axis)
{
case 0:
student.Attributes["x"].Value = str_tmp_value;
Debug.Log("x被改了:");
break;
case 1:
student.Attributes["y"].Value = str_tmp_value;
Debug.Log("y被改了:");
break;
case 2:
student.Attributes["z"].Value = str_tmp_value;
Debug.Log("z被改了:");
break;
}
}
}
xmlDoc.Save(path);
}
}
}
1、解析:
当我找到了persistentDataPath里的xml文件后,通过解析它,就可以设置它里面的属性,student.Attributes["z"].Value = str_tmp_value;
1、xml文件
<config name="榫卯的奥秘">
<target0 x="123" y="12" z="12" />
<target1 x="9" y="321" z="53" />
<target2 x="923" y="123" z="342" />
<target3 x="9123" y="345" z="67" />
<target4 x="934" y="785469" z="546" />
<target5 x="95" y="546" z="890" />
<target6 x="69" y="678" z="879" />
</config>
1、运行效果:电脑端
①、电脑:如果是编辑器运行的话,第一次电脑上面会有这个xml产生,以后你代码中进行处理的是这个xml文件,路径是你Unity发布设置时候的名称
1、运行效果:安卓端
1、注意
①、配置文件如果有修改,需要修改PC端此目录下文件,让程序新建配置文件(安卓端不需要):
第一次运行时候系统就自动检测在系统文件夹下面是否有这个文件,所以以后修改的都是这个目录下的文件了,所以需要注意StreamingAssets和persistentDataPath下面不同的配置文件(如果对配置文件有修改,在PC端的时候,需要将这个文件删除,然后让它自己新建一个配置文件)(因为在安装同一个版本的apk的时候,会将前apk的配置文件的persistentDataPath下的配置文件删除,重新创建,所以安卓端不用删除配置文件)
①、使用 int.TryParse(student.Attributes["x"].Value,out x);得到属性里面x的值
①、使用 student.Attributes["y"].Value = str_tmp_value;修改属性里面x的值
①、save出来是BOM格式的,但是LoadXML是UTF-8格式的,所以会报错
①、路径很多是局部string变量,就按照这个代码来写,并且每次发布到安卓上面进行查看是否能读取到配置文件
①如果配置文件设置在StreamingAssets/test10/下面的话,那么程序只需要在这里修改一下就可以(这样PC端自己读取后新建的配置文件还是在这个目录下面,不能对其进行操作变为test10文件夹下面)
①如果要读取配置文件在其他程序前面,可以将协程改为普通的函数,其他都没有进行变化