【发布时间】:2017-03-18 23:07:30
【问题描述】:
我正在开发一个在我的视频游戏中使用的通用网格框架,其中网格由接口IGrid <T> 定义,T 被限制为GridCell。网格必须实现一个 Generate 方法来实例化单元格,然后 GridPositioniningRule 负责每个单元格在网格中的定位方式。这是我遇到麻烦的地方,我正在处理RectGrid2D,我有一个规则BasicPositionRule,它只能与RectGrid2D一起使用,因为它需要知道网格列+行但我可以不知道如何将我的规则很好地限制为RectGrid。
到目前为止,这是我的代码库:
using System.Collections.Generic;
using System;
using System.Linq;
using UnityEngine;
public interface IGrid<T> where T : GridCell
{
Dictionary<GridCoordinate, T> grid { get; set; }
/// <summary>
/// populates the grid with cell type t + a shiny callback to handle each cell after instantiation
/// </summary>
void Generate(T t, IGridPositionRule<T, IGrid<T>> positionRule, System.Action<int, int, T> callback);
/// <summary>
/// returns the cell at given grid coordinate
/// </summary>
T Fetch(GridCoordinate coord);
}
public partial class RectGrid2D <T> : MonoBehaviour, IGrid<T> where T : GridCell
{
public int rows;
public int columns;
public Dictionary<GridCoordinate, T> grid { get; set; }
public void Generate(T t, IGridPositionRule<T, IGrid<T>> positionRule, Action<int, int, T> callback)
{
grid = new Dictionary<GridCoordinate, T>();
for (int x = 0; x < rows; x++)
{
for (int y = 0; y < columns; y++)
{
var coord = new GridCoordinate(x, y);
var cell = GameObject.Instantiate(t);
grid.Add(coord, cell);
positionRule.PositionCell(cell, this, x, y);
System.Action<int, int, T> _callback = callback;
if (_callback != null)
{
_callback(x, y, cell);
}
}
}
}
/// <summary>
/// returns the cell at given grid coordinate
/// </summary>
public T Fetch(GridCoordinate coord)
{
return grid[coord];
}
/// <summary>
/// Returns a grid cell given T
/// </summary>
public GridCoordinate CoordinateFromCell(T cell)
{
return grid.FirstOrDefault(x => x.Value == cell).Key;
}
}
public struct GridCoordinate
{
public int x;
public int y;
public GridCoordinate (int _x, int _y)
{
this.x = _x;
this.y = _y;
}
}
public class GridCell : MonoBehaviour
{
}
public interface IGridPositionRule <T, U> where T : GridCell where U : IGrid <T>
{
void PositionCell(T cell, U grid, int x, int y);
}
public class BasicPositionRule : IGridPositionRule<GridCell, RectGrid2D<GridCell>>
{
public void PositionCell(GridCell cell, RectGrid2D<GridCell> grid, int x, int y)
{
// do math to position cells for rect grid type pattern
}
}
public partial class GridExample : MonoBehaviour
{
[SerializeField] private GridCell gridCell; // prefab
private void Awake()
{
RectGrid2D<GridCell> grid = GetComponent<RectGrid2D<GridCell>>();
grid.Generate(gridCell, new BasicPositionRule(), (x, y, cell) => // ERROR HERE
{
// do something with grid cell
});
}
}
现在这会引发错误"Argument #2 cannot convert BasicPositionRule expression to type IGridPositionRule<GridCell,IGrid<GridCell>>"
但我希望我的 BasicPositionRule 专属于 RectGrid2D,但这会引发错误:“Argument #2' cannot convertBasicPositionRule' 表达式以键入 `IGridPositionRule>'”
可以通过不将BasicPositionRule 限制为RectGrid2D 来修复该错误
喜欢:
public class BasicPositionRule : IGridPositionRule<GridCell, IGrid<GridCell>>
{
public void PositionCell(GridCell cell, IGrid<GridCell> grid, int x, int y)
{
// do math to position cells for rect grid type pattern
}
}
但我真的想弄清楚如何将定位规则限制为特定的网格类型。
【问题讨论】:
-
抛出的错误cannot convert BasicPositionRule expression to type SM.Grid.IGridPositionRule在哪里?您更改了哪个方法的哪个参数来修复它?
-
@zwcloud 错误位于 GridExample 的第 28 行,在 BasicPositionRule 中将两个 RectGrid2D 定义更改为 IGrid 可修复错误
-
请编辑代码并注释 line 28...
-
@zwcloud 我不太确定如何在此处执行此操作?但是第 28 行是指 GridExample 中网格实例上的 Generate 方法,所以:grid.Generate(gridCell, new BasicPositionRule(), (x, y, cell) =>
-
最好提供可编译的代码。我试图让你的代码在 Unity3D 中工作,但失败了。很抱歉,由于代码包含的类型太多,您的描述仍然不清楚。见mvce。
标签: c# generics unity3d architecture software-design