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
0
Question by NeatWolf · Mar 27, 2014 at 11:56 PM · datatypesetcollection

What's the best way to implement a "set" data Type in C#?

Hi Unity Answers Community,

I was wondering, (may be answered before but couldn't find the answer), is there a "set" data type in Unity's C#?

That is, an enum which elements could be present or not in a single time (e.g: in a game, the enemy's immunities: fire, water and death)

something that could be easily implementable in the Inspector, much like the Culling mask of a Camera.

I was dreaming of a syntax like:

 public set ImmunitiesSet of {
 Fire,
 Ice,
 Holy
 }

that automagically shows up properly in the inspector and allows Mask-like operations.

Since I'm pretty sure there isn't a native solution, in your experience what's the most straightforward way to implement this, in the most general case?

Thanks for your time.

Comment
Add comment · Show 1
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 dscroggi · Mar 28, 2014 at 12:32 AM 0
Share

Enum all the way. having a strongly typed list is nice although i dont think it can contain spaces. might just use a dictionary enum, string

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by Bunny83 · Mar 28, 2014 at 02:11 AM

Sure, you can use enums as bitmask, however you're limited to 32 values of course. Also you should use hex numbers to specify the bitmask values, it's less error prone ;)

 public enum SomeBitMask
 {
     Value1  = 0x0001,
     Value2  = 0x0002,
     Value3  = 0x0004,
     Value4  = 0x0008,
     Value5  = 0x0010,
     Value6  = 0x0020,
     Value7  = 0x0040,
     // ...
 }

To display a bitmask dropdown list in the inspector you can use this property drawer i've written.

Comment
Add comment · Show 2 · 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 NeatWolf · Mar 28, 2014 at 11:49 AM 0
Share

Looks like a nice solution, I'll take some time to study it.

I was also wondering if changing the enum element types to string would be a nice move (to allow an infinite number of elements) or not. Or maybe a hashmap. I fear to overcomplicate this, this really should have been a native data structure.

avatar image Bunny83 · Apr 02, 2014 at 04:23 AM 0
Share

@NeatWolf:
The great thing about bitmasks is that they are fast and don't require much memory (just one "int" [4 bytes]).

Enums can only use an integral type as underlying type, so a string doesn't work, especially since a string isn't a value-type and doesn't have bit-operator support ;)

You could boost the bitmask up to 64 values by using ulong / int64 as underlying type but you won't get any further than that. If you need more than 32 / 64 you might want to use the HashSet type. It's of course slower and requires more memory but does support "unlimited" elements.

ps:
If the question is answered, could you accept one of the answers to close the question?

avatar image
0

Answer by gfoot · Mar 28, 2014 at 01:08 AM

Depending on the use case you could use a bit field, combining emum values together, but it's not particularly well-supported by the language.

It is far clearer to just use a class containing a few public bool members.

 public class Immunities
 {
     public bool Fire;
     public bool Ice;
     public bool Holly;
 }

Then you can add an Immunities field to your components and check the boxes in the Inspector, and the syntax for checking them from code is straightforward and readable.

Comment
Add comment · Show 4 · 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 NeatWolf · Mar 28, 2014 at 01:27 AM 0
Share

This means I have to rewrite part of the code, and the inspector editor class almost each time, but I see your point.

Why do you say it's not particularly well supported? Does something weird happen to have something like

 public enum Immunities
 {
     Fire=1,
     Ice=2,
     Holy=4
 }

and doing some bitmasking?

avatar image gfoot · Mar 28, 2014 at 09:54 AM 0
Share

I just meant that custom code to manage bitfields is more complex to write and use than if you let the language do the heavy lifting by splitting the bits into separate bools.

Compare this:

 if (myImmunities & Immunity_Ice)
 {
     myImmunities |= Immunity_Holly;
     myImmunities &= ~Immunity_Fire;
 }

To this:

 if (myImmunities.Ice)
 {
     myImmunities.Holly = true;
     myImmunities.Fire = false;
 }

For me, the second is much clearer to read, with less potential for error at the call site.

However, the code to check whether two instances have some flags in common is much briefer with the bit field version, because that's what bit fields are particularly good for.

If you do go with a bit field anyway (a lot of people do), you may be able to wrap it in a struct and provide properties to make it look more like the bool version. It depends a bit on the usage.

Also, whichever way you go, you shouldn't have to rewrite your editor class each time you change the elements in your class/enum - you should probably be using reflection in the editor class to automatically present whichever ones are defined (like Unity does in the default Inspector).

avatar image Bunny83 · Mar 28, 2014 at 02:23 PM 1
Share

But the point of sets and set operations is to work on sets itself. So a union operation would be much more complicated with your "set".

How would you combine (union) those two sets:

 Immunities set1 = new Immunities();
 set1.Fire = true;
 Immunities set2 = new Immunities();
 set2.Ice = true;
 set2.Holy = true;
 // [...]
 Immunities combined = set1 | set2; 

Set operations are the msin point of using sets, right?

avatar image gfoot · Mar 28, 2014 at 02:37 PM 1
Share

Sure, like many things it depends exactly what you're going to use it for. If set operations are the focus then a bit field will work better; and there's always the option of HashSet, which has a wider range of operators.

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

23 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Is it possible to use a custom object in java (my WeaponObject) as a data type (like Vector3) 1 Answer

Creating a data type instance difference question 1 Answer

What data is automatically sent to Unity by the end user's Unity project content 1 Answer

Calabrate Accelerometer 1 Answer

When creating new elements how do you auto set values? 1 Answer


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