#Mr Frog Learns to Count
1 messages · Page 1 of 1 (latest)
ok, but you didn't have to do me dirty
2
in 1 and 0
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
yes
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
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.
Do you see now how binary and layer masks are intrinsically linked, @opal ivy
does this work for you
what i understand that 4 digits make one number and so on.
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
ok so if i want to check if an object is an layer well i need to refer the number of the layer
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
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.
So,
LayerMask groundMask = LayerMask.GetMask("Dirt", "Mud");
Debug.Log(groundMask);
this prints "3"
Does this make sense so far
What doesn't make sense so I can go back
We're not checking if a layer is in it yet
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
Ok so here we get the layers we want to allow
"You ain't getting in with that layer"
Yes. The layer mask is a list of booleans for whether that layer should be "allowed" or not
Grass = Nope = 0
Water = Nope = 0
Mud = Yeah = 1
Dirt = Yeah = 1
Reading those numbers on the column gets us 0011, the layer mask.
That is what a layer mask is. A list of "allowed layers" stored in a number in binary, as described here:
#1100517354779189338 message
Better?
Yes
Okay, so, now that we know what a layer mask is, and how it turns into a number, let's go back and remember that each layer has an index, defined up here
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?
I am checking for a single layer ? Corect me if am wrong
You want to check if a single layer is in the layer mask
which you can't do with ==
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 ?
We aren't at the point where we are trying to find a solution yet don't get ahead.
This is merely attempting to understand the problem
As in, "Why does this not work" you posted to start this out
Yes i know. Wait a few seconds i am trying to think logically what the problem might be
If you want to work it out, here's some tools to put in your toolbox that you might not know:
x << y will take the binary digit x and push it to the left y many times, filling the empty space with zeroes
x & y will return the number that has 1 in every digit that x and y both have a 1, and 0 everywhere else
0 in binary is 0000
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
Could you tell me why it would make it 3, i don't understand that part
0011 in binary is 3
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
Using the value of groundMask we made up here
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
The problem is, you're checking if a layer index is equal to a layer mask
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
That doesn't work beacose I am checking if a number is equal to an array ?
Basically, yes
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?
Yes
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?
I am lost here
Think of them as a list
It checks if there's a true in the same place in both lists
So we got two lists, the layers and the layer mask, and we check if the layer mask contains the layers dirt and mud ?
So, we have turned the layer of dirtBlock into a list, and we have the layerMask which is a list of dirt and mud, and we check if they have any elements in common
So if the layer of the dirt block is 0001 and the layer mask is 0011 we check for the 1
Yes, if they have anything in common, there will be a 1 somewhere in the result.
If we looked for mudBlock instead, we'd do 0010 & 0011 which would get us 0010
So the one is the layer we want to let through
Before I answer this, which "one" do you mean here? Because I want to say "yes" but I want to make sure we're on the same page
Okay, right, yes
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
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 ?
Yes. That turns our layer index into the same number format the mask is looking for
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
So we check if those two lists have something in common not if they're equal , so that's why it was not working?
Right
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
Oh, so this is how it would look on code
Yep
But one question you put "&" instead of "&&" what's the difference
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
So, & checks if every bit in a number individually. && is for checking two booleans.
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
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 ?
I think it'll be archived after a few days. You won't be able to post in it but it'll be around forever, just check your post history
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
You're a legend, dude every time you actually helped me i have been saving those explanations and examples you were giving