2015-11-01 127 views
0

在團結我正在做一個程序,讓你點擊一個立方體,並選擇代表頂點領域,如下圖所示:如何修改統一的兩個類之間的List <>?

Cube with vertices

球被選中,他們將被添加到一旦論文列表selectedSpheres類型GameObject

我創建了兩個類文件 - Cube.csVertex.csVertex繼承Cube,它繼承自MonoBehaviour。在多維數據集中,我有一個存儲選定球體的成員列表。

我已經定義了一個函數addToSelected(),它將輸入添加到selectedSpheres列表中。函數內部的print語句每次都打印出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

由於頂點繼承形式立方和Cube具有更新功能

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

語句print(selectedSpheres[0]);在每次按空格鍵時從所有從Cube繼承的對象內執行。在Vertex selectedSpheres的一些(或大多數)實例中爲空,這就是爲什麼您會得到超出範圍錯誤的參數。此外,您已爲每個Cube實例(因此Vertex)定義了一個selectedSpheres列表。因此,在示例場景中有9個selectedSpheres實例。解決這個問題的最簡單方法是聲明selectedSpheres爲靜態。然後,您將只有一個Cube/Vertex實例的列表。

因此,繼續前進,並嘗試:

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

工作,謝謝。不過,我很好奇爲什麼使它私人不起作用?如果它是私人的,Vertex不應該繼承Cube中的'selectedSpheres',所以我認爲它會起作用。 – ryanmattscott

+0

等一下,沒關係,如果我將'selectedSpheres'私人化並對'Update'函數做了一個覆蓋,那麼它應該工作 – ryanmattscott

1

有幾個問題與您的代碼:

  1. Vertex不應Cube繼承自一個頂點是不是一個立方體。
  2. 此繼承正在創建多個列表:每個頂點都有自己的列表selectedSpheres,因爲它繼承了Cube的列表。我希望你意識到現在的方式,每個頂點都將自己插入自己的列表中,因此每個selectedSpheres總是會有0或1個元素。
  3. addToSelect(可能其他方法)不應該是public,因爲你不想從其他類中調用它。它不能是私人作爲你的評論說,因爲那麼繼承的類不能使用它;它必須是保護,如果你堅持繼承。
  4. 打印selectedSpheres[0]是不好的,因爲在你的情況下,列表可能是空的,這會產生超出範圍的異常參數。

我說這些問題是由遺傳引起的:立方體頂點而不是頂點立方體。您應該有一個立方體中的頂點列表,一個布爾值,用於指示頂點是否被選中,以及立方體中的方法是否會遍歷頂點列表並返回選定的頂點(這相當於CubeselectedSpheres )。

你可以有一個抽象類或接口來表示兩個類都具有共同的東西,比如isSelected也許addToSelect所以這兩個類將實現/繼承它,但同樣,不能從Cube使Vertex繼承。

+0

我完全同意第一點。我誠實地這樣做,因爲我是OOP的新手,它會工作,但它絕對不是一個乾淨的解決方案。我之前隱約地聽說過抽象類和接口,但我不知道如何使用它們,直到現在才使用它們。你能指出我如何定義一個接口然後實現它,或者從一個抽象類中「繼承」(不確定這是否合適)? – ryanmattscott

+1

我認爲你應該尋找一個面向對象的教程,一個簡單的教程會讓你對這些事情有一個高層次的理解,並且你花費的時間將會得到回報,因爲你可以更快地編寫代碼並且有更少的問題。多元化和訪問修飾符是我想要學習的第一件事情之一。那麼你可以很容易地自己做到這一點。 – Roberto

相關問題