Tales of the Rampant Coyote

Adventures in Indie Gaming!

Unity C# Question

Posted by Rampant Coyote on March 6, 2012

Maybe someone here who is more familiar with Unity and/or C# can give me a hand here.

Using the Monodevelop IDE, I had the following code (somewhat modified here)…


public class RoomGeo : MonoBehaviour {

public string[] wallResources= {"wall1a","wall2a","wall4a"};

void CreateWallVisual(int index)
{
int val = m_RoomTemplates[0].walls[index].wallID;
string strname = "Tiles/"+wallResources2[val];
}

}

Okay, all is fine and dandy. I pass in a value for index between 0 and 3, and it works as expected. But THEN I make the following change….

public string[] wallResources= {“wall1a”,”wall2a”,”wall4a”,”wallcapa”,”",”",”"};

And call it with an index of 4. Should work fine, right? Wrong. Even after a “rebuild”  I am getting a run-time exception for an array out of bounds error.  At the end of my rope, I rename wallResources to wallResources2 for both the array and (obviously) the call to it, and voilà… problem goes away.

It’s like the previous array declaration with only three values was somehow “stuck” and wouldn’t get refreshed until I renamed the array.

While the problem is temporarily solved, this concerns me. Something like this is very likely to bite me again, and I might waste a lot of time trying to figure it out. Can anybody tell me what I did wrong (if anything)? My C# is rusty and I’m still a newb to Unity, so this is a head-scratcher for me.


Filed Under: Programming - Comments: 8 Comments to Read



  • Jonathan MacAlpine said,

    The problem is that the values that you passed in initially to populate the array got stored in as made-in-the-editor values, if that makes sense. Only a NEW component that you create will have those assignments be exactly what’s in code.

    For example, if you have:

    public int thing = 2;

    …and then create a component, it sets “thing” to 2 and makes the value editable via the inspector. This causes the value 2 to be saved into the runtime component. Later changing the code to read:

    public int thing = 3;

    …will cause all future components of this type to START with the value 3, but the one you created initially will still have the original value, 2.

    I’m not sure what you can do to address this, but that’s the problem.

  • David said,

    When you create a public variable, it will exist in the Unity inspector. If you ever change the value manually in the inspector, this will become the dominant value and will always overwrite any changes you make in your script.

    For example,
    in your script: public int myNum = 5;
    in the inspector, you change the value to 10
    back in your script: public int myNum = 20
    The value will remain 10

  • Rampant Coyote said,

    So if I understand you guys correctly, this is an issue with the interactive Unity environment. Aside from the way I did it, I’d either have to restart Unity or delete and re-add the script to an object for it to “refresh” with the new values?

    Is there some other way to force a refresh on an object of any changed code?

  • Jonathan MacAlpine said,

    On that, I’m not sure. Curious myself, though!

    On a side note, you can get the basic iOS and Android licenses absolutely free, no strings attached, from now until April 8th! 😀

  • Kurt said,

    Just click the options icon on the component/script and select Reset.

    It will hold the inspector value until you click reset or make a major change to the code.

  • Rampant Coyote said,

    Okay, I’ll try that tonight, thanks Kurt!

    And yep, I got the basic package for mobile platforms last night! Score!

  • Anonymous said,

    I don’t know about C#, but in UnityScript, if you declare a Variable of a Script as public, you are supposed to change that Variable in the Inspector and not in the Script. If you assign Values to the Variable in the Script, then those are the Default-Values given to every GameObject, that you add the Script to.

    The reason for that is very simple:
    Imagine you have a Script ‘Enemy’ with
    public int health = 10;
    And the GameObjects ‘Orc’ and ‘Goblin’, both with an Enemy-Script attached to them.
    In The Inspector you change the Health of the Orc to 20 and leave the Goblin at the Standard 10. Now both GameObjects have different Values for Health.
    If you now change the Default-Value in the Script to 50, the Health of your two enemies does not change. It is Assumed, that you had a good reason for changing or keeping the Value for those GameObjects. That way the Programmer does not ruin the Work of the Designer (Note: The Programmer can still ruin the work of the Designer, by renaming(at least I think) or by making the Variable protected or private. This Note is just to notify you of a Pitfall you could fall into.)

    If you absolutly must have the Variable changed in the Script and not in the Inspector, then you should declare the Variable private or protected, that way they are not exposed in the Inspector.

    It is a bit of a different Philosophy than what you are used to in ‘normal’ programming. Again the only purpose of declaring a Variable as public is to change it in the Inspector and not constantly having to change the Script.

    If you have another Question to Unity, feel free to post another Blogpost:).

  • Rampant Coyote said,

    Ah, that does make sense, and is something I will have to watch out for.

    This script is for a single “master” object – really a static array (I probably should have declared them const or the equivalent in C#). So I’m not too worried about instantiation. Whenever working with a new system engine / paradigm / language I have to take some early steps to wrap my brain around how it works, and it takes some problems like this one to hammer it home.

    Thanks!

top