Help with Layers

So, since the game I’m building involves base building, I was wondering if someone would be so kind as to help me with my layer issues, I’m trying to get them to shift like floors, so if anyone can help I’d appreciate it. Here is my code;

var moveRate = 2.0;
var scrTop = Screen.height;
var scrRight = Screen.width;
var money = 500000;
var unitCap=1;
var currentFloor = 1;

function Update () 
{
	var Floor1 = 1 << 10;
	var Floor2 = 1 << 11;
	var Floor3 = 1 << 12;
	var Floor4 = 1 << 13;
	var set = 1 << 0;

	if(Input.GetMouseButtonDown(0))
	{
		var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
		var layerMask = 1 << 8;
		if(Physics.Raycast(ray,900000000,layerMask))
		{
			Application.Quit();
		}
	}
	if(Input.GetKeyDown("f12"))
	{
		money+=100000;
	}
	if(Input.GetKeyDown("f11"))
	{
		unitCap=100;
	}
	if(Input.GetKey("up"))
	{
		transform.Translate(0,Time.deltaTime*40,0);
	}
	if(Input.GetKey("down"))
	{
		transform.Translate(0,Time.deltaTime*-40,0);
	}
	if(Input.GetKey("left"))
	{
		transform.Translate(Time.deltaTime*-40,0,0);
	}
	if(Input.GetKey("right"))
	{
		transform.Translate(Time.deltaTime*40,0,0);
	}

	if(Input.GetKey("1")&currentFloor!=1)
	{
		currentFloor=1; // There is no first floor
		camera.cullingMask-=Floor2 << 0;
		camera.cullingMask-=Floor3 << 0;
		camera.cullingMask-=Floor4 << 0;
	}
	if(Input.GetKey("2")&currentFloor!=2)
	{
		currentFloor=2;
		camera.cullingMask=Floor1 << 1;
		camera.cullingMask=Floor2 << 1;
		camera.cullingMask=Floor3 << 0;
		camera.cullingMask=Floor4 << 0;
	}
	if(Input.GetKey("3")&currentFloor!=3)
	{
		camera.cullingMask=Floor1 << 1;
		camera.cullingMask=Floor2 << 1;
		camera.cullingMask=Floor3 << 1;
		camera.cullingMask-=Floor4 << 0;
	}
	
	if(Input.GetKey("4")&currentFloor!=4)
	{
		currentFloor=4;
		camera.cullingMask=set;
	}


	
	// End of the code bits for screen movement.
}

The problem I seem to suffer is that it is funky, and shows different layers then the ones I need to be shown.

I’m not really sure what you’re trying to do with Camera.CullingMask in that code…

Integer subtraction of masks (as you do on GetKey(“1”)) is unlikely ever to do what you expect – remember, although it’s an integer type it represents a bit mask.

Saying “mask = x; mask = y; mask = z;” is also redundant; each assignment overwrites the prior one.

Assuming the camera should only render items in one particular layer, all you need to do is assign the appropriate mask, once:

if (input.GetKey("1")  currentFloor != 1) 
{
    currentFloor = 1;
    camera.cullingMask = Floor1;
}
...

Make sure your bit-shifts to set Floor1, Floor2, etc are correct (and get rid of all the extra bit shifts (<< operators) in your mask assignment code) and you should be set.

The bottom section should be using bitwise operators OR, XOR and NOT.

if(Input.GetKey("3")&currentFloor!=3)
   {
      int cullingMask = camera.cullingMask;
      cullingMask = cullingMask | (Floor1 << 1);
      cullingMask = cullingMask | (Floor2 << 1);
      cullingMask = cullingMask | (Floor3 << 1);
      cullingMask = ~(cullingMask ^ (Int.MaxValue - (Floor4 << 0)));
   }

This will take the existing CullingMask and add Floors 1, 2, and 3, while removing 4. If you want to only have those and clear off existing layers, set the original cullingMask variable to 0 instead of the current Mask.

Check Bitwise operation - Wikipedia for a bit more information on these operations ( | is the symbol for OR, ! is the symbol for NOT, and ^ is XOR).

This is off the top of my head, but the only one I’m not fully sure of is the last, and their is probably a shorter way to figure that one out.

As for using Flags check out:

Edit: Changed ! to ~, I used the wrong operator.

Thank you a lot! You’ve helped me quite a bit. :slight_smile:

But problem is it says the caret is a unexpected character.

Hmm, it could be casting.

I got the symbol from http://msdn.microsoft.com/en-us/library/zkacc7k1(v=VS.80).aspx

I’m assuming by caret you mean ^.

I just tried in C# and it seems to work. I’m sorry I’m not very proficient using Unityscript (javascript for Unity).
Althought is certainly should be included within the language.

However if you meant the !, then the solution is to change it to ~, as I accidentally wrote the incorrect operator.

I assumed that the Floors were just small ints, but I’m kind of curious as to why you bitshift them twice.

If the << 0 and << 1 inside the if statement were meant to be on and off settings remove them and just use the floor variable.

None of this is working, any other ideas?

What does “<<” do?

It has to do with Bit Shifting I think.

I looked up Bit Shifting and found alot on how to do it but just out of curiosity Why would you do it?

I don’t know.

Bit Shifting is the << symbol.

It’s used for Flags:

Remember that flags can be interpreted in Binary.

if you want flags 4 and 2 on it’s

0000 1010

Only Flag 1:

0000 0001

The Last 4 Flags:

1111 0000:

Now for Bitshifting.

1 is:
0000 0001

Now if I want to flag the nth bit, I can use 2 to the power of (n) to get the value, or I could do this:

1 << n

For example, If I want the 6th flag (0 indexed)

1 = 0000 0001
1^5 = 32 = 0001 0000
1 << 5 = 0010 0000

So bitshifting is just a clearer way to represent a layer.

As for GameSnake, It looks like a number of the bitshifting logic is flawed.

Your Floor variables are already properly set when initialized, no need to change them again when you set them. Use Binary operators like I listed above to combine or remove those flags.

Edit:

The reason that Bitshifting is used, is because an object can only be on one layer, but a camera can read any number of layers. This means that you can’t just tell a camera to draw layer 5, but have to say draw 1, 4, 2, 3, and 8. You could use an int array, but that is incredibly bulky and slow. Instead you use flags. flags are a binary type and therefore use binary operators. It allows you to select a multitude of values incredibly fast and cheaply while also allowing another variable to only contain one of those values.

If you could better elaborate what it is you want to achieve exaclty maybe I could help a bit.
Do you want to Only load the levels listed when you press a certain key? Do you want to just swap the loaded levels depending on Key? Do you want it to remember what is currently loaded or discard it? What layers are your floors marked as?

Also it appears ^ doesn’t work in JS.

Check out http://forum.unity3d.com/viewtopic.php?t=61277 for alternatives.

What’s the easier way of doing this? I know there’s got to be one.

I don’t see how it can get much easier…

  • to set the culling mask to a specific layer: camera.cullingMask = mask;
  • to set the culling mask to include two or more layers: camera.cullingMask = mask1 | mask2 | ...;

You already have the masks (your Floor1, Floor2, … variables). You don’t need to worry about all the binary logic/maths Ntero posted unless you want to understand the theory behind what you’re doing.[/list]

Laurie, thank you so much.

None of this is working… How exactly is that | Floor3 thing supposed to work?

Not working how? What is happening? (Or what isn’t?)

Post your code as it is now – if you’ve simplified it as suggested above, the most likely problem is that your initial masks aren’t right. Here’s an alternative way to get the masks that might be easier to work with:

int Floor1 = (1 << LayerMask.NameToLayer("My First Level"));
...
if (input.GetKey("1")) {
    camera.cullingMask = Floor1;
}

Note I haven’t checked that works as expected, but it’s something else to try :stuck_out_tongue: