(flags & CollisionFlags.CollidedBelow) != 0; ???


I am trying to make some C# script, and it goes surprisingly good, but I got stuck by 2 lines I don't understand.

` CollisionFlags flags = controller.Move(transform.forward * verticalInput + Vector3.up * upwardSpeed + addMovement);

grounded = (flags & CollisionFlags.CollidedBelow) != 0; `

Mainly the second line is a problem. What does the &-mark do, and where is the !=0 for? And for the first line: an collision is equal to a movement? does that make sence? Can someone explain this in meta language?

I hope some of you can help me out. tnx.

PS: this is indeed the basic CharacterMovement script, edited a bit here and there.

Flags are a special type of variable harking back to the nature of how memory is stored: in binary. Fortunately, you don't need to understand the why to understand how they work.

A flag variable holds one or more bit/bool (true/false) values. Each CharacterController has a CharacterController.collisionFlags flag variable. This flag lets you know if you controller has collided with any other object and also where it collided. It has four bool values:

  • none
  • sides
  • above
  • below

Although a flag's bit values can be true or false in any combination, the controller will prevent "none" from being combined with any others because that doesn't make sense. However, it does make sense that you could collide with sides AND below, such as if you're on the ground and leaning against a wall.

As for its relation to Move(), the function returns this variable (which you can also always get through CharacterController.collisoinFlags) as a matter of convenience. Commonly, after moving your character, you need to know if it just hit something.

The & Syntax

You also asked about the syntax and what it means in plain English.

grounded = (flags & CollisionFlags.CollidedBelow) != 0;

For starters, when comparing flags you are required to use "&" to request any flags that are shared between two flags and "|" to request any flags that either of the two have.

The statement above is asking first to see which flags they have in common. The flags variable can have any of the four flags I mentioned set. The CollisionFlags.CollidedBelow only has the below flag set. When compared to see what they have in common, it'll either return "none" (which is also represented by zero) or "below". You could also write it as so:

bool grounded = (flags & CollisionFlags.CollidedBelow);
CollisionFlags myFlags = (flags & CollisionFlags.CollidedBelow);
grounded = myFlags == CollisionFlags.CollidedBelow;
grounded = myflags != CollisionFlags.None;

See this SO question for a technical explanation.