unity Android 打包后读取 xml 文件

本文介绍了解决Unity游戏开发中跨平台XML文件读取问题的方法。针对不同平台(PC和Android)上的路径差异,提供了具体的代码实现,确保游戏在不同设备上能够正确加载和解析XML数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学习学习!原帖地址:http://www.cnblogs.com/wuzhang/p/wuzhang20140731.html?utm_source=tuicool&utm_medium=referral

问题: 前天在做东西的过程中发现了一个让人很纠结的问题,为什么Unity 程序在PC上测试一点都没问题但是打包发布到Android后却无法读取XML文件。

通过查找自资料发现打包发不到安卓后的路径和PC上测试时的路径发生了变化,因此读取就出bug了。

那么解决方法很简单:

1,建立一个新工程

2,添加两个GUItext组件一个用于显示测试平台另一个用于显示读取到的XML数据,

如下:

3,该贴代码了

//------------------------------------------------------------------------------
// <auto-generated>
//	 此代码由工具生成。
//	 运行时版本:4.0.30319.18063
//
//	 对此文件的更改可能会导致不正确的行为,并且如果
//	 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using UnityEngine;
using System.IO;
using System.Xml;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;


namespace AssemblyCSharp1
{
  
  public class AddressData1
  {
    public string timeURL;
    public static string all;
    public static string hp;		
    public static string speed;
    public static string demage;
    
    public static string localPath;
    public static string id;
    public static string score;
    public static List<int> allScore;

    public void AddressData ()
    {
      Debug.Log (localPath);
    }

    public static List<int> getAllScore()
    {
      return allScore;
    }

    /// <summary>
    /// 获取XML路径
    /// </summary>
    /// <returns>The XM.</returns>
    public static IEnumerator GetXML()
    {
      if(Application.platform==RuntimePlatform.Android)
      {
        localPath = Application.streamingAssetsPath+"/score.xml"; //在Android中实例化WWW不能在路径前面加"file://"
        Debug.Log (localPath);
      }
      else
      {
        localPath = "file://"+UnityEngine.Application.streamingAssetsPath + "/score.xml";//在Windows中实例化WWW必须要在路径前面加"file://"
        
        Debug.Log (localPath);
      }
      WWW www = new WWW(localPath);
      while (!www.isDone)
      {
        Debug.Log("Getting GetXML");
        yield return www;
        all = www.text;
        ParseXml(www);
      }
    }
    
    /// <summary>
    ///按属性获取节点
    /// </summary>
    /// <param name="www">Www.</param>
    public static void ParseXml(WWW www) 
    {
      if(allScore == null)
      {
        allScore =new List<int>();
      }
      XmlDocument xmlDoc = new XmlDocument();
      xmlDoc.LoadXml(www.text);
      XmlNodeList nodeList=xmlDoc.SelectSingleNode("rank").ChildNodes;
      
      foreach(XmlElement xe in nodeList)
      {
        id = xe.GetAttribute("id");
        score = xe.GetAttribute("score");
        allScore.Add(int.Parse(score));  //将所有得分读入List

        Debug.Log ("ID:"+id+" Score:"+score);
      }
      allScore.Sort();
      allScore.Reverse();
      foreach(var score in allScore )
      {
        Debug.Log (score.ToString());
      }
    }
    
    /// <summary>
    /// 读取xml内容
    /// </summary>
    public static IEnumerator load()
    {
      string url = string.Empty;
      string path = string.Empty;
      string line1 = string.Empty;
      if(Application.platform==RuntimePlatform.Android)
      {
        url=Application.streamingAssetsPath+"/hp.xml"; //在Android中实例化WWW不能在路径前面加"file://"
        
        WWW wWA=new WWW(path);///WWW读取在各个平台上都可使用
        yield return wWA; 
        line1=wWA.text;
        Debug.Log (line1);
      }
      else
      {
        url="file://"+Application.streamingAssetsPath+"/hp.xml";//在Windows中实例化WWW必须要在路径前面加"file://"
        WWW wWA=new WWW("file://"+url);
        yield return wWA; 
        line1=wWA.text;
        Debug.Log (line1);
      }
      yield return null;
    }


    /// <summary>
    /// 加载xml文档
    /// </summary>
    /// <returns></returns>
    public static  XmlDocument ReadAndLoadXml()
    {
      XmlDocument doc = new XmlDocument();
      //Debug.Log("加载xml文档");
      doc.Load(localPath);
      return doc;
    }

    /// <summary>
    /// 增加节点
    /// </summary>
    /// <returns>The node.</returns>
    /// <param name="score">Score.</param>
    public static void insertNode(int score)
    {
      int minute=int.Parse((System.DateTime.Now.Minute.ToString()));
      string order = System.DateTime.Now.Hour+""+System.DateTime.Now.Minute+""+System.DateTime.Now.Second;
      XmlDocument xmlDoc=new XmlDocument();
      xmlDoc.Load(Application.dataPath + "/StreamingAssets/score.xml");
      XmlNode root=xmlDoc.SelectSingleNode("rank");
      
      XmlElement xel=xmlDoc.CreateElement("rank");	//建立节点
      xel.SetAttribute("id",order);
      xel.SetAttribute("score",score.ToString());
      
      root.AppendChild(xel);
      xmlDoc.Save(Application.dataPath + "/StreamingAssets/score.xml");
      return;
    }

  }


}

测试读取数据代码:

using UnityEngine;
using System.Collections;
using AssemblyCSharp1;

public class testinsert : MonoBehaviour 
{
  public GUIText guitext;
  public GUIText platform;
  string allscores="";

  void Awake()
  {
    if(Application.platform==RuntimePlatform.Android)
    {
      platform.text = "Android";
    }
    else
    {
      platform.text = "PC";
    }
  }

  // Use this for initialization
  void Start () 
  {

    StartCoroutine(AddressData1.GetXML());
    //AddressData1.insertNode(22);

  }

  void OnGUI()
  {
    if(GUI.Button(new Rect(100,100,40,40),"load"))
    {
      foreach(int score in AddressData1.allScore)
      {
        allscores+=score.ToString();
        guitext.text+="\t";
      }
      guitext.text = allscores;
    }
  }

  // Update is called once per frame
  void Update () 
  {
  
  }
}
<?xml version="1.0" encoding="UTF-8" ?>
<rank>
    <rank id="5618" score="12" ></rank>
    <rank id="1712" score="14" ></rank>
</rank>

那下面鸡冻的时刻来了: PC端 运行前:

运行后:

点击load按钮:

看看控制台都输出哪些内容了:

PC上测试Ok了吧。

接下来Android测试,本人的手机哦:

到此结束了,以后程序关于数据处理的都是浮云了!

<think>嗯,用户想在Unity打包Android APK中读取.xlsx文件,我得想想怎么解决这个问题。首先,UnityAndroid平台上处理文件的方式和桌面端可能不同,需要考虑文件路径和访问权限的问题。 用户提到的.xlsx文件是Excel文件,可能需要使用第三方库来解析。比如用EPPlus或者Open XML SDK,但这两个是.NET的库,在Unity中是否兼容呢?尤其是Android环境下,可能有限制。或者有没有其他适用于Unity的库,比如ExcelDataReader?不过需要确认是否支持Android平台。 另外,文件应该放在哪里?如果是只读的,可能需要放在StreamingAssets文件夹里,这样打包时会被含进APK,然后通过UnityWebRequest或者System.IO来读取。不过Android文件系统访问可能需要使用Application.streamingAssetsPath,并且路径可能需要用file:///开头。 比如,用户可能需要将.xlsx文件放在Assets/StreamingAssets下,然后在代码中使用Application.streamingAssetsPath获取路径。不过读取的时候可能需要用UnityWebRequest,因为Android的StreamingAssets路径不能直接用System.IO读取。或者如果是可写的文件,可能需要放在Application.persistentDataPath,但用户的问题好像是读取,不是写入。 然后,解析.xlsx文件,可能需要使用ExcelDataReader库,这个库在Unity中需要入合适的DLL,并且可能需要额外的依赖,比如System.Data.dll和I18N相关的DLL。另外,需要注意在Android上使用时的兼容性问题,比如是否支持ARM架构,是否需要启用.NET兼容性设置。 另外,用户提到的引用[1]是关于Java中检测MIME类型的,但用户的问题是在Unity读取文件,可能不太相关。不过用户可能担心MIME类型的问题,但实际在Unity中可能不需要处理MIME类型,而是直接读取文件内容。 总结步骤应该是:1..xlsx文件放入StreamingAssets。2.使用UnityWebRequest读取文件内容为byte[]。3.使用ExcelDataReader解析byte[]为数据集。4.处理数据。需要注意Android平台的路径处理,以及确保ExcelDataReader在Android上可用。 可能的问题点:ExcelDataReader在Unity Android上的兼容性,是否需要额外的设置,比如在Player Settings里启用Allow 'unsafe' Code,或者处理文件流的正确方式。此外,可能需要处理文件是否存在,以及异步加载的问题,因为UnityWebRequest是异步的。 另外,用户可能需要示例代码,展示如何正确使用UnityWebRequest和ExcelDataReader,并处理可能的异常,比如文件找不到或解析错误。还要注意ExcelDataReader需要ExcelDataReader.DataSet扩展来读取为DataSet,可能需要引入相关的命名空间。</think>在Unity读取.xlsx文件需要结合文件路径处理和第三方库解析,以下是具体实现方法: ### 一、文件路径处理 1..xlsx文件放入`Assets/StreamingAssets`文件夹 2. 通过UnityWebRequest获取文件内容: ```csharp IEnumerator LoadExcelFile() { string filePath = Path.Combine(Application.streamingAssetsPath, "data.xlsx"); #if UNITY_ANDROID && !UNITY_EDITOR filePath = "jar:file://" + Application.dataPath + "!/assets/" + "data.xlsx"; #endif UnityWebRequest request = UnityWebRequest.Get(filePath); yield return request.SendWebRequest(); if (request.result != UnityWebRequest.Result.Success) { Debug.LogError("加载失败: " + request.error); } else { byte[] fileBytes = request.downloadHandler.data; ProcessExcelData(fileBytes); // 解析文件内容 } } ``` ### 二、安装Excel解析库 1. 通过NuGet获取ExcelDataReader(3.6.0+)和ExcelDataReader.DataSet(3.6.0+) 2. 将以下DLLUnity: - Excel.dll - ICSharpCode.SharpZipLib.dll - System.Data.dll - System.Text.Encoding.CodePages.dll ### 三、数据解析示例 ```csharp using ExcelDataReader; using System.Data; using System.IO; void ProcessExcelData(byte[] fileBytes) { System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); using (var stream = new MemoryStream(fileBytes)) using (var reader = ExcelReaderFactory.CreateReader(stream)) { var result = reader.AsDataSet(new ExcelDataSetConfiguration() { ConfigureDataTable = (_) => new ExcelDataTableConfiguration() { UseHeaderRow = true // 使用首行作为列名 } }); DataTable table = result.Tables[0]; foreach (DataRow row in table.Rows) { Debug.Log(row["Name"] + " | " + row["Score"]); } } } ``` ### 四、注意事项 1. Android平台需要开启`File Access`权限 2. Player Settings中启用: - Allow downloads over HTTP - .NET 4.x Equivalent兼容级别 3.文件建议异步加载避免卡顿
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值