简体   繁体   English

如何在两个类之间统一修改List <>?

[英]How to modify List<> between two classes in unity?

In unity I'm making a program that allows you to click on a cube and select spheres that represent the vertices as shown below: 我正在统一编写一个程序,允许您单击一个多维数据集并选择表示顶点的球体,如下所示:

有顶点的多维数据集

Once theses spheres are selected they are to be added to the list selectedSpheres of type GameObject . 一旦选择了这些球体,它们将被添加到GameObject类型GameObject selectedSpheres列表GameObject

I've created two class files - Cube.cs and Vertex.cs . 我创建了两个类文件Cube.csVertex.cs Vertex inherits from Cube which inherits from MonoBehaviour . VertexCube继承,而CubeMonoBehaviour In Cube I have a member list that stores the selected spheres. 在多维数据集中,我有一个成员列表,用于存储选定的球体。

I have defined a function addToSelected() which adds the input to the selectedSpheres list. 我定义了一个函数addToSelected() ,它将输入添加到selectedSpheres列表中。 The print statement inside the function prints off true every single time. 函数内部的print语句每次都会打印true。 But the print statement in the Update() function prints an Argument out of range error as shown below while the addToSelected() has shown that it has worked 8 times: 但是Update()函数中的print语句会打印参数超出范围的错误,如下所示,而addToSelected()表明它已经工作了8次:

错误

The addToSelected() function is called from the OnMouseDown() function inside the Vertex class. Vertex类内部的OnMouseDown()函数调用addToSelected()函数。 The code for both classes is shown below: 这两个类的代码如下所示:

Cube.cs 多维数据集

public class Cube : MonoBehaviour {

    bool isSelected = false;
    GameObject[] Spheres;
    List<GameObject> selectedSpheres = new List<GameObject>();

    public void addToSelected(GameObject obj) {
        selectedSpheres.Add(obj);
        print(selectedSpheres.Contains(obj));
    }

    public void removeSelected(GameObject obj) {
        selectedSpheres.Remove(obj);
    }

    public void clearSelected() {
        selectedSpheres.Clear();
    }

    // Update is called once per frame
    void Update() {
        if(Input.GetKeyDown(KeyCode.Space)) {
            print(selectedSpheres[0]);
        }
    }
 }

Vertex.cs 顶点

public class Vertex : Cube {

    void OnMouseDown() {
        // this object was clicked - do something
        Renderer rend = GetComponent<Renderer>();

        if (rend.material.color != Color.red) {
            rend.material.color = Color.red; // #d96459
            addToSelected(this.gameObject);

        } else {
            rend.material.color = Color.white;
            removeSelected(this.gameObject);
        }
    }
}

Since Vertex inherits form Cube and Cube has the Update function 由于顶点继承了多维数据集形式,并且多维数据集具有更新功能

void Update() {
    if(Input.GetKeyDown(KeyCode.Space)) {
        print(selectedSpheres[0]);
    }
}

the statement print(selectedSpheres[0]); 语句print(selectedSpheres[0]); is executed inside of all objects that inherit from Cube everytime you press the space key. 每次您按空格键时,都会在从Cube继承的所有对象内部执行。 In some (or most) instances of Vertex selectedSpheres is empty, which is why you get an argument out of range error. 在某些(或大多数)顶点实例中, selectedSpheres为空,这就是为什么您收到参数超出范围错误的原因。 Also, you have defined a selectedSpheres list for every instance of Cube (and therefore Vertex). 此外,您还为每个Cube实例(因此也为Vertex)定义了selectedSpheres列表。 So you have 9 instances of selectedSpheres in your sample scene. 因此,您的示例场景中有9个selectedSpheres实例。 The shortest way to fix this would be to declare selectedSpheres as static. 解决此问题的最短方法是将selectedSpheres声明为static。 Then, you would have only one list for all instances of Cube/Vertex. 这样,对于多维数据集/顶点的所有实例,您将只有一个列表。

So go ahead and try: 因此,继续尝试:

static List<GameObject> selectedSpheres = new List<GameObject>();

There are a few problems with your code: 您的代码存在一些问题:

  1. Vertex shouldn't inherit from Cube since a vertex is not a cube. Vertex不应从Cube数据集继承,因为顶点不是多维数据集。
  2. This inheritance is creating a number of lists: every vertex has its own list selectedSpheres since it inherits the list from Cube . 这种继承创建了许多列表:每个顶点都有自己的列表selectedSpheres因为它从Cube继承了列表。 I hope you realise that the way it is now, each vertex is inserting itself inside its own list, so each selectedSpheres would always have 0 or 1 elements. 我希望您认识到,现在的方式是,每个顶点都将自己插入其自己的列表中,因此每个selectedSpheres将始终具有0或1个元素。
  3. addToSelect (and probably other methods) shouldn't be public , since you don't want to call it from other classes. addToSelect (可能还有其他方法)不应是public ,因为您不想从其他类中调用它。 It can't be private as your comment says because then the inherited class couldn't use it; 正如您的评论所说,它不能是私有的 ,因为继承的类无法使用它。 it has to be protected , if you insist with the inheritance. 如果您坚持继承,则必须对其进行保护
  4. Printing selectedSpheres[0] is bad because in your case the list may be empty and that would generate the argument out of range exception you were getting. 打印selectedSpheres[0]是不好的,因为在您的情况下,列表可能为空,并且会生成您超出范围的参数。

I'd say all these problems are caused by the inheritance: cubes have vertices and not vertices are cubes . 我会说所有这些问题都是由继承引起的: 多维数据集具有顶点,而不是顶点是多维数据集 You should have a list of vertices in the cube, a boolean to tell if the vertex is selected and a method in the cube to go over the vertices list and return the ones that are selected (that would be the equivalent of Cube 's selectedSpheres ). 您应该在多维数据集中有一个顶点列表,一个布尔值(用来告诉您是否选择了顶点),以及一个多维数据集中的方法可以遍历顶点列表并返回所选的顶点(这与CubeselectedSpheres等效) )。

You could have an abstract class or an interface to represent the stuff that both classes has in common, like isSelected or maybe addToSelect so both classes would implement/inherit from it, but again, not make Vertex inherit from Cube . 您可以有一个抽象类或一个接口来表示两个类的共同点,例如isSelectedaddToSelect以便两个类都可以addToSelect实现/继承,但同样,不要让VertexCube继承。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM