【问题标题】:Making an object inaccessible at runtime使对象在运行时不可访问
【发布时间】:2016-03-08 20:49:25
【问题描述】:

我有一个非常具体的问题。我的场景中有一堆立方体。

当我点击其中一个时该立方体变为红色(或我的阵列中的其他颜色之一)几秒钟,此脚本将应用于我的所有立方体。

现在我想要发生的是只要其中一个立方体是红色的,其他的就无法访问(当我点击它们时它们不会改变颜色)。

这是我的立方体的代码:

private renderer render;

void Start()
{
    render = GetComponent<renderer>();
}

private Color[] colors = {Color.red, Color.green, color.yellow);

void Update(){}

void OnMouseDown()
{
    render.material.color = colors[Random.Range(0, colors.Lenght)];
}

【问题讨论】:

  • 您的示例代码不完整,不能反映您所解释的行为。尝试提供更多代码来解释您想要实现的目标。
  • 一种可能的解决方案是在事件处理程序中获取所有立方体的颜色。如果任何立方体是红色的,那么什么都不应该做。

标签: c# unity3d


【解决方案1】:

您需要设置class 级别Boolean 来控制其中一个立方体何时为红色,例如:

static bool _bBlockMouseDown;

void OnMouseDown()
{
    Color color = colors[Random.Range(0, colors.Lenght)];
    if (color == Color.Red)
    {
        _bBlockMouseDown = true;
        render.material.color = color; //Force the color to be set here
    }

    if (!_bBlockMouseDown)
    {
        render.material.color = color;
    }
}

此代码将立方体更改为随机颜色,如果它是红色,则将 Boolean 设置为 true,这将阻止任何其他立方体设置颜色。所有这些需要是只要立方体不再是红色,只需将 _bBlockMouseDown 变量更改为 true。

注意:_bBlockMouseDown 变量是静态的,因此它在所有多维数据集中包含相同的值。

对此的替代解决方案是使用System.Linq 命名空间并拥有一个多维数据集列表。类似于以下内容:

void OnMouseDown()
{
    if (!listOfCubes.Any(c => c.material.color == Color.Red))
    {
        render.material.color = colors[Random.Range(0, colors.Lenght)];
    }
}

这种方法的缺点是如果有很多立方体,它会稍微慢一些。

【讨论】:

  • 非常感谢,第一个解决方案正是我想要的
  • 我不明白第二种解决方案,关于总共有 30 个立方体,第二种解决方案会更容易
  • @ali10gaucho 第二个解决方案需要将所有多维数据集添加到列表中,当您通过OnMouseDown 调用更新多维数据集时,它会使用linq 方法@987654330 检查任何具有红色的多维数据集@。如果没有红色立方体,它会分配颜色,否则它将继续,即阻止呼叫。
  • @BarışÇırıka 我确实在答案的底部提到了这一点
【解决方案2】:

糟糕...我以为我发布了答案,但没有通过。不管怎样,代码已经写好了,我不能把它扔掉。

此方法使用数组。将编辑器中的数组大小更改为 5,并为其分配 5 个立方体。红色立方体只会改变颜色,其余的不会改变,除非场景中没有红色立方体。

public GameObject[] cubes;

void Start()
{

}

private Color[] colors = { Color.red, Color.green, Color.yellow };

void Update()
{
    checkMouseClick();
}


void checkMouseClick()
{
    MeshRenderer tempMR;

    //Check if mouse button is pressed
    if (Input.GetMouseButtonDown(0))
    {
        RaycastHit hitInfo = new RaycastHit();
        if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo))
        {
            tempMR = hitInfo.collider.gameObject.GetComponent<MeshRenderer>();

            int cubeSize = cubes.Length;

            //Loop through all the cubes in in cubes array
            for (int i = 0; i < cubeSize; i++)
            {
                //Check if any of them have a red color
                if (cubes[i].GetComponent<MeshRenderer>().material.color == Color.red)
                {
                    //if the cube we clicked is alread read, go ahead and generate a new color for it, else DONT CHANGE THE COLOR
                    if (cubes[i] == hitInfo.collider.gameObject)
                    {

                    }
                    else
                    {
                        return; //Exit if any cube has the red color
                    }
                }
            }

            //No cube has a red color, change the color of clicked cube to a random color
            tempMR.material.color = colors[Random.Range(0, colors.Length)];
        }
    }
}

【讨论】:

    猜你喜欢
    • 2018-09-28
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 2019-12-28
    相关资源
    最近更新 更多