c# - 自动填充检查器数组
问题描述
我有一个二维数组(基于网格)并想通过检查器填充它。给你一个关于游戏的想法
所以我的地面脚本包含所有这些单元格。
public class Ground : MonoBehaviour
{
public Cell[,] cells;
private void Start()
{
Debug.Log(cells);
}
}
由于管理所有这些单元并将它们分配给我考虑自动化它的地面脚本将是很多工作。所以每当我添加一个游戏对象(作为一个孩子)并将单元组件分配给它时,地面应该自动将此单元添加到数组中。为了实现这一点,我考虑为检查员创建一个编辑器脚本。
[CustomEditor(typeof(Ground))]
public class GroundEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Ground ground = (Ground)target;
Dictionary<Vector2Int, Cell> cells = new Dictionary<Vector2Int, Cell>();
int maximumHorizontalLength = 0;
int maximumVerticalLength = 0;
foreach (Transform groundCell in ground.transform)
{
Cell cell = groundCell.GetComponent<Cell>();
if (cell != null)
{
Vector3 cellPosition = groundCell.position;
Vector2Int cellIndices = new Vector2Int(Mathf.RoundToInt(cellPosition.x), Mathf.RoundToInt(cellPosition.z));
cells.Add(cellIndices, cell);
if (cellIndices.x > maximumHorizontalLength)
{
maximumHorizontalLength = cellIndices.x;
}
if (cellIndices.y > maximumVerticalLength)
{
maximumVerticalLength = cellIndices.y;
}
}
}
maximumHorizontalLength++;
maximumVerticalLength++;
ground.cells = new Cell[maximumHorizontalLength, maximumVerticalLength];
for (int x = 0; x < maximumHorizontalLength; x++)
{
for (int y = 0; y < maximumVerticalLength; y++)
{
ground.cells[x, y] = cells[new Vector2Int(x, y)];
}
}
}
}
所以我想在开始游戏之前创建这个二维网格以节省资源。我不想在玩的时候按标签或类型搜索。而且我认为这种方法可以节省时间。
不幸的是,在开始游戏时,Debug.Log 打印为 null。我希望用这条线填充它ground.cells = new Cell[maximumHorizontalLength, maximumVerticalLength];
我错过了什么吗?这甚至可能吗?
解决方案
Unity 序列化程序不支持多维数组,因此您需要重新构建您希望如何在每个 Cell 上存储数据。一种选择是创建一个从 MonoBehaviour 派生的新自定义类来存储此数据并将其放置在场景中的某个位置:
[System.Serializable]
public class CellData : MonoBehaviour
{
[System.Serializable]
public class CellReference
{
public int xPos;
public int yPos;
public Cell cell;
public CellReference(Vector2Int posVal, Cell celVal)
{
xPos = posVal.x; yPos = posVal.y; cell = celVal;
}
}
public List<CellReference> cellReferences = new List<CellReference>();
}
然后可以通过检查器通过对 Ground 和 GroundEditor 类的以下更改来填充它:
public class Ground : MonoBehaviour
{
public CellData cells;
private void Start()
{
Debug.Log(cells);
}
}
[CustomEditor(typeof(Ground))]
public class GroundEditor : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (GUILayout.Button("Refresh Cell References"))
{
Ground ground = (Ground)target;
ground.cells.cellReferences = new List<CellData.CellReference>();
foreach (Transform groundCell in ground.transform)
{
Cell cell = groundCell.GetComponent<Cell>();
if (cell != null)
{
Vector3 cellPosition = groundCell.position;
Vector2Int cellIndices = new Vector2Int(Mathf.RoundToInt(cellPosition.x), Mathf.RoundToInt(cellPosition.z));
ground.cells.cellReferences.Add(new CellData.CellReference(cellIndices, cell));
}
}
}
}
}
将 CellsData 脚本连接到您放置的 Ground 脚本,每次在检查器中按下“刷新单元格引用”按钮时,这将生成一个新的单元格列表。
推荐阅读
- angular - 使用 setInterval 取消订阅 RxJS
- javascript - 将模式链接到输入字段并使用 JavaScript 进行验证
- asp.net - 找不到文件 '..\bin\roslyn\csc.exe'。发布到服务器后
- vba - VBA Excel 这个循环的一半有效
- node.js - express static 2个不同的文件夹
- php - 自定义帖子类型分类中未显示帖子
- javascript - AJAX onreadystatechange 函数并不总是被调用
- python - 如何计算列表中的数字
- angular - 无法从 Angular 中的 Web api 获得响应
- user-permissions - 如何设置权限以编辑自己的用户数据而不是其他人的数据?