简体   繁体   中英

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 .

I've created two class files - Cube.cs and Vertex.cs . Vertex inherits from Cube which inherits from MonoBehaviour . 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. The print statement inside the function prints off true every single time. 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:

错误

The addToSelected() function is called from the OnMouseDown() function inside the Vertex class. 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]); is executed inside of all objects that inherit from Cube everytime you press the space key. In some (or most) instances of Vertex selectedSpheres is empty, which is why you get an argument out of range error. Also, you have defined a selectedSpheres list for every instance of Cube (and therefore Vertex). So you have 9 instances of selectedSpheres in your sample scene. The shortest way to fix this would be to declare selectedSpheres as 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.
  2. This inheritance is creating a number of lists: every vertex has its own list selectedSpheres since it inherits the list from 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.
  3. addToSelect (and probably other methods) shouldn't be public , since you don't want to call it from other classes. 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.

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 ).

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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