artur47wien artur47wien - 8 days ago 5
C# Question

How to change object's layer at runtime in Unity?

I've got WallCreator script to place walls in Unity, and another one, WallCreatorSwitcher to turn WallCreator ON/OFF by checking the toggle. I also wanted to change wallPrefab's layer there by using

GetComponent<WallCreator>().wallPrefab.layer = LayerMask.NameToLayer("LayerName");
, so when the toggle is checked (WallCreator ON) layer is "Ignore Raycast" - and it works, and if the toggle is unchecked (WallCreator OFF) layer is "Default" - but the problem is, it's not changing the layer in this case.

public class WallCreatorSwitcher : MonoBehaviour {

public Toggle toggle;
public Text text;


// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
if (toggle.isOn)
{
GetComponent<WallCreator>().enabled = true;
Debug.Log("Wall Creator is ON");
text.enabled = true;
GetComponent<WallCreator>().wallPrefab.layer = LayerMask.NameToLayer("Ignore Raycast");

}

else
{
GetComponent<WallCreator>().enabled = false;
Debug.Log("Wall Creator is OFF");
text.enabled = false;
GetComponent<WallCreator>().wallPrefab.layer = LayerMask.NameToLayer("Default");

}

}

}

Answer

The newer walls, when placed, are in the Default layer after it's been changed in the prefab - and that is because changing the prefab changes what is placed when you create a wall, not what's already there. To change the layer of ALL walls, you can do something like this (assuming the walls have the tag wall)

GetComponent<WallCreator>().wallPrefab.gameObject.layer = LayerMask.NameToLayer("Default");
GameObject[] walls = GameObject.FindGameObjectsWithTag("wall");
foreach(GameObject wall in walls)
{
    wall.layer = LayerMask.NameToLayer("Default");
}

This will loop through every wall in the scene and change its layer to the one you want. It is also important that the WallCreator still has its property changed also, so that walls placed after this change, will remain on the new layer as opposed to the old one