如何在 Unity 中以最佳方式实例化 UI 图像的静态网格?
How do I instantiate a static grid of UI images in Unity optimally?
设置如下:
- 包含带有子图像的游戏对象的预制件(CellPrefab)。实例化 Cell 时,它会获得随机颜色。
- 单元格的 X 乘 Y 网格。
这是预制件:
其中 base 是带有图像的游戏对象:
像素是一个 1x1 的白点。
以及单元格的代码:
using UnityEngine;
using UnityEngine.UI;
public class Cell : MonoBehaviour
{
private void Start()
{
GetComponent<Image>().color = Random.ColorHSV(0f, 1f, 0f, 1f, 0f, 1f);
}
}
网格代码:
public class Grid
{
public Grid(int width, int height, float cellSize, Cell CellPrefab, Canvas canvas)
{
this.cellSize = cellSize;
oneCell = CellPrefab;
gridArray = new int[width,height];
cellContentArray = new Cell[width,height];
for (var x = 0; x < Width; x++)
{
for (var y = 0; y < Height; y++)
{
CreateCell(x, y, GetWorldPosition(x,y) + new Vector2(cellSize,cellSize)*0.5f, canvas);
}
}
}
private void CreateCell(int x, int y, Vector2 position, Canvas canvas)
{
var cell = Object.Instantiate(oneCell, position, Quaternion.identity, canvas.transform);
cell.transform.localPosition = position;
cell.name = $"[{x},{y}]";
cellContentArray[x, y] = cell;
}
private Vector2 GetWorldPosition(int x, int y)
{
return new Vector2(x * cellSize - (Width*cellSize/2f),y * cellSize - (Height*cellSize/2f));
}
}
请注意,网格包含的对象永远不会移动、调整大小或以其他方式转换,因此是静态的。
挑战 是网格的大小无法控制。在我的用例中,我不能低于 100 x 100 网格。这意味着使用我当前的方法我正在实例化 10.000 个 gameObjects 只是为了显示网格,此时我正在渲染 40.000 个 tris。尝试 select 网格中的任何单元格时,Unity 编辑器长时间无响应。
正如您在屏幕截图中看到的,每个单元格只是一个带有颜色(随机)的正方形图像。
我会欣赏一些在 Unity 中处理大量游戏对象的指示或方法,或者如果有其他方法我可以解决这个问题。也许是一种 "squash" 将所有图像合并为一个大但仍保留有关不同单元格位置和对象信息的方法。
谢谢!
我认为通过 UI 渲染这个是错误的抽象。
你需要这样想:
- 如何存储单元格的信息?
- 如何向用户显示单元格?
这是两个截然不同的问题,你把它们混为一谈了。
1) 如何存储单元格信息?
在一个简单的二维数组中。
您有一个 Cell
class。
每个单元格应该有一个显示颜色作为单元格class属性的public。
那么,您的单元格网格只是一个 Cell[,]
对象。
2) 我怎样才能向用户展示这个?
创建与二维元胞数组尺寸相同的黑色图像
循环遍历您的二维元胞数组。
对于每个 x,y 单元格,您将图像的 x,y 像素颜色更改为单元格的颜色。
完成。现在你有 1 个游戏对象,一个与你的二维数组尺寸相同的图像。
设置如下:
- 包含带有子图像的游戏对象的预制件(CellPrefab)。实例化 Cell 时,它会获得随机颜色。
- 单元格的 X 乘 Y 网格。
这是预制件:
其中 base 是带有图像的游戏对象:
像素是一个 1x1 的白点。
以及单元格的代码:
using UnityEngine;
using UnityEngine.UI;
public class Cell : MonoBehaviour
{
private void Start()
{
GetComponent<Image>().color = Random.ColorHSV(0f, 1f, 0f, 1f, 0f, 1f);
}
}
网格代码:
public class Grid
{
public Grid(int width, int height, float cellSize, Cell CellPrefab, Canvas canvas)
{
this.cellSize = cellSize;
oneCell = CellPrefab;
gridArray = new int[width,height];
cellContentArray = new Cell[width,height];
for (var x = 0; x < Width; x++)
{
for (var y = 0; y < Height; y++)
{
CreateCell(x, y, GetWorldPosition(x,y) + new Vector2(cellSize,cellSize)*0.5f, canvas);
}
}
}
private void CreateCell(int x, int y, Vector2 position, Canvas canvas)
{
var cell = Object.Instantiate(oneCell, position, Quaternion.identity, canvas.transform);
cell.transform.localPosition = position;
cell.name = $"[{x},{y}]";
cellContentArray[x, y] = cell;
}
private Vector2 GetWorldPosition(int x, int y)
{
return new Vector2(x * cellSize - (Width*cellSize/2f),y * cellSize - (Height*cellSize/2f));
}
}
请注意,网格包含的对象永远不会移动、调整大小或以其他方式转换,因此是静态的。
挑战 是网格的大小无法控制。在我的用例中,我不能低于 100 x 100 网格。这意味着使用我当前的方法我正在实例化 10.000 个 gameObjects 只是为了显示网格,此时我正在渲染 40.000 个 tris。尝试 select 网格中的任何单元格时,Unity 编辑器长时间无响应。
正如您在屏幕截图中看到的,每个单元格只是一个带有颜色(随机)的正方形图像。
我会欣赏一些在 Unity 中处理大量游戏对象的指示或方法,或者如果有其他方法我可以解决这个问题。也许是一种 "squash" 将所有图像合并为一个大但仍保留有关不同单元格位置和对象信息的方法。
谢谢!
我认为通过 UI 渲染这个是错误的抽象。
你需要这样想:
- 如何存储单元格的信息?
- 如何向用户显示单元格?
这是两个截然不同的问题,你把它们混为一谈了。
1) 如何存储单元格信息?
在一个简单的二维数组中。
您有一个 Cell
class。
每个单元格应该有一个显示颜色作为单元格class属性的public。
那么,您的单元格网格只是一个 Cell[,]
对象。
2) 我怎样才能向用户展示这个?
创建与二维元胞数组尺寸相同的黑色图像 循环遍历您的二维元胞数组。
对于每个 x,y 单元格,您将图像的 x,y 像素颜色更改为单元格的颜色。
完成。现在你有 1 个游戏对象,一个与你的二维数组尺寸相同的图像。