【问题标题】:How to change object's layer at runtime in Unity?如何在 Unity 运行时更改对象的图层?
【发布时间】:2016-11-30 01:04:54
【问题描述】:

我有 WallCreator 脚本来在 Unity 中放置墙壁,还有一个 WallCreatorSwitcher 通过检查切换开关来打开/关闭 WallCreator。我还想使用 @987654321 @更改WallPrefab的层,因此,当检查切换(WallCreator On)时,层是“忽略的raycast”,并且它可以工作,并且如果不受控制(WallCreator Off)(WallCreator Off)层是“ DEFAULT”,则为“ default”。 - 但问题是,在这种情况下它并没有改变图层。

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

       }

   }    

}

【问题讨论】:

  • 想必,您在这里面临的问题是GetComponent&lt;WallCreator&gt;().enabled = false; 完全停止了正在与之交互的组件,因此您可能必须打开它,更改图层,然后再打开它退出,或者在关闭之前进行图层切换
  • 即使我删除了GetComponent&lt;WallCreator&gt;().enabled = false;(因此即使未选中切换开关我也可以放置墙壁),图层仅针对新对象进行更改。我的意思是,例如,我将 wall1 放置为 ON - 它的图层是“Ignore Raycast”,然后我将切换切换到 OFF,放置 wall2 - 它的图层是“Default”,但 wall1 的图层不会改变
  • 我没有意识到你的意思是之前放置的墙壁,这完全是一个不同的问题。较新的墙在更改后位于默认图层中 - 这是因为更改预制件会更改创建墙时放置的内容,而不是已经存在的内容。要更改所有墙的层,您可以执行以下操作(假设墙有标签wall):GameObject[] walls = GameObject.FindGameObjectsWithTag("wall"); 然后您可以通过 foreach 循环操作它们
  • 您还应该发布您的WallCreator 脚​​本并描述每个脚本的附加位置
  • @AlfieGoodacre 是的,我可能没有正确地提出我的问题。无论如何,您的回答很有帮助,现在可以使用了,谢谢

标签: c# unity3d runtime


【解决方案1】:

新墙在放置后位于Default 层中,因为它在预制件中被更改 - 这是因为更改预制件会更改创建墙时放置的内容,而不是已经存在的内容。要更改所有墙壁的图层,您可以执行以下操作(假设墙壁有标签墙)

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

这将遍历场景中的每一面墙并将其图层更改为您想要的图层。同样重要的是WallCreator 的属性也发生了变化,因此此更改后放置的墙将保留在新图层上而不是旧图层上

【讨论】:

    【解决方案2】:

    看起来好像您没有引用 wallPrefab 的游戏对象,这可能是问题所在。变化:

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

    收件人:

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

    虽然没有看到其他脚本,但我不能确定这是否能解决问题。

    【讨论】:

    • 阅读他们的这部分评论 - “我将 wall1 放置为 ON - 它的图层是“忽略 Raycast”,然后我将切换开关切换到 OFF,放置 wall2 - 它的图层是“默认” ,但是wall1的图层没有改变”,图层IS在改变,但他们实际上希望旧墙改变图层
    • 知道了,没看到。不过,引用 gameObject 仍然是一个好习惯。我会说你上面的评论应该这样做,找到所有对象并以这种方式更改它们的图层!
    • 循环遍历它们的另一个好处是您可以从FindGameObjectsWithTag 获得GameObject
    • 确实如此,代码行数减少了,您可以确定图层已更改。做得很好,这是一个非常优雅的解决方案。
    猜你喜欢
    • 2018-07-30
    • 1970-01-01
    • 2021-04-09
    • 2016-09-28
    • 2012-01-20
    • 2013-07-09
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多