2016-06-11 31 views
0

我想在統一中製作瓦片網格地圖,其中每個瓦片都是包含某些信息的類。所有瓦片信息都保存在一個名爲TileData的腳本中。我有四種瓷磚類型,每種都有4個變量。 (平鋪圖形,平鋪名稱,平鋪位置X和平鋪位置Z.)用於構建地圖的所有信息均包含在第二個腳本中。 (我正在調用地圖腳本中的tiledata腳本的本地版本。)Unity C# - Array中的類是Overriden而不是創建副本(多個腳本)

我可以使用隨機選擇一個瓦片類形成瓦片類數組的多維數組,從而成功地使用瓦片構建網格。 我的問題是,當我嘗試爲瓦片位置分配位置x和位置z時,它會覆蓋瓦片數組中的信息。最終結果是每個圖塊顯示所有其他像瓦片的x,z,而不是單獨顯示。

我想要做的是構建一個隨機Class Tile的二維數組,但爲每個新tile分配他們自己的x和z座標。 (我打算稍後用於移動/尋路等)

我嘗試了所有我能想到的方法,甚至試圖使用多維鋸齒陣列,但無法使其工作。

代碼(刪除無關位)以下:

TileData腳本

using UnityEngine; 
using System.Collections; 
using System.Collections.Generic; 

public class TileData { 

[System.Serializable] 
public class Tile                 //Public class Tile to act as Tile Template. 
{ 
    public int tileGraphic = 0;              //An int to point to our Tile Graphic 
    public string tileName = "Unknown";            //Name of the Tile. 

    public int tilePositionX = 0; 
    public int tilePositionZ = 0; 
} 

public Tile[] tileTypes = new Tile[4];            //Makes a new Tile Array from the Tile Class 

public void makeArray()                //Constructs the array. 
{ 
    tileTypes[0] = new Tile { tileGraphic = 0, tileName = "Grassland"};   //Makes the new Tile and puts them in the array. 
    tileTypes[1] = new Tile { tileGraphic = 1, tileName = "Water"}; 
    tileTypes[2] = new Tile { tileGraphic = 2, tileName = "Forest"}; 
    tileTypes[3] = new Tile { tileGraphic = 3, tileName = "Mountain"}; 
} 

地圖腳本

using UnityEngine; 
    using System.Collections; 
    using System.Collections.Generic; 
    using System.Linq; 

    [ExecuteInEditMode] 
    [RequireComponent(typeof(MeshFilter))]               //Ensures the object has a filter, Renderer and Collider when created. 
    [RequireComponent(typeof(MeshRenderer))] 
    [RequireComponent(typeof(MeshCollider))] 

    public class missionMap : MonoBehaviour 
    { 

    //Map Variables 

    public int sizeX = 25;                  //The left/right size of the map (in tiles). Public so it can be changed from the editor. 
    public int sizeZ = 25;                  //The forward/backward size of the map (in tiles). 

    public float tileSize = 1.0f;                //The size of each tile. (How many vertices wide the tile is.) 

    //Tile Variables 

    public TileData localTileData = new TileData();            //Pulls the tile types in from their own script. 
    public TileData.Tile[,] localTileArray = new TileData.Tile[25, 25];       //Builds an Array of our Tile class the size of our map, so each tile on the map has a Tile Class corresponding to it.  

    void Start() 
    { 
     localTileData.makeArray();                //Calls the makeArray from the Tile Data script, so we can access the array later. 

     //localTileArray[0, 0] = localTileArray[sizeX,sizeZ]; 

     BuildMap();                    //Builds the map when the code starts. 
     //BuildPathGraph(); 
    } 
    } 

我省略的實際建築地圖並跳到瓷磚。

public void BuildTiles() 
{ 
    for (int z = 0; z < sizeZ; z++)              //A double for loop to populate our tile position array with the size of the our map in x and z. 
    { 
     for (int x = 0; x < sizeX; x++) 
     { 

      localTileArray[x, z] = localTileData.tileTypes[Random.Range(0, 4)];   //Fills the Array with Tile Copies of type 0 - 3 (0 = grass, 2 = water, 3 = forest, 4 = mountain.) 

     } 
    } 

回答

0

問題可能出在您省略的部分:建立地圖。 你在做這樣的事嗎?

for (int z = 0; z < sizeZ; z++) 
{ 
    for (int x = 0; x < sizeX; x++) 
     { 

     localTileArray[x, z] = localTileData; 
    } 
} 

如果是這樣的話,你在做什麼是分配參考到localTileData在localTileArray所有元素。所以這就是修改一個引用會影響數組中所有元素的原因:它們都是一樣的。這是因爲在C#中,類Reference Types

的解決方案是一個@ graju256談到:使用.MemberwiseClone()創建localTileArray參考的副本

另一種解決方案是將Tile從類更改爲Struct並將其轉換爲Value Type,因此,當您將localTileData分配給數組中的元素時,會創建副本。

+0

.MemberwiseClone()有錯誤,因此我查看了Structs。我猶豫不決,因爲我以前從未使用過它們。但是,迄今爲止它完美的工作。我將不得不花費更多時間閱讀文檔以瞭解結構和類之間的差異,因爲它們看起來與我大體上可以互換。 謝謝。 – Magnus22191

+0

查看關於我在答案中提供的價值/參考類型的鏈接,您將在完成學習類和結構之間差異的過程中完成一半的工作;) –

0

克隆選定區塊實例,同時建立localTileArray。因此,您可以避免修改/引用程序中的同一個實例。

您可能會重新考慮您的TILE設計。聲明您的TILE類型的枚舉並在創建時傳遞它。在構建內部數組時創建具有類型的新TILE。所以,你可以避免保持TILE類型的實例。

+0

我不確定你的意思,你能舉一個代碼示例嗎?如果我製作一個新的TILE,它不會是四種類型之一,它只是一個基本的TILE。 – Magnus22191

+0

使用MemberwiseClone方法克隆您的TILE對象。因爲TILE類是由值類型組成的,所以可以通過淺層模型來克隆對象,這是正確的,複製。否則,我們應該通過實現ICloneable接口來考慮深層複製。 – graju256

相關問題