#Mr Frog Learns to Count

1 messages · Page 1 of 1 (latest)

honest wigeon
#

Let's keep this in here @opal ivy

opal ivy
#

ok, but you didn't have to do me dirty

smoky owl
#

2

honest wigeon
#

So, binary is a way of counting

#

0011 in binary means "three"

opal ivy
#

in 1 and 0

honest wigeon
#

Since each "digit" can only be 0 or 1, that means it's also kind of like a boolean right?

#

Booleans can only be true or false, binary digits can only be 1 or 0

opal ivy
#

yes

honest wigeon
#

they're basically the same thing

#

Now, 3 in binary is 0011

#

This is the same as an array of [false, false, true, true]

#

Meaning you can now store four variables in one

#

Except an int is thirty-two bits, meaning one variable can hold thirty-two boolean variables

#

A layer mask is one of these psuedo-lists

smoky glade
#

Fun fact, each "1" in a binary number is double the one to the right of it.

So 0001 = 1
And 0010 = 2
Then 0100 = 4
Then 1000 = 8

It's easy to remember it all that way if you ever try to count them.

honest wigeon
#

Do you see now how binary and layer masks are intrinsically linked, @opal ivy

#

does this work for you

opal ivy
#

what i understand that 4 digits make one number and so on.

honest wigeon
#

So, layerMask is essentially bool[], except stored in one number

#

Let's pretend we have only four layers, it's easier than working with 32.

#

Let's give them names and numbers:

Dirt = 0
Mud = 1
Water = 2
Grass = 3
opal ivy
#

ok so if i want to check if an object is an layer well i need to refer the number of the layer

honest wigeon
#

So, a layer mask that says "Yes dirt and mud, no water or grass" would have 1 in positions zero and one.

Binary numbers are read right to left, so that's
0011

#

The layer mask containing both dirt and mud is therefore 3

smoky glade
# opal ivy what i understand that 4 digits make one number and so on.

This really depends on what you're using. In c# you often use integers (defined with "int"), and these are actually 32 bits (binary numbers), not 4.
You also have the short type, which is 16, and the long type, being 64.
You often also define these as either int16, int32 or int64, depending on the number of bits.

You got a lot more, but those are the most common ones.
If you think of 4 bits in a number, you think of a byte type, by the way. c# also has those.

honest wigeon
#

So,

LayerMask groundMask = LayerMask.GetMask("Dirt", "Mud");
Debug.Log(groundMask);

this prints "3"

#

Does this make sense so far

opal ivy
#

not really

#

true is dirt and mud, and false is water and grass

honest wigeon
#

What doesn't make sense so I can go back

honest wigeon
#

We want the mask that says "Please let through dirt and mud, but not water or grass"

#

We have not checked an object yet

#

This is solely to create the mask

#

The bouncer at the nightclub

opal ivy
honest wigeon
#

"You ain't getting in with that layer"

honest wigeon
#
Grass = Nope = 0
Water = Nope = 0
Mud   = Yeah = 1
Dirt  = Yeah = 1

Reading those numbers on the column gets us 0011, the layer mask.

#

Better?

opal ivy
#

Yes

honest wigeon
#

So, if you had an object on the "Dirt" layer named dirtBlock, then dirtBlock.Layer would be 0.

#

If you were to do dirtBlock.Layer == groundMask, it would be checking if 0 == 3, which is false

#

Because that's not how you're meant to check a layer mask. Do you understand know what the problem is, even if you don't know how to solve it yet?

opal ivy
#

I am checking for a single layer ? Corect me if am wrong

honest wigeon
#

You want to check if a single layer is in the layer mask

#

which you can't do with ==

opal ivy
#

The layer of the object is 0. And i am checking to see if the object has the layer dirt or mudd, and the dirt layer is 1 and the mud zero, i would check if the object has the layer 3 ?

honest wigeon
#

This is merely attempting to understand the problem

#

As in, "Why does this not work" you posted to start this out

opal ivy
#

Yes i know. Wait a few seconds i am trying to think logically what the problem might be

honest wigeon
opal ivy
#

What "<<"

#

Is ?

honest wigeon
# opal ivy What "<<"

x << y will take the binary digit x and push it to the left y many times, filling the empty space with zeroes

#

1 << 3 takes the 1 and pushes it three spaces, so 1000

opal ivy
honest wigeon
#

Counting in decimal: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
Counting in binary: 1, 10, 11, 100, 101, 110, 111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111

#

That is why groundMask is 3

honest wigeon
opal ivy
#

I think the problem is that i am checking for the third layer in the layer mask. Not for the layers i actually want to check is that correct

honest wigeon
#

In order to solve this problem, first we have to establish why this doesn't work

#

Do you know have a good idea of why that doesn't work

opal ivy
#

That doesn't work beacose I am checking if a number is equal to an array ?

honest wigeon
#

It doesn't throw an error because that array is stored in a number using math

#

But that is indeed the problem

#

Now, shall we move on to the solution on how to check if a layer is in a mask?

opal ivy
#

Yes

honest wigeon
#

So, last time on Dragon Ball Z:
We had an object, dirtBlock that is on the Dirt layer, and a groundMask that lets through Dirt and Mud

#

If we do dirtBlock.layer it gets the layer index, which is 0

#

So, we need a number that has a 1 in position 0, the first digit.

#

So, we want to start with a 1 and "push" it 0 times. 1 << dirtBlock.layer gets us the binary value 0001

#

Now, we need to check if it has any numbers in common with our LayerMask. This can be done with &, a "bitwise and"

#

0001 & 0011 checks each bit in order. 0 & 0, then 0 & 0, then 0 & 1, then 1 & 1, and puts a 1 if both values are 1. It ends up looking like this:

0001
0011
____
0001
#

If there are any 1s in that list, that means there is an overlap between our layer and the mask

#

Since 0 in binary is 0000, if our number is not zero, then that means it must contain a 1 somewhere

#

Putting it together, we get:

if ((1 << dirtBlock.layer) & groundMask != 0){
  Debug.Log("Dirt Block passes through the mask");
}
#

Do you follow this now?

honest wigeon
#

It checks if there's a true in the same place in both lists

opal ivy
#

So we got two lists, the layers and the layer mask, and we check if the layer mask contains the layers dirt and mud ?

honest wigeon
opal ivy
#

So if the layer of the dirt block is 0001 and the layer mask is 0011 we check for the 1

honest wigeon
#

If we looked for mudBlock instead, we'd do 0010 & 0011 which would get us 0010

opal ivy
#

So the one is the layer we want to let through

honest wigeon
opal ivy
#

Wich "one"

#

?

#

The layer

#

We want to let through is 1

honest wigeon
#

that's what I thought you were saying, but I realized there were a lot of "ones" there

#

so I didn't want to lead you down the wrong path if you were asking about one of the numbers

#

Yes, mud is layer one, which would mean 1 << mudBlock.layer would be 1 << 1 or "one pushed to the left one space", or 0010

#

Now, if we had waterBlock, its index is 2, so 1 << waterBlock.layer is 1 << 2, which is "one pushed to the left twice", or 0100. If we were to do 0100 & 0011, we would end up with 0000. They don't have any 1s in common

#

Is it starting to come together or do I need to go back

opal ivy
#

So we got 0000 at start for 4 layer. We want to check if the object has the layer mud or dirt, depending on the index of the layer we push a one to the left ?

honest wigeon
#

We still can't check if they're equal though, because a layer mask can have more than one layer in it

#

That's why we use & to check it instead

#

That checks each individual bit for equality, rather than the entire number

opal ivy
#

So we check if those two lists have something in common not if they're equal , so that's why it was not working?

honest wigeon
#

They aren't going to be exactly equal, so == and != are not actually helpful here

#

We need to check if they have at least one digit equal

#

End result?

bool isObjectInLayer = (1 << someObject.layer) & layerMaskToCheck != 0
#

That is how you check if any object is in a layer mask, no matter what that object's layer or how many or few layers are in the mask

opal ivy
honest wigeon
#

Yep

opal ivy
#

But one question you put "&" instead of "&&" what's the difference

honest wigeon
#

After an hour of explanation, I'd hope that you can understand why it does that, and not just a blind copypasta you'd get from google

honest wigeon
#

When you're dealing with numbers, it's &, with booleans, it's &&. The number case actually came first (punch cards being what they were in the 80s), and the concept of a separate data type for "boolean" is a more modern invention

#

that's why it gets the longer symbol

opal ivy
#

Oh, i get it thanks digiholic. Can I save this chat ? Or it will delete ? And a question just for curiosity, how long you have been programing, did you work on any games ?

honest wigeon
#

I have been programming in some capacity for 15 years, and I mostly have a graveyard of abandoned games and game jam submissions that I didn't finish in time, nothing released. I guide others to a treasure I cannot possess

opal ivy
#

You're a legend, dude every time you actually helped me i have been saving those explanations and examples you were giving