Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by Damocles · Jan 07, 2013 at 10:32 AM · c#arrayscompiler

enums and array indexing - weird issue, maybe compiler bug?

This one is properly crazy - I'm using a fairly standard practice of ending my enum lists with a 'maxValue' entry, so I can easily create arrays using that value which resize as the enum list changes. This has been working fine, but suddenly today I hit play and am getting index out of bounds errors where it shouldn't be possible.

So the code - I have this enum:

 public enum DamageType
 {
     // general damaging types
     none, fire, slice, crush, physical, pierce, ice, spirit, nature, light, dark, death, energy, explosive,
     // special types
     healing, blinding,
     // generic magic resistance
     magic,
     // custom type for room spawning
     roomBuilder,
     maxValue
 }

and in a class I have this variable:

 public float[] damageModifiers = new float[(int)DamageType.maxValue];

also in this class I call a method to set the defaults:

 public virtual void setDefaults()
     {
         // set default values in case they are left blank in the ini
         Debug.Log("dmg type max value is " + (int)DamageType.maxValue);
         for (int i = 0; i < (int)DamageType.maxValue; ++i)
         {
             Debug.Log("Setting dmg mod default for " + (DamageType)i + " (" + i + ")");
             damageModifiers[i] = 1f;
         }
     }

I've added in the debug logs to help track down the issue. So the console output now is:

dmg type max value is 18

Setting dmg mod default for none (0)

Setting dmg mod default for fire (1)

// ..... //

Setting dmg mod default for magic (16)

Setting dmg mod default for roomBuilder (17)

IndexOutOfRangeException: Array index is out of range.

Character.setDefaults () (at Assets/Scripts/Behavioural/Character.cs:959)

This is crazy. It's not only a very standard practice, but has been working great for ages. It went wrong after I added a new enum to the list (it was 'magic' not that it should matter). Now even if I remove magic from the list it still bombs out.

This should not happen. All I can think is that somehow Unity is not re-compiling properly and is keeping the value of 'maxValue' as 17 when it should now be 18. But that wouldn't explain why it fails when I remove 'magic' form the list.

I also tried setting maxValue=64, but it still bombs out on 'roomBuilder' (index 17). The debug output did show maxValue as 64 though, so I have no idea how the array could only be 17 elements long!

Is there a way in Unity to 'clean' the compiled object files? (Like in Visual Studio you can go to Project->clean and it will remove all intermediate compile data).

Or does anyone have an idea why this is happening?

Comment
Add comment · Show 7
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image gbelini · Jan 07, 2013 at 12:19 PM 0
Share

i was testing your code here, and i don't get any error add or remove. You could Try right click on script, and Reimport.

avatar image Damocles · Jan 07, 2013 at 12:30 PM 0
Share

Hmm, that would suggest there's something in my code that's somehow modifying the size of the array. I did a search and there's only a handful of spots where the variable is referenced, and none of them do anything that could change the array size.

I tried reimporting, and I even tried deleting the script and replacing it, but still get the same error.

Thanks for trying the code, it's good to know it's something specific to my project. At least I'm one step closer now.

avatar image Piflik · Jan 07, 2013 at 12:56 PM 0
Share

Your console tells you, that maxValue has the correct value. Somehow your array is initialized to short. Try printing dam$$anonymous$$odifiers.length.

Is this all in one class, or is the enum in an interface/abstract class and probably overwritten?

avatar image Damocles · Jan 07, 2013 at 01:09 PM 0
Share

Right now I think I've narrowed it down a corrupted symbols table. I can rename the variable and it will run fine. If I rename it back to the original name, the problem returns.

So I tried cleaning out the intermediary files, but no luck. I think Unity might store the symbols table in some obscure location. So I've submitted a bug report to Unity and will just have to wait and see what comes of it.

I know, the obvious question is: why not just rename and move on? Annoyingly my project makes very heavy use of reflection to match names in data files to names in run-time objects, so rena$$anonymous$$g this variable is a large undertaking :(

avatar image CHPedersen · Jan 07, 2013 at 01:18 PM 0
Share

I tested your code too, it works fine on my machine as well. It prints all expected values correctly. The only conclusion I have is that the error is somewhere outside the snippet you've posted. If I were you, I would do as @Piflik suggested and carefully track the length of your float array. Put multiple printouts between the place where it is assigned and the loop that fills it with values, and see if you can pinpoint exactly where, along the way, its length changes.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Wolfram · Jan 07, 2013 at 01:12 PM

You are reserving (int)DamageType.maxValue (=18) entries for your array, but your enum has 19 entries (0..18). Increase the size of your array by 1.

EDIT: Oh, wait, I see your maxValue entry is already supposed to be a marker, not an actual value. In that case I assume a different cause: When I try the code as posted in your question, I don't get an error. So my guess is, you started off with a smaller number of enum entries when you started your script. While you're trying to initialize your array to (int)DamageType.maxValue entries, the very first time your script successfully compiles, this value is carried over to the inspector - where it sticks, even if you change your enum afterwards. Check your inspector - it probably shows 17 for "damageModifiers". To prevent this, initialize your array size in Awake() or Start(), instead of globally (unless you need to modify it in the inspector).

Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image CHPedersen · Jan 07, 2013 at 01:36 PM 0
Share

I disagree with this. If the array hadn't been explicitly assigned, maybe. (That is, if his code had just said public float[] damage$$anonymous$$odifiers;) and he had then used the inspector to assign it, then yes. But his code explicitly sets the length of that array at runtime. The editor shouldn't have any power there.

avatar image Wolfram · Jan 07, 2013 at 01:41 PM 0
Share

No, but the Inspector/Editor overrides any globally initialized values in scripts. Once the variable was visible in the inspector at least once, any script initializations within the class outside any methods are ignored.

avatar image Damocles · Jan 07, 2013 at 02:12 PM 0
Share

That was it - thanks Wolfram. Unity had indeed serialized the length of the array. It was because when I first made the variable ages ago it was visible in the inspector and got serialized. It's no longer visible, but it still keeps the array size as part of the prefab data. Re-initializing the array before use fixes the issue.

avatar image Fattie · Jan 08, 2013 at 03:29 PM 1
Share

Does he essentially need the

@System.NonSerialized

directive? (Sorry, I don't precisely understand the question.)

As Wolf says "No, but the Inspector/Editor overrides any globally initialized values in scripts..." an annoying gotchya!

avatar image Wolfram · Jan 08, 2013 at 03:35 PM 1
Share

@Fattie: Yes, that's another possibility. However, since we're talking C#, that would be [System.NonSerialized].

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

14 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Distribute terrain in zones 3 Answers

Get ParticleSystem (Shuriken) to play from array of game objects C# 2 Answers

Obtaining the Variable of a Prefab in an array. 1 Answer

Automatically running a script when compiling 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges