writing to a resource text file?

Hello,
I know that StreamWriter() is a way to write to files, and Resource.Load() is a way to read from files, but I also noticed how the files that I write to do not change unless I reload them either in Unity or inside a document editor somewhere. If the text file is not loaded anywherer, it will not change, and if it is already loaded, I have to close the .txt file and reload it before the changes take place. How do I fix this glitch? Also, will StreamWriter work in a published .exe file or in a web browser (due to security purposes) and how does THAT work?

What I am trying to do is have a bunch of game settings I can store in a .txt file, and when I change a setting in a GUI control, it writes to a file. The GUI controls also read from the file to get the values of each setting, but if the file doesn’t change when I write to it and I go back to the “settings screen”, nothing in my settings change.

You could use UnityEngine.PlayerPrefs to save/load data easily.

You can’t save files in Resources, atleast I don’t think you can.
So instead save the settings at Application.dataPath or use UnityEngine.PlayerPrefs.

It won’t work in a Web Player build.
It won’t work writing to a Resources folder in a built exe
It will work if you write to something like Application.dataPath and load with System.IO.
The above won’t work in a Web Player either. For Web Player you’re stuck with PlayerPrefs or POSTing the data somewhere and retrieving it via some kind of web service or GET.

2 Likes

What about an idea of developing some “conventional temp memory” for the web player so resources can be virtually ‘written’ to that way, and when the user closes out of the web player, he/she gets a dialog box that says, “Would you like to save your changes to a .data file?” and if he/she clicks “Yes”, a save dialog box comes up where he/she can save this information to their hard drive?

You can use base C# classes to write to a file, call it a .cfg. Since .cfgs are just renamed text files, you would just need to parse the text. We did the same thing when we replaced the default Unity launcher with a custom patcher. We needed to save settings from the custom launcher into the game proper, and this is how we did it. Take a look at the code:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System;


public static class GameCFG : System.Object {
    static string cfgDirectory = Directory.GetCurrentDirectory() + "/LiveWorldCfg.cfg";

    public static bool GetConfigBool() {
        return false;
    }

    public static void Initiate() {

        //Prepare for config
        List<string> cfgLines = new List<string>();
        string cfgDirectory = Directory.GetCurrentDirectory() + "/config.cfg";
        try {
            //Check if cfg currently exists
            if (File.Exists(cfgDirectory)) {
                //Get cfg lines
                foreach (string _l in File.ReadAllLines(cfgDirectory)) {
                    cfgLines.Add(_l);
                }
                //Process cfg lines
                ProcessConfigLines(cfgLines.ToArray());
            } else {
                //create the config file
                Debug.LogWarning("WARNING: CONFIG FILE NOT FOUND. CREATING NEW FILE.");
                string[] defaultConfigOptions = new string[2];
                defaultConfigOptions[0] = "resolution=1366x768";
                defaultConfigOptions[1] = "fullscreen=false";
                defaultConfigOptions[1] = "quality=Simple";

                File.WriteAllLines(cfgDirectory, defaultConfigOptions);
            }
        } catch (IOException e) {
            Debug.LogException(e);
        } catch (MissingReferenceException r) {
            Debug.LogException(r);
        } finally {
            //Parse each line into eval
            foreach (string line in cfgLines) {
                ProcessConfigLine(line);
            }
        }
    }

    static void ProcessConfigLine(string line) {
    }

    static string GetConfigString() {
        return "Some String";
    }
    static int GetConfigInt(string[] cfgLines) {
        return 1;
    }
    static bool GetConfigBool(string[] cfgLine, string TargetCommand) {
        string _val = "";

        foreach (string line in cfgLine) {
            string command = line.Substring(0, line.IndexOf('='));
            if (command == TargetCommand) {
                _val = line.Substring(line.IndexOf('=') + 1, line.Length - line.IndexOf('=') - 1);
            }
        }
        return _val == "true";
    }

    static void ProcessConfigLines(string[] cfgLines) {

        foreach (string line in cfgLines) {
            string _command = line.Substring(0, line.IndexOf('='));
            string _value = line.Substring(line.IndexOf('=') + 1,
                line.Length - line.IndexOf('=') - 1);

            //Debug.Log(_value);
            switch (_command) {

                //read resolution config
                case "resolution":
                    string[] numbers = _value.Split('x');

                    int _x = Convert.ToInt32(numbers[0]);
                    int _y = Convert.ToInt32(numbers[1]);
                    Screen.SetResolution(_x, _y, GetConfigBool(cfgLines, "fullscreen"));
                    break;

                //ready fullscreen config
                case "fullscreen":
                    if (_value == "True")
                    {
                        if(!Screen.fullScreen)
                        Screen.fullScreen = true;
                    }
                    else if(_value == "False")
                    {
                        if(Screen.fullScreen)
                        Screen.fullScreen = false;
                    }
                    break;

                //read quality config
                case "quality":
                    switch (_value)
                    {
                        case "Fastest":
                            QualitySettings.SetQualityLevel(0);
                            break;
                        case "Fast":
                            QualitySettings.SetQualityLevel(1);
                            break;
                        case "Simple":
                            QualitySettings.SetQualityLevel(2);
                            break;
                        case "Good":
                            QualitySettings.SetQualityLevel(3);
                            break;
                        case "Beautiful":
                            QualitySettings.SetQualityLevel(4);
                            break;
                        case "Fantastic":
                            QualitySettings.SetQualityLevel(5);
                            break;
                    }
                    break;
            }
        }
    }
}

Thank you. That was what I needed. Will it work in a web player though, to where a person who plays a game from a browser can directly save information to his computer through a save dialog box?