Unity C#可移动网格系统Move函数实现异常求助
体素游戏可移动网格系统Move函数实现问题
正在为体素游戏开发可移动网格系统,大部分功能已完成,但Move函数的实现一直受阻。以下是未实现Move函数逻辑的核心代码:
using UnityEngine; using System; public class Grid<T> { private T[] data; public Vector3Int position; public Vector3Int size; public int iSize; public Grid(Vector3Int size) { this.position = new Vector3Int(0, 0, 0); this.size = size; this.iSize = size.x * size.y * size.z; this.data = new T[size.x * size.y * size.z]; } public T this[int x, int y, int z] { get { Vector3Int position = new Vector3Int(x, y, z); if (!IsValidIndex(position - this.position)) { throw new IndexOutOfRangeException("Invalid position"); } Vector3Int positionRelative = PositionToRelative(position); return this.data[VectorToIndex(positionRelative)]; } set { Vector3Int position = new Vector3Int(x, y, z); if (!IsValidIndex(position - this.position)) { throw new IndexOutOfRangeException("Invalid position"); } Vector3Int positionRelative = PositionToRelative(position); this.data[VectorToIndex(positionRelative)] = value; } } public void Move(Vector3Int newPosition) { Vector3Int offset = PositionToRelative(newPosition); T[] newData = new T[data.Length]; this.data = newData; this.position = newPosition; } private bool IsPositionInRange(Vector3Int position, Vector3Int start, Vector3Int end) { int minX = Mathf.Min(start.x, end.x); int maxX = Mathf.Max(start.x, end.x); int minY = Mathf.Min(start.y, end.y); int maxY = Mathf.Max(start.y, end.y); int minZ = Mathf.Min(start.z, end.z); int maxZ = Mathf.Max(start.z, end.z); return position.x >= minX && position.x <= maxX && position.y >= minY && position.y <= maxY && position.z >= minZ && position.z <= maxZ; } private Vector3Int PositionToRelative(Vector3Int position) { return position - this.position; } private bool IsValidIndex(Vector3Int position) { int index = VectorToIndex(position); return index >= 0 && index < this.iSize; } private bool IsValidIndex(int index) { return index >= 0 && index < this.iSize; } private int VectorToIndex(Vector3Int position) { return position.x + this.size.x * (position.y + this.size.y * position.z); } }
测试代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Tester : MonoBehaviour { void PrintMatrix<T>(Grid<T> grid) { for (int x = 0; x < grid.size.x; x++) { string output = "\n"; for (int y = 0; y < grid.size.y; y++) { Vector3Int position = new Vector3Int(x, y, 0) + grid.position; output += grid[position.x, position.y, position.z]; if (y < grid.size.y - 1) { output += " "; } } Debug.Log(output); } } void Start() { Vector3Int size = new Vector3Int(4, 4, 1); Grid<int> grid = new Grid<int>(size); for (int x = 0; x < size.x; x++) { for (int y = 0; y < size.y; y++) { grid[x, y, 0] = x + size.y * y + 1; } } PrintMatrix<int>(grid); Debug.Log("-------- Amogus ------------"); grid.Move(new Vector3Int(-1, 0, 0)); PrintMatrix<int>(grid); } void Update() { } }
示例中尝试将网格左移,首次输出的网格数据正确:
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
但执行Move函数后输出结果不符合预期:
预期输出:
0 1 5 9
0 2 6 10
0 3 7 11
0 4 8 12
实际输出:
2 6 10 14
3 7 11 15
4 8 12 16
0 9 13 0
曾尝试过以下Move函数实现,但仍无法正确计算startPosition和endPosition,导致功能异常:
public void Move(Vector3Int position) { T[] newData = new T[data.Length]; Vector3Int positionRelative = PositionToRelative(position); Vector3Int startPosition = new Vector3Int( positionRelative.x >= 0 ? positionRelative.x : this.size.x + positionRelative.x, positionRelative.y >= 0 ? positionRelative.y : this.size.y + positionRelative.y, positionRelative.z >= 0 ? positionRelative.z : this.size.z + positionRelative.z ); Vector3Int endPosition = new Vector3Int( positionRelative.x < 0 ? this.size.x : positionRelative.x, positionRelative.y < 0 ? this.size.y : positionRelative.y, positionRelative.z < 0 ? this.size.z : positionRelative.z ); Debug.Log(positionRelative + " " + startPosition + " " + endPosition); for (int x = 0; x < size.x; x++) { for (int y = 0; y < size.y; y++) { for (int z = 0; z < size.z; z++) { Vector3Int currentPosition = new Vector3Int(x, y, z); int index = VectorToIndex(currentPosition); int translationIndex = VectorToIndex(currentPosition - positionRelative); if ( IsPositionInRange(currentPosition, startPosition, endPosition) || !IsValidIndex(translationIndex) ) { newData[index] = default(T); continue; } newData[index] = data[translationIndex]; } } } this.position = position; data = newData; }
预期效果说明:位置为(0,0,0)的网格展示了其2x2区域的样子,位置为(-1,0,0)的网格则展示了移位后2x2区域的预期效果,新露出的区域用0表示未知值。
内容的提问来源于stack exchange,提问作者Bloxxy 213
相关产品推荐
相关产品推荐

