Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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");

       }

   }    

}
like image 432
artur47wien Avatar asked Nov 29 '16 15:11

artur47wien


People also ask

How do I change a runtime layer?

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.

How do you check an object's layer in Unity?

Unity generates 32 layers, labelled with integers from 0 to 31 and reserves layers 0 to 5 for its own systems. You can use layers 5 and above. To add or view a layer, click the Layout button in the top-right of the Editor window.


2 Answers

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

like image 75
Alfie Goodacre Avatar answered Sep 27 '22 20:09

Alfie Goodacre


It appears as if you aren't referencing the gameObject of the wallPrefab, which could be the problem. Change:

GetComponent<WallCreator>().wallPrefab.layer = LayerMask.NameToLayer("Ignore Raycast");

To:

GetComponent<WallCreator>().wallPrefab.gameObject.layer = LayerMask.NameToLayer("Ignore Raycast");

Without seeing the other scripts, I can't be sure this will fix the problem though.

like image 42
KenSchnetz Avatar answered Sep 27 '22 20:09

KenSchnetz