如何重新加载XML填充的Unity资源

时间:2019-07-19 12:30:11

标签: xml unity3d dynamic

我正在用一些XML文件中的数据填充一些元素,例如ScrollView。通过单击按钮,将从服务器中获取最新文件。 我试图直接在GUI中显示它们,但是我总是必须重新启动应用程序才能查看最新下载的版本。 下载和编写工作正常。

以下是一些代码:

首先是下载/更新过程

public bool update() {
    try {
        // Download + Save
        WebClient wc = new WebClient();
        wc.Credentials = new NetworkCredential("anonymous", "");
        wc.DownloadFile(_address_employeesXML, _filePathToXMLImport + "/employees.xml");

        XMLReader test = new XMLReader(logController);
        test.readXMLFiles(); 
        Debug.Log("Update successful");
    } catch (Exception e) {
        #if UNITY_EDITOR
        EditorUtility.DisplayDialog("Error",  e.Message, "OK");
        #endif
        XMLReader test = new XMLReader(logController);
        //test.readXMLFiles();
        Debug.LogException(e);
        return false;
    }
    return true;
}

然后读取过程:

    public bool readEmployees()
{
    string pathToEmployeeXML = _filePathToXMLImport + "/employees.xml";
    if (File.Exists(pathToEmployeeXML))
    {
        using (XmlReader reader = XmlReader.Create(pathToEmployeeXML))
        {
            while (reader.Read())
            {
                // Only detect start elements.
                if (reader.IsStartElement())
                {
                    switch(reader.Name)
                    {
                        case "employee":

                            XmlReader inner = reader.ReadSubtree();

                            inner.ReadToDescendant("firstName");
                            string firstName = inner.ReadElementString();
                            inner.ReadToDescendant("lastName");
                            string lastName = inner.ReadElementString();

                            generateEmployee(firstName, lastName);
                            break;
                    }
                }
            }
        }
        return true;
    }
    return false;
}

我发现了这个线程: Reloading XML asset in Unity 不幸的是,这并不能真正解决我的问题。

我还尝试使用AssetDatabase.Refresh,但实际上并没有真正找到实现它的方法。

2 个答案:

答案 0 :(得分:0)

我希望使整个过程异步,以免使用UnityWebRequest进行下载来阻止主线程。

实际上,您实际上不必真正写入文件并再次读取它……您可以直接使用下载的string并将其传递给XmlSerializer(您必须实现一个表示xml布局的类-请参见Saving and Loading Data: XmlSerializer)。

如果您仍然需要/想写,我会写到Application.persitentDataPath并使用FileStream读/写文件

public void update(Action<bool> success)  
{
    StartCoroutine(UpdateRoutine(onSuccess)); 
}

private string authenticate(string username, string password) 
{
    string auth = username + ":" + password;
    auth = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(auth));
    auth = "Basic " + auth;
    return auth; 
}  

private IEnumerator UpdateRoutine (Action<bool> onSuccess) 
{   
    using(var www = UnityWebRequest.Get(_address_employeesXML)
    {
        string authorization = authenticate("YourUserName", "YourPassWord");
        www.SetRequestHeader("AUTHORIZATION", authorization);

        yield return www.SendRequest();

        if(www.error)
        {
             success?.Invoke(false);
        } 
        else
        {
            // you could ofcourse simply use the returned filecontent now like
            var xml = www.downloadHandler.text;

            var xmlSerializer = new XmlSerializer(typeof(YOURDATA_CLASS));

            var dataClass = (YOURDATA_CLASS) xmlSerializer.Deserialize(xml);
            success?.Invoke(true);


            // However if you prefer to write the file 
            WriteFile(xml, success);
        }
    }
}

// Usually async void is bad
// but with a callback its fine
private async void WriteFile(string xml, Action<bool> success)
{ 
    try
    {
        var data = Encoding.UTF8.GetBytes(xml);

        using(var file = File.Open(Path.Combine(_filePathToXMLImport, "employees.xml", FileMode.OpenOrCreate))
        {
            await file.WriteAsync(data, 0, data.length);

            success?.Invoke();
        }
    }
    catch
    {
        success?.Invoke(false);
    }
}      

然后读取过程:

public void ReadFile(Action<bool> success)
{
    using(var file = File.Open(Path.Combine(_filePathToXMLImport, "employees.xml", FileMode.Open))
    {
        var data = new byte[(int)file.length];
        await file.ReadAsync(data, 0, data.length);

        var xml = Encoding.UTF8.GetString(Data);

        var xmlSerializer = new XMLSerializer(typeof(YOURDATA_CLASS));

        var dataClass = (YOURDATA_CLASS) xmlSerializer.Deserialize(xml);
        success?.Invoke(true);
    }
}

注意:在智能手机上键入内容,因此没有保修,但我希望这个主意会清楚

答案 1 :(得分:0)

解决我的问题的方法是将我上面提到的代码移到负责StartView的Controller类中。