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:
Vertex
shouldn't inherit from Cube
since a vertex is not a cube. 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. 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. 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.