如何同时更改多个对象的元素

时间:2019-02-22 15:14:45

标签: c# unity3d

我是Unity的新手,正在制作一款自上而下的游戏。 我编写了一个脚本,该脚本根据播放器是在对象的前面还是后面来更改对象在图层中的顺序,但是我无法弄清楚如何立即更改所有对象的图层。 (我试图让他们成为一个对象的所有子对象,但它不起作用) 我当前的代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Perspective_changer : MonoBehaviour {
    void Update () {
        GameObject librarian = GameObject.Find("Librarian");
        Layer_orderer librarian_layer = librarian.GetComponent<Layer_orderer>();
        librarian_layer.y_pos = transform.position.y;
        GameObject blue_book_stand = GameObject.Find("Blue");
        Layer_orderer blue_book_stand_layer = blue_book_stand.GetComponent<Layer_orderer>();
        blue_book_stand_layer.y_pos = transform.position.y;
        GameObject purple_book_stand = GameObject.Find("Purple");
        Layer_orderer purple_book_stand_layer = purple_book_stand.GetComponent<Layer_orderer>();
        purple_book_stand_layer.y_pos = transform.position.y;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Layer_orderer : MonoBehaviour {
    public float y_pos;
    void Start() {
    }
    void Update() {
        if (transform.position.y > y_pos)
        {
            GetComponent<SpriteRenderer>().sortingOrder = 1;
        }
        else
        {
            GetComponent<SpriteRenderer>().sortingOrder = 3;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

您可以使用FindObjectsOfType并循环执行

public class Perspective_changer : MonoBehaviour 
{
    private void Update () 
    {
        var layerOrderers= FindObjectsOfType<Layer_orderer>();librarian = GameObject.Find("Librarian");
        foreach(var layer in layerOrderers)
        {
            layer.y_pos = transform.position.y;
        }
    }
}

注意FindObjectsOfType仅会在场景中找到活动和启用的组件。


但是,尽可能不要在Find中使用GetComponentUpdate或任何重复方法,因为它们非常昂贵。最好在AwakeStart中执行一次,然后重用引用。 (我使用规则Awake获取组件并设置自己的值-Start用于获取其他组件/ GameObjects的组件/值)

public class Perspective_changer : MonoBehaviour 
{
    Layer_orderer[] layerOrderers;

    private void Start()
    {
        layerOrderers = FindObjectsOfType<Layer_orderer>();
    }

    private void Update () 
    {
        foreach(var layer in layerOrderers)
        {
            layer.y_pos = transform.position.y;
        }
    }
}

Layer_orderer

中也是如此
public class Layer_orderer : MonoBehaviour 
{
    public float y_pos;
    private SpriteRenderer _spriteRenderer;

    private void Awake()
    {
        _spriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Update()
    {
        // for single values this is easier to read/write
        _spriteRenderer.sortingOrder = transform.position.y > y_pos ? 1 : 3;
    }
}

答案 1 :(得分:0)

在每个对象上放置一个单行为,因此每个对象都会在Update()中进行更新。

或使用FindObjectsOfType()获取所有SpriteRenderers。

但是

可能会有更简单的方法来完成您要尝试做的事情。您可以在“编辑”->“项目设置”->“图形”中更改透明度排序顺序轴。将其更改为基于Y坐标的自定义轴。

Sort axis settings

然后,如果在导入精灵时将精灵的枢轴设置为地面,一切将正常工作。