Unity 关卡编辑器(自动捕捉功能)
使用动机
当编辑场景时,有大量的物体需要按照一定的排列顺序进行仔细的摆放时,unity提供的自动捕捉功能往往不能很好的实现项目的需求,我们需要根据自己的项目去拓展出相应的功能捕捉系统。
Level脚本
public partial class Level : MonoBehaviour
{
public int cols;
public int rows;
public float gridSize;
private static Level _instance;
public static Level Instance
{
get
{
if (_instance == null)
{
_instance = FindObjectOfType<Level>();
}
return _instance;
}
}
private void Awake()
{
_instance = this;
}
private void DrawLine()
{
Gizmos.DrawLine(Vector3.zero, new Vector3(cols * gridSize, 0f, 0f));
Gizmos.DrawLine(Vector3.zero, new Vector3(0f, rows * gridSize, 0f));
Gizmos.DrawLine(new Vector3(cols * gridSize, 0f, 0f), new Vector3(cols * gridSize, rows * gridSize, 0f));
Gizmos.DrawLine(new Vector3(0f, rows * gridSize, 0f), new Vector3(cols * gridSize, rows * gridSize, 0f));
}
private void DrawItem()
{
for (var i = 1; i < cols; i++)
Gizmos.DrawLine(new Vector3(gridSize * i, 0f, 0f), new Vector3(gridSize * i, rows * gridSize, 0f));
for (var i = 1; i < rows; i++)
Gizmos.DrawLine(new Vector3(0f, i * gridSize, 0f), new Vector3(cols * gridSize, i * gridSize, 0f));
}
private void OnDrawGizmos()
{
var oldMatrix = Gizmos.matrix;
Gizmos.matrix = transform.localToWorldMatrix;
DrawLine();
DrawItem();
Gizmos.matrix = oldMatrix;
}
private void OnDrawGizmosSelected()
{
var oldColor = Gizmos.color;
Gizmos.color = Color.yellow;
var oldMatrix = Gizmos.matrix;
Gizmos.matrix = transform.localToWorldMatrix;
DrawLine();
Gizmos.color = oldColor;
Gizmos.matrix = oldMatrix;
}
public Vector2 World2Grid(Vector3 point)
{
var position = transform.position;
var colsIndex = (int) ((point.x - position.x) / gridSize);
var rowsIndex = (int) ((point.y - position.y) / gridSize);
return new Vector2(colsIndex, rowsIndex);
}
public Vector3 Grid2World(int col, int row)
{
var position = transform.position;
var x = position.x + (col * gridSize + gridSize / 2);
var y = position.y + (row * gridSize + gridSize / 2);
return new Vector3(x, y, 0f);
}
public bool IsInGrid(Vector3 point)
{
var position = transform.position;
var minX = position.x;
var maxX = position.x + gridSize * cols;
var minY = position.y;
var maxY = position.y + gridSize * rows;
return point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY;
}
public bool IsInGrid(int col, int row)
{
return col >= 0 && col < cols && row >= 0 && row < rows;
}
测试的网格片脚本
[ExecuteAlways]//在编辑器模式,Prefab模式下可以运行生命周期,Update在修改了才会调用
public class Test : MonoBehaviour
{
private void Update()
{
var pos = Level.Instance.World2Grid(transform.position);
transform.position = Level.Instance.Grid2World((int) pos.x, (int) pos.y);
}
private void OnDrawGizmos()
{
var oldColor = Gizmos.color;
var position = transform.position;
Gizmos.color = Level.Instance.IsInGrid(position) ? Color.green : Color.red;
Gizmos.DrawCube(position,Level.Instance.gridSize * Vector3.one);
Gizmos.color = oldColor;
}
}