Layermask error

I used layermask for the first time and had some problem to get hang of it but I got it to work as intended except I got this error.

A game object can only be in one layer. The layer needs to be in the range [0…31]
UnityEngine.GameObject:set_layer(Int32)
BuildHandle:Update() (at Assets/Scripts/Handle/BuildHandle.cs:21)

I assigned layer 8 so i don’t understand why i get an error that says the layer is not in the span of 0 to 31.

My code: The layer mask code is on line: 8,17 and 28.

public class BuildHandle : MonoBehaviour {
	
	public Buildings[] buildings;

	private GameObject buildingObject;
	private Transform buildingTransform;

	private int layermask = 1<<8;

	// Update is called once per frame
	void Update () {
		foreach(Buildings building in buildings){
			if(Input.GetKeyDown(building.hotkey)){
				buildingObject = building.building;
				buildingTransform = ((GameObject)Instantiate(building.building)).transform;

				for(int i = 0; i < buildingTransform.childCount;i++){
					buildingTransform.GetChild(i).gameObject.layer = layermask;
				}

			}
		}

		if(buildingTransform != null){
			Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
			RaycastHit hit;
			Debug.DrawRay(ray.origin,ray.direction * 100);
			
			if(Physics.Raycast(ray,out hit,Mathf.Infinity,~layermask)){
				if(hit.collider.tag == "Ground"){
					buildingTransform.position = new Vector3(hit.point.x,hit.point.y,hit.point.z);
					for(int i  =0; i < buildingTransform.childCount;i++){
						buildingTransform.GetChild(i).renderer.material.color = Color.green;
					}
				}
				else{
					for(int i  =0; i < buildingTransform.childCount;i++){
						buildingTransform.GetChild(i).renderer.material.color = Color.red;
					}
				}
			}
			else{
				for(int i  =0; i < buildingTransform.childCount;i++){
					buildingTransform.GetChild(i).renderer.material.color = Color.red;
				}
			}
		}
	}


}
[System.Serializable]
public class Buildings{
	public GameObject building;
	public string hotkey;
}

What you did with this (private int layermask = 1<<8;) line is that you shifted the bits of the number 1 by 8. If you Debug.Log it it is going to be 256 in 32 bit representation.

You are close but you dont understand the layermask enough. You can use this operator in layermask if you would like to put your layer number 8 in a LayerMask representation you can do this by the following code:

LayerMask mask |= 1<<8;

But you assigned this value to an integer and as an integer it is going to mean the number 256. And finally you assigned your value 256 to your objects layer number and this is where you didnt stay in the bounds. If you would like your raycast to only take into account your layer number 8 you should do the following:

buildingTransform.GetChild(i).gameObject.layer = 8;

then:

int layerMask = 1 << 8;
 if(Physics.Raycast(ray,out hit,Mathf.Infinity,layermask)).......

Here we also assign this value to an integer but the raycast uses the bits of this number not the actual value of it.

I also recommend the use of LayerMask.NameToLayer function. That makes your code easier to read for example:

buildingTransform.GetChild(i).gameObject.layer = LayerMask.NameToLayer("Wall");

int layerMask = 1 << LayerMask.NameToLayer("Wall");
 if(Physics.Raycast(ray,out hit,Mathf.Infinity,layermask)).......

This way you can easily understand that you only wantto raycast against walls