-4

Unity3d PlayerPrefs only allow saving certain types - string, float, and int32. Since int is composed of 32 bits, it should be able to store 32 flags or a bool[] of length 32.

So far, I've thought about setting the int based on a binary number of 32 digits, where each digit represents a flag. I'm having trouble doing this with consideration of negative numbers.

Is there a way to access each individual bit of the int without recursive math to store and use them as flags?

JPtheK9
  • 189
  • 1
  • 2
  • 11
  • why didn't you ask at Stack Overflow? http://meta.stackexchange.com/a/129632/165773 – gnat May 26 '15 at 04:21
  • It says that "we are no longer accepting answers from this account". Been like that for about a year. – JPtheK9 May 26 '15 at 04:32
  • 1
    Do not post off-topic content on a site in an [attempt to circumvent a question block on another site](http://meta.programmers.stackexchange.com/questions/7020/lets-help-askers-who-are-trying-to-circumvent-question-block-at-stack-overflow). This is not an appropriate question here - if you wish to get out of the block on Stack Overflow, please read the linked article that appears on the block message. You know, [this one](http://stackoverflow.com/help/question-bans). – gnat May 26 '15 at 04:32
  • @gnat I've been reading through the on-topics in the help center and I think my question might fall under algorithm and data structure concepts. I'm not as experienced with this community as you but do you think this might be the case? – JPtheK9 May 26 '15 at 08:46
  • "Is there a built-in method in C# to save an array of flags as an integer?" doesn't read like about algorithm and data structure concepts. Regarding your block at SO, you could simply remove and recreate account and continue asking questions there at a [rate one per week](http://meta.stackexchange.com/a/234518/165773 "as explained here") - provided that you will abstain of asking poor ones (your question here suggests that you could do that) – gnat May 26 '15 at 10:48
  • So if I delete "Is there a built-in method in C#..." and just ask about how to store 32 flags in the 32 bits of an integer, will my question be on topic? – JPtheK9 May 26 '15 at 19:47

3 Answers3

3

Yes, there is a Flags attribute that lets you use enums as flags for an int, and the type has methods to help identify if a flag is set and the such.

Telastyn
  • 108,850
  • 29
  • 239
  • 365
  • Sorry I'm a bit of a newb with the Flags attribute. How would I convert an array of 32 booleans into an int, then reconstruct this array from an int with this? – JPtheK9 May 26 '15 at 03:05
  • @JPtheK9 - you wouldn't have 32 booleans, you would have 32 enum values. At that point it is simply a matter of casting to/from the int/enum. – Telastyn May 26 '15 at 11:12
1

Expanding on @Telastyn's answer, you can declare your flags as an enum with the Flags attribute instead of using an array of booleans:

[Flags]
public enum Options : uint {
    Empty = 0,
    FancyClouds = 1,
    EnhancedGrassTextures = 2,
    HiDefNoses = 4,
    NoPantsMode = 8,
    // etc. values are increasing powers of 2 up to 2^31
}

You can fiddle with the flags using bitwise operators:

Options flags = Options.HiDefNoses | Options.FancyClouds;
flags &= ~Options.HiDefNoses;               // remove an option
if ((flags & Options.HiDefNoses) != 0) {    // test an option
if (flags.HasFlag(Options.HiDefNoses)) {    // same thing, nicer(?) syntax

And the enum value can be (explicitly) cast to and from Int32:

int i = (int)flags;
Options o = (Options)i;     // round-tripped to int and back
Blorgbeard
  • 203
  • 1
  • 10
  • Thanks! After saving the int and getting it back, how do I turn it back into a bunch of flags? – JPtheK9 May 26 '15 at 04:21
  • `Options o = (Options)i;` converts from an `int` to the `enum`. If you want to convert either the enum or the int to a list of bools, there's not really a shortcut in the standard library that I know of. – Blorgbeard May 26 '15 at 04:32
  • Ah, okay. Well thanks for the in-depth explanation. – JPtheK9 May 26 '15 at 04:32
  • @JPtheK9 Check the accepted answer here: http://stackoverflow.com/questions/4171140/iterate-over-values-in-flags-enum Works a treat. – BrianH May 27 '15 at 17:58
  • Thanks! I took the easy way out and just converted a BitArray to a byte[] then finally an int32 but I never knew that enums could be used in that way. – JPtheK9 May 27 '15 at 18:38
0

Here is what I came up with:

The Flags attribute way consisted of several tricky pitfalls. For example, bit shifts on signed ints are arithmetic so the sign bit can't be easily used. Also, reconstructing the array of flags from a bitmask can get really mess, as blorgbeard mentioned.

Instead, I used the System.BitArray class which which is easily accessible with indexes. BitArray allows for easy serialization and deserialization to and from an int. BitArray offers a CopyTo() method to copy its bits to a byte array which can then be converted to an int with BitConverter.ToInt32(). To reconstruct the BitArray, a constructor can be used that takes a byte array generated from BitConverter.GetBytes().

I.e.

//Serializing 32 flags into int
BitArray bitArray = new BitArray (32);
byte[] byteBuffer = new byte[4];
bitArray.Copyto (byteBuffer, 0);
int SerializedFlags = BitConverter.ToInt32 (byteBuffer, 0);

//Reconstructing 32 flags from int
byteBuffer = BitConverter.GetBytes(SerializedFlags);
bitArray = new BitArray (byteBuffer);
JPtheK9
  • 189
  • 1
  • 2
  • 11