- Home /
Getting A Variable From a Outside Text File
Hello, I have been trying to grasp how you would go about reading variables from a text file that is for example in the root folder of the Unity Project. I would like to use this to change certain aspects of the game without having to rebuild it, for example change the color of a cube after the standalone containing it is already built.
Currently I have found this script from the forums, and it works perfectly at what it was intended to do, display the text lines in print on the console.
import System.IO;
var textName : String;
function Start () {
try {
// Create an instance of StreamReader to read from a file.
sr = new StreamReader(textName);
// Read and display lines from the file until the end of the file is reached.
line = sr.ReadLine();
while (line != null) {
print(line);
line = sr.ReadLine();
}
sr.Close();
}
catch (e) {
// Let the user know what went wrong.
print("The file could not be read:");
print(e.Message);
}
}
I have a text file in the root of my project with lines that go like
"
cube1 isGreen
cube2 isRed
cube3 isYellow
"
I also have a managerial script in the game that interprets the strings and causes them to change the colors of the objects in question. However I cant figure out how to take these lines, which are currently only printed, and put the information into a list that I can use to give to the manager script.
Ideally I would like for the "cube#" part to be left out, and only read the line number and the variable ie the first line in the array would say "isGreen". Either that or It could have "var cubeOne : String;" and place the "isGreen" there, if an array would be too difficult.
If anybody would be willing to explain this to me I would be extremely appreciative!
I have a solution to this issue in my code but I have decided to scrap it all.. ins$$anonymous$$d, it would be better just to create a game object with a script attached to it.. the script would contain public variables that I would assign in the inspector.. this is much more intuitive then reading from a file.
also the file is in X$$anonymous$$L format. probably best to use a format like this, or CSV as Itinerant describes
Also, unless I'm mistaken, doesn't Unity include the text file in the build? So how can you modify it after its built?
Anyway, let me know if you still need a solution, I can post the way I read from the X$$anonymous$$L when I get home.
Is the text file included in the build? Im not very familiar with this text files for storing information stuff. I thought that since in the above script the text file can be read from a path (as opposed to being required to drag a reference of it) that I could set it to be within the standalone folder and it would still work if I set the correct path?
Currently it is reading data off of the root of the Unity folder and doesn't show up in the actual project folder, with no reference dragging required. I haven't been able to test this yet by building it to see if it works, guess I can see tomorrow.
I have never tried X$$anonymous$$L, so I don't understand any of it's conventions or even how to start using it. Though I suspect I will have to learn soon :)
Okay, so I build it with a modified version of the above script, with the path set to the root of the unity project, and it didn't build it in. Once I put the text file in the root of the built standalone however it read the information fine. So theoretically this method allows me to change variables in the game without having to rebuild, yay!
The biggest issue with this method is that I can only use one single line of csv, it will only ever show the last one.. I dont know how to fix it to display the lines as the elements of the array and not just the comma seperated values on a single line.
Answer by Itinerant · Jan 08, 2013 at 05:07 PM
My first thought would be to switch your text file into a more ordered system, like a CSV spreadsheet. Perk to this is that it'll be easier to modify using excel, instead of dealing with a text file. Here's a script I'm using to do just that, creating a dictionary with the first CSV column as the key, and everything else stacked behind it. Right now I'm using this to attach about 20 attributes to gameobjects, so it works well :) It skips duplicate keys and lines with an empty first column.
//Load a dictionary with spreadsheet data, taking a text file and a dictionary as arguments.
function LoadCSVfromTXT(csvAsTxt : TextAsset, dictionary : Dictionary.<String, List.<String> > ){
var tempArray : String[];
var tempArray2 : String[];
//Split text file by lines
tempArray = csvAsTxt.text.Split("\n"[0]);
//For as many lines as exist, split by commas. If the first value isn't already in the dictionary,
//and isn't n/a, add it to the array.
for(var x=0; x<tempArray.Length; x++){
tempArray2 = tempArray[x].Split(","[0]);
if(tempArray2[0] in dictionary || tempArray2[0]=="") continue;
else{
dictionary[tempArray2[0]] = new List.<String>();
for(var y=1; y<tempArray2.Length; y++){
dictionary[tempArray2[0]].Add(tempArray2[y]);
}
}
}
}
Note that you need to change your table from a .csv to a .txt for this to work.
Thank you so much for helping! I've never used a CSV spreadsheet before though, so If you could maybe help me understand this process a little more that would be great. Do you have to use Excel to make a CSV spreadsheet? I don't currently have it but I can get a trial of excel if that's the only way.
So basically a CSV is a spreadsheet with a bunch of columns, and I would use the first column to find the game objects and the second and thereafter columns as variables that are assigned ie cube1 in the first column and isGreen in the second column with cube 2 underneath? Then save it out from Excel as a CSV, and then change the file type to .txt and put it in the root of the project folder as well? Sorry for so many questions, just want to make sure I'm understanding it right :)
Also I get these errors when I put it into Unity,
"The name 'List' does not denote a valid type ('not found'). Did you mean 'UnityEngine.Light'?"
"The name 'Dictionary' does not denote a valid type ('not found'). Did you mean 'System.Collections.Generic.Dictionary'?"
CSV stands for 'Comma Separated Values,' and it's basically a spreadsheet where columns are marked by commas, and rows are marked by returns. Any spreadsheet software should be able to export one, if you don't have one I'd suggest using Google Docs.
As for your understanding, that's pretty much it. You'll need to declare it somewhere in the script of course as an object of type TextAsset, and then plug that object in. I use a public variable and then assign the .txt to it in the inspector, which means the file can be anywhere in your assets folder.
And not a problem, let me know if you have more questions, and remember to mark the answer as correct if it ends up working for you :D
Do you know why I'm getting the two errors above, about the List and Dictionary? Also when you say declare the text asset do you mean switch out the "TextAsset" at line one to "someTextAsset" and down below state "var someTextAsset : TextAsset"? Finally, if it is a text asset and is located in the resources folder, will I have to load an asset bundle at runtime if I want to be able to swap them out without rebuilding? Thanks :)
Oh yeah, I forgot about that. Add this to the beginning of the script:
import System.Collections.Generic;
As for where it's at, if you're assigning it in the inspector it doesn't really matter where it's at in the project. It packs it with your build, just like a texture or gameobject, so it shouldn't require any special effort :)