我有两个脚本。脚本A包含一个Class的数组。该类包含两个变量,一个int和一个字符串。脚本B包含我正在执行的大部分代码,需要从脚本A中的类数组访问变量。
(基本上我正在尝试使用网格制作程序生成的平铺贴图。在第一遍中我制作网格。在第二个网格上我想使用贴图类制作贴图,可以使旧值相关到了瓷砖,[它的名字,图形,属性等]我理论上会做第三次传递来制作纹理,因此需要访问每个瓷砖中包含的图形信息。)
我的问题是,无论我尝试做什么,我似乎无法让脚本B识别脚本A中的数组作为初始化。相反,我得到错误"对象引用未设置为对象的实例"在我尝试访问变量的行上。
我试图以我能想到的每一种方式做到这一点,即使使用列表但无法实现这一点。我无疑是C#和Unity的新手。我想知道为什么我在做什么是错的,以及如何解决它以更好地理解这个过程。
任何可以提供的帮助将不胜感激。我的代码的相关部分如下:
脚本A
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TileData {
[System.Serializable]
public class Tile
{
public int tileGraphic = 0;
public string tileName = "Unknown";
}
public Tile[] tileArray = new Tile[3];
public void makeArray()
{
tileArray[0] = new Tile { tileGraphic = 0, tileName = "Grassland" };
tileArray[1] = new Tile { tileGraphic = 1, tileName = "Water" };
tileArray[2] = new Tile { tileGraphic = 2, tileName = "Forest" };
tileArray[3] = new Tile { tileGraphic = 3, tileName = "Mountain" };
}
脚本B
public void BuildMap()
{
//There's other stuff above here that works, I have omitted it for brevity.
BuildTiles();
}
public TileData tileTypes;
void BuildTiles()
{
Debug.Log("Test Tile Graphic = " + tileTypes.tileArray[0]);
//Debug.Log("Test Tile Graphic = " + tileTypes.tileArray[0].tileGraphic);
}
**正如所承诺的那样,下面全部都是下面的。我省略了评论,并评论了保持可读性的尝试。谢谢大家的帮助。
SCRIPT A
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshCollider))]
public class missionMap : MonoBehaviour {
public int sizeX = 25;
public int sizeZ = 25;
public float tileSize = 1.0f;
public Texture2D testTile;
public int tileResolution;
void Start ()
{
BuildMap();
//public TileData tileTypes = new TileData();
}
//Build the Map
public void BuildMap()
{
int numTiles = sizeX * sizeZ;
int numTris = numTiles * 2;
int vertSizeX = sizeX + 1;
int vertSizeZ = sizeZ + 1;
int numVerts = vertSizeX * vertSizeZ;
Vector3[] vertices = new Vector3[numVerts];
Vector3[] normals = new Vector3[numVerts];
Vector2[] uv = new Vector2[numVerts];
int[] triangles = new int[numTris * 3];
int x, z; //Loop counters.
for (z = 0; z < vertSizeZ; z++)
{
for (x = 0; x < vertSizeX; x++)
{
vertices[z * vertSizeX + x] = new Vector3(x * tileSize, 0, z * tileSize); //Fills the vertices array with new vector 3's.
normals[z * vertSizeX + x] = Vector3.up;
uv[z * vertSizeX + x] = new Vector2((float)x / sizeX, (float)z / sizeZ);
}
}
for (z = 0; z < sizeZ; z++)
{
for (x = 0; x < sizeX; x++)
{
int squareIndex = z * sizeX + x;
int triOffset = squareIndex * 6; //We can offset it by 6 (number of verts in a tile [2 traingles * 3 points each])
triangles[triOffset + 0] = z * vertSizeX + x + 0; [NW corner of the square]
triangles[triOffset + 1] = z * vertSizeX + x + vertSizeX + 0;
triangles[triOffset + 2] = z * vertSizeX + x + vertSizeX + 1;
triangles[triOffset + 3] = z * vertSizeX + x + 0;
triangles[triOffset + 4] = z * vertSizeX + x + vertSizeX + 1;
triangles[triOffset + 5] = z * vertSizeX + x + 1;
}
}
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.normals = normals;
mesh.uv = uv;
MeshFilter meshFilter = GetComponent<MeshFilter>();
MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
MeshCollider meshCollider = GetComponent<MeshCollider>();
meshFilter.mesh = mesh;
meshCollider.sharedMesh = mesh;
BuildTiles();
}
//Build the Tiles
public TileData tileTypes = new TileData();
void BuildTiles()
{
Debug.Log("Test Tile Graphic = " + tileTypes.tileArray[0].tileGraphic);
int[,] tilePosition;
tilePosition = new int[sizeX, sizeZ];
for (int z = 0; z < sizeZ; z++)
{
for (int x = 0; x < sizeX; x++)
{
tilePosition[x, z] = 0;
//Debug.Log("Tile Position: " + x + "," + z);
SCRIPT B
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class TileData {
[System.Serializable]
public class Tile
{
public int tileGraphic = 0;
public string tileName = "Unknown";
}
public Tile[] tileArray = new Tile[4];
public void makeArray()
{
//for (int i = 0; 1 < tileArray.Length; i++)
//tileArray = new Tile[3];
tileArray[0] = new Tile { tileGraphic = 0, tileName = "Grassland" };
tileArray[1] = new Tile { tileGraphic = 1, tileName = "Water" };
tileArray[2] = new Tile { tileGraphic = 2, tileName = "Forest" };
tileArray[3] = new Tile { tileGraphic = 3, tileName = "Mountain" };
}
答案 0 :(得分:0)
我可以在您的代码中发现问题。
访问超出范围的索引。
您有public Tile[] tileArray = new Tile[3];
您的索引是0到2.(0,1,2)
但这就是你的makeArray
函数的样子:
public void makeArray()
{
tileArray[0] = new Tile { tileGraphic = 0, tileName = "Grassland" };
tileArray[1] = new Tile { tileGraphic = 1, tileName = "Water" };
tileArray[2] = new Tile { tileGraphic = 2, tileName = "Forest" };
---**tileArray[3] = new Tile { tileGraphic = 3, tileName = "Mountain" };**---
}
您访问了tileArray[3]
?哪个是出界的。最高为2.这可以通过删除该行代码或使您的Tile数组大小为4来解决。public Tile[] tileArray = new Tile[4];
现在您可以使用tileArray[3]
。
编辑:
使用更新的代码,您的代码仍然包含另一个代码。您正在调用Debug.Log("Test Tile Graphic = " + tileTypes.tileArray[0].tileGraphic);
而未在Tile
中创建每个TileData
的新实例。你有一个函数makeArray()
可以做到这一点,但永远不会调用该函数。
解决此问题的方法是在致电makeArray()
之前从script A
致电BuildMap()
。
void Start()
{
tileTypes.makeArray();
BuildMap();
//public TileData tileTypes = new TileData();
}
OR
您可以通过BuildMap();
功能调用它。
void BuildTiles()
{
tileTypes.makeArray();
Debug.Log("Test Tile Graphic = " + tileTypes.tileArray[0].tileGraphic);
}
在访问tileTypes.tileArray[0].tileGraphic.
之前,您必须调用一次我建议您使用从Start()
函数调用它的第一个解决方案,这样您每次都不会分配内存调用BuildTiles()
函数。