尝试使用列表中的变量创建GameObject

时间:2018-04-04 00:30:15

标签: c# unity3d

我正在尝试通过输入TileID来创建GameObject。 对于我的地形生成,我最终希望能够做类似

的事情
Generate()
{
    Tile(<TileID>); 
}

现在它只会为我生成一个Stone图块,因为它是列表中两个项目中的第二个。我该怎么做才能让自己输入TileID来显示正确的图块。

TileObject类:

public class TileObject : MonoBehaviour {
//Instance Variables
TileManager tileManager;
GameObject gameManager;

//Variables

public int TileID;
Sprite TileSprite;
string TileName;
SpriteRenderer spriteRenderer;


// Use this for initialization
void Start () 
{
    gameManager = GameObject.Find("Manager");
    tileManager = gameManager.GetComponent<TileManager>();
    spriteRenderer = gameObject.GetComponent<SpriteRenderer>();

    foreach (Tile tile in tileManager.Tiles)
    {
        TileID = tile.tileID;
        TileSprite = tile.tileSprite;
        TileName = tile.tileName;
    }
}
public TileObject(int TileID) 
{

    gameObject.name = TileName;
    spriteRenderer.sprite = TileSprite;
}

// Update is called once per frame
void Update () 
{

}

瓷砖类:

public Tile(int newTileID, string newTileName, Sprite newTileSprite, float newBreakSpeed) 
{
    tileID = newTileID;
    tileName = newTileName;
    tileSprite = newTileSprite;
    breakSpeed = newBreakSpeed;
}

2 个答案:

答案 0 :(得分:2)

根据我在此处看到的内容,您似乎在尝试使用单个TileObject时应该使用每个图块一个

你在哪里调用TileObject的构造函数?如果它来自TileManager类,包括那将使回答这个问题变得容易得多。

在没有TileManager类的清晰视图的情况下我可以说,当调用Start()方法时,在继续执行foreach时,您将为每个先前设置的值写入

TileID = tile.tileID;
TileSprite = tile.tileSprite;
TileName = tile.tileName;

因此,当它读取TileManager中的切片列表时,先前读取的切片信息将被覆盖。例如......

迭代1

TileID = 0;
TileSprite = sprite1;
TileName = firstTile;

迭代2

TileID = 1;
TileSprite = sprite2;
TileName = secondTile;

迭代3

TileID = 2;
TileSprite = sprite3;
TileName = thirdTile;

在到达列表末尾(大小为n)之后,你将最终得到

迭代 N

TileID = **N-1**;
TileSprite = sprite**N**;
TileName = **Nth**Tile;

本质上,TileObject类将包含tileManager.Tiles中最后一个tile的值。然后,当您调用TileObject()时,它将使用列表中最后一个tile的值创建一个tile。

有了TileManager类的副本后,我可以帮助您更正确地指导您。希望这有帮助,如果您有任何问题,请不要犹豫。

答案 1 :(得分:2)

您的tileManager应该实例化新的图块。例如:

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

public class TileManager : MonoBehaviour {

    public GameObject tilePrefab;

    [Serializable]
    public class Tile {
        public int tileID;
        public string tileName;
        public Sprite tileSprite;
        public float breakSpeed;
    }

    // List should be populated in inspector
    public List<Tile> Tiles;

    public GameObject Generate(int id) {
        GameObject newObj = null;
        try {

            var data = Tiles.FirstOrDefault(tileData => id == tileData.tileID);
            newObj = Instantiate(tilePrefab);
            newObj.GetComponent<SpriteRenderer>().sprite = data.tileSprite;
            newObj.name = data.tileName; // same name to multiple tiles?
        } catch {
            Debug.LogWarning("TileManager not initialised properly!");
        }
        return newObj;
    }
}

tilePrefab是一个游戏对象,用作&#34;原型&#34;用于实例化。在这个例子中,它只是一个2d精灵。 tile image

在检查器中填充tileManager tile数据: tile manager image

然后你可以使用:

生成图块
    var manager = GetComponent<TileManager>();
    // generate 10 tiles with id [0..maxid]
    int tilecount = 10;
    int maxid = 1;
    for (int id = 0; id <= maxid; ++id) {
        for (int i = 0; i < tilecount; ++i) {
            var obj = manager.Generate(id);
            obj.transform.position = UnityEngine.Random.insideUnitCircle;
        }
    }