2015-11-01 4 views
0

В единстве я делаю программу, которая позволяет щелкнуть на кубе и выберите сферы, которые представляют собой вершину, как показано ниже:Как изменить Список <> между двумя классами в единстве?

Cube with vertices

После того, как тезисы сфера выбраны они должны быть добавлены к лист selectedSpheres типа GameObject.

Я создал два файла классов - Cube.cs и Vertex.cs. Vertex наследует от Cube, который наследует от MonoBehaviour. В Cube у меня есть список участников, в котором хранятся выбранные сферы.

Я определил функцию addToSelected(), которая добавляет ввод в список selectedSpheres. Оператор печати внутри функции выводит значение true каждый раз. Но оператор печати в функции Update() печатает аргумент из ошибки диапазона, как показано ниже, в то время как addToSelected() показал, что он работал в 8 раз:

Error

addToSelected() функция вызывается из OnMouseDown() функции внутри Vertex класс. Код для обоих классов приведен ниже:

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); 
     } 
    } 
} 

ответ

1

Поскольку вершинных наследует форму куба и куб имеет функцию Update

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

инструкция print(selectedSpheres[0]); выполняется внутри всех объектов, которые наследуют от Cube каждый раз, когда вы нажимаете клавишу пробела. В некоторых (или большинстве) экземплярах Vertex selectedSpheres пуст, поэтому вы получаете аргумент вне диапазона. Кроме того, вы определили список selectedSpheres для каждого экземпляра Cube (и, следовательно, Vertex). Таким образом, у вас есть 9 экземпляров selectedSpheres в вашей сцене. Самый короткий способ исправить это - объявить selectedSpheres статическим. Тогда у вас будет только один список для всех экземпляров Cube/Vertex.

Так идти вперед и попробовать:

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

Это работает, спасибо. Однако мне любопытно, почему сделать его частным не работает? Если он был закрыт, то Vertex не должен наследовать 'selectedSpheres' из Cube, поэтому я думаю, что он будет работать. – ryanmattscott

+0

Подождите, если я сделал 'selectedSpheres' приватным и сделал переопределение в функции' Update', то он _should_ work – ryanmattscott

1

Есть несколько проблем с кодом:

  1. Vertex не наследуемые от Cube так как вершина не является куб.
  2. Это наследование создает несколько списков: каждая вершина имеет свой собственный список selectedSpheres, так как он наследует список от Cube. Надеюсь, вы поймете, что так, как сейчас, каждая вершина вставляет себя в свой собственный список, поэтому каждый selectedSpheres всегда будет иметь 0 или 1 элемент.
  3. addToSelect (и, возможно, другие методы) не должно быть public, так как вы не хотите называть его из других классов. Он не может быть приватным, так как ваш комментарий говорит, потому что тогда унаследованный класс не мог его использовать; он должен быть защищен, если вы настаиваете на наследовании.
  4. Печать selectedSpheres[0] плохо, потому что в вашем случае список может быть пустым, и это приведет к возникновению аргумента за пределами исключения, которое вы получали.

Я бы сказал, что все эти проблемы вызваны наследования: кубики имеют вершины и не вершины являются кубы. У вас должен быть список вершин в кубе, логический, чтобы определить, выбрана ли вершина, а метод в кубе - переместить список вершин и вернуть те, которые были выбраны (это было бы эквивалентно CubeselectedSpheres).

Вы могли бы иметь абстрактный класс или интерфейс для представления материала, что оба класса имеет в общем, как isSelected или, может быть addToSelect так как оба класса будут реализовывать/наследовать от него, но опять же, не делают Vertex наследовать от Cube.

+0

Я полностью согласен с точкой 1. Я честно сделал это, потому что я новичок в ООП, и я понял это будет работать, но это определенно не чистое решение. Я слышал об абстрактных классах и интерфейсах смутно раньше, но я не знаю, как их использовать и до сих пор, когда их использовать. Не могли бы вы указать мне в правильном направлении, как определить интерфейс, а затем реализовать его или «наследовать» (не уверен, что это правильный термин) из абстрактного класса? – ryanmattscott

+1

Я думаю, вы должны искать учебник по ООП, простой способ дать вам понимание на высоком уровне этих вещей, и время, которое вы потратили бы, будет окупиться, потому что вы сможете быстрее кода и иметь гораздо меньше проблем , Я думаю, что полиморфизм и модификаторы доступа - одна из первых вещей, которые нужно изучить. Тогда вы сможете сделать это сами, очень легко. – Roberto

Смежные вопросы