1

I am trying to read different text files based on the index of the current scene (in Unity lingo). So, I decided to use a switch statement as follows:

void MyReadString()
{
    Scene currentScene = SceneManager.GetActiveScene(); // Unity command to get the current scene info
    int buildIndex = currentScene.buildIndex; // Unity command to get the current scene number
    string path = string.Empty; // Create an empty string variable to hold the path information of text files
    switch (buildIndex)
    {
        case 0:
            string path = "Assets/Scripts/some.txt"; //It says here that the variable path is assigned but never used!
            break;
        case 1:
            string path = "Assets/Scripts/another.txt"; //Same here - assigned but never used. 
            break;
        // and many other cases - atleast 6 more
    } 
    StreamReader reader = new StreamReader(path); // To read the text file
    // And further string operations here - such as using a delimiter, finding the number of values in the text etc
}

If I comment out the line:

string path = string.Empty;

then,

StreamReader reader = new StreamReader(path); // says here the name "path" does not exist in the current context.

I know this has to do something with the scope of the switch statement. However, declaring the string variable outside the switch as an "Empty" is not working. Kindly let me know if I can assign a string value within a Switch statement and use that value later on. Or if it is not possible, please suggest me workarounds.

Draken
  • 3,134
  • 13
  • 34
  • 54
Riz
  • 77
  • 1
  • 5
  • 1
    Remove `string` when you assign `path` in the switch statement. – eye_am_groot Aug 01 '18 at 11:16
  • I did that - it says "cannot use local variable 'path' before it is declared. – Riz Aug 01 '18 at 11:18
  • I would have thought that the code you have posted would cause a compilation error. You are re-defining "path" twice after its initial declaration. Just declare it once at the top and remove the "string" from within the switch statement. – Wheels73 Aug 01 '18 at 11:20
  • Did you remove ALL redeclarations of `string path` in the `switch` statement? – eye_am_groot Aug 01 '18 at 11:23

3 Answers3

5

You are having issues because you're re-declaring the path variable again in the switch statement. Declare it once only outside the switch statement then assign it in the switch statement.

void MyReadString()
{
    Scene currentScene = SceneManager.GetActiveScene(); // Unity command to get the current scene info
    int buildIndex = currentScene.buildIndex; // Unity command to get the current scene number
    string path = null;
    // Create an empty string variable to hold the path information of text files
    switch (buildIndex)
    {
        case 0:
            path = "Assets/Scripts/some.txt"; //It says here that the variable path is assigned but never used!
            break;
        case 1:
            path = "Assets/Scripts/another.txt"; //Same here - assigned but never used. 
            break;
            // and many other cases - atleast 6 more
    }
    StreamReader reader = new StreamReader(path); // To read the text file                                               // And further string operations here - such as using a delimiter, finding the number of values in the text etc
}

Unrelated, but please note that this is not how to read a file in Unity.That code will fail when you build the project. Use the Resources API or use Assetbundles.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • A query on the Resources API - currently, I have all my text files inside a folder that I created - "Scripts" under my Assets folder. I do not have it under the Resources folder (which also appears separately under Assets), but has stuff like Shaders, Fonts and so on. So, is this Resources API useful only for stuff inside the "Resources" folder or is it simply the correct way to read a file in Unity, no matter where your text files are? – Riz Aug 02 '18 at 08:56
  • Resources API can only be used with files in the Resources folder. Either that or use the AssetBundle API with the StreamingAssets folder. I linked to both in my answer. Assetbundles + StreamingAssets is faster and more recommended than the Resources API and its folder. – Programmer Aug 02 '18 at 10:37
2

You're trying to redeclare a variable - but you actually just want to assign a new variable to the existing variable that you've declared here:

// This line is still needed, and must be before the switch statement.
// Ideally, remove the initialization - your switch statement should cover
// all cases, I expect.
string path = string.Empty;

So this:

case 0:
    string path = "Assets/Scripts/some.txt"; //It says here that the variable path is assigned but never used!
    break;
case 1:
    string path = "Assets/Scripts/another.txt"; //Same here - assigned but never used. 
    break;

Should be:

case 0:
    path = "Assets/Scripts/some.txt";
    break;
case 1:
    path = "Assets/Scripts/another.txt";
    break;

IMO it would be cleaner to either put this logic in a separate method, or just have an array or Dictionary<int, string> though. For example:

string path = GetScriptPath(buildIndex);

or (with scriptPaths being a string[] or Dictionary<int, string>)

string path = scriptPaths[buildIndex];
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

You're correct about the scope bit. The variable path being declared within the switch statement makes it only accessible from within that statement. To make your variable accessible from outside the statement you must declare it in a wider scope.

If you want to access that variable:

  • Only within that function, declare it within void MyReadString() but outside the switch statement
  • Elsewhere within the class, declare it within the class structure (outside the MyReadString() function) this is for if you wish to use that path later in another function

In its current form you are creating a new string every time the switch statement hits a case, by moving the declaration you will just be assigning a pre-declared string.

Will Anderson
  • 113
  • 1
  • 14