224 lines
8.6 KiB
C#
224 lines
8.6 KiB
C#
|
using UnityEngine;
|
||
|
using UnityEngine.Tilemaps;
|
||
|
|
||
|
namespace UnityEditor
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The Editor for a HexagonalRuleTile.
|
||
|
/// </summary>
|
||
|
[CustomEditor(typeof(HexagonalRuleTile), true)]
|
||
|
[CanEditMultipleObjects]
|
||
|
public class HexagonalRuleTileEditor : RuleTileEditor
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// The HexagonalRuleTile being edited.
|
||
|
/// </summary>
|
||
|
public HexagonalRuleTile hexTile => target as HexagonalRuleTile;
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets the index for a Rule with the HexagonalRuleTile to display an arrow.
|
||
|
/// </summary>
|
||
|
/// <param name="position">The adjacent position of the arrow.</param>
|
||
|
/// <returns>Returns the index for a Rule with the HexagonalRuleTile to display an arrow.</returns>
|
||
|
public override int GetArrowIndex(Vector3Int position)
|
||
|
{
|
||
|
if (position.y % 2 != 0)
|
||
|
{
|
||
|
position *= 2;
|
||
|
position.x += 1;
|
||
|
}
|
||
|
|
||
|
if (position.x == 0)
|
||
|
{
|
||
|
if (position.y > 0)
|
||
|
return hexTile.m_FlatTop ? 5 : 1;
|
||
|
else
|
||
|
return hexTile.m_FlatTop ? 3 : 7;
|
||
|
}
|
||
|
else if (position.y == 0)
|
||
|
{
|
||
|
if (position.x > 0)
|
||
|
return hexTile.m_FlatTop ? 1 : 5;
|
||
|
else
|
||
|
return hexTile.m_FlatTop ? 7 : 3;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (position.x < 0 && position.y > 0)
|
||
|
return hexTile.m_FlatTop ? 8 : 0;
|
||
|
else if (position.x > 0 && position.y > 0)
|
||
|
return hexTile.m_FlatTop ? 2 : 2;
|
||
|
else if (position.x < 0 && position.y < 0)
|
||
|
return hexTile.m_FlatTop ? 6 : 6;
|
||
|
else if (position.x > 0 && position.y < 0)
|
||
|
return hexTile.m_FlatTop ? 0 : 8;
|
||
|
}
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Get the GUI bounds for a Rule.
|
||
|
/// </summary>
|
||
|
/// <param name="bounds">Cell bounds of the Rule.</param>
|
||
|
/// <param name="rule">Rule to get GUI bounds for.</param>
|
||
|
/// <returns>The GUI bounds for a rule.</returns>
|
||
|
public override BoundsInt GetRuleGUIBounds(BoundsInt bounds, RuleTile.TilingRule rule)
|
||
|
{
|
||
|
foreach (var n in rule.GetNeighbors())
|
||
|
{
|
||
|
if (n.Key.x == bounds.xMax - 1 && n.Key.y % 2 != 0)
|
||
|
{
|
||
|
bounds.xMax++;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return base.GetRuleGUIBounds(bounds, rule);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Gets the GUI matrix size for a Rule of a HexagonalRuleTile
|
||
|
/// </summary>
|
||
|
/// <param name="bounds">Cell bounds of the Rule.</param>
|
||
|
/// <returns>Returns the GUI matrix size for a Rule of a HexagonalRuleTile.</returns>
|
||
|
public override Vector2 GetMatrixSize(BoundsInt bounds)
|
||
|
{
|
||
|
Vector2 size = base.GetMatrixSize(bounds);
|
||
|
return hexTile.m_FlatTop ? new Vector2(size.y, size.x) : size;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Draws a Rule Matrix for the given Rule for a HexagonalRuleTile.
|
||
|
/// </summary>
|
||
|
/// <param name="tile">Tile to draw rule for.</param>
|
||
|
/// <param name="rect">GUI Rect to draw rule at.</param>
|
||
|
/// <param name="bounds">Cell bounds of the Rule.</param>
|
||
|
/// <param name="tilingRule">Rule to draw Rule Matrix for.</param>
|
||
|
public override void RuleMatrixOnGUI(RuleTile tile, Rect rect, BoundsInt bounds, RuleTile.TilingRule tilingRule)
|
||
|
{
|
||
|
bool flatTop = hexTile.m_FlatTop;
|
||
|
|
||
|
Handles.color = EditorGUIUtility.isProSkin ? new Color(1f, 1f, 1f, 0.2f) : new Color(0f, 0f, 0f, 0.2f);
|
||
|
float w = rect.width / (flatTop ? bounds.size.y : bounds.size.x);
|
||
|
float h = rect.height / (flatTop ? bounds.size.x : bounds.size.y);
|
||
|
|
||
|
// Grid
|
||
|
if (flatTop)
|
||
|
{
|
||
|
for (int y = 0; y <= bounds.size.y; y++)
|
||
|
{
|
||
|
float left = rect.xMin + y * w;
|
||
|
float offset = 0;
|
||
|
|
||
|
if (y == 0 && bounds.yMax % 2 == 0)
|
||
|
offset = h / 2;
|
||
|
else if (y == bounds.size.y && bounds.yMin % 2 != 0)
|
||
|
offset = h / 2;
|
||
|
|
||
|
Handles.DrawLine(new Vector3(left, rect.yMin + offset), new Vector3(left, rect.yMax - offset));
|
||
|
|
||
|
if (y < bounds.size.y)
|
||
|
{
|
||
|
bool noOffset = (y + bounds.yMax) % 2 != 0;
|
||
|
for (int x = 0; x < (noOffset ? (bounds.size.x + 1) : bounds.size.x); x++)
|
||
|
{
|
||
|
float top = rect.yMin + x * h + (noOffset ? 0 : h / 2);
|
||
|
Handles.DrawLine(new Vector3(left, top), new Vector3(left + w, top));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (int y = 0; y <= bounds.size.y; y++)
|
||
|
{
|
||
|
float top = rect.yMin + y * h;
|
||
|
float offset = 0;
|
||
|
|
||
|
if (y == 0 && bounds.yMax % 2 == 0)
|
||
|
offset = w / 2;
|
||
|
else if (y == bounds.size.y && bounds.yMin % 2 != 0)
|
||
|
offset = w / 2;
|
||
|
|
||
|
Handles.DrawLine(new Vector3(rect.xMin + offset, top), new Vector3(rect.xMax - offset, top));
|
||
|
|
||
|
if (y < bounds.size.y)
|
||
|
{
|
||
|
bool noOffset = (y + bounds.yMax) % 2 != 0;
|
||
|
for (int x = 0; x < (noOffset ? (bounds.size.x + 1) : bounds.size.x); x++)
|
||
|
{
|
||
|
float left = rect.xMin + x * w + (noOffset ? 0 : w / 2);
|
||
|
Handles.DrawLine(new Vector3(left, top), new Vector3(left, top + h));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var neighbors = tilingRule.GetNeighbors();
|
||
|
|
||
|
// Icons
|
||
|
Handles.color = Color.white;
|
||
|
for (int y = bounds.yMin; y < bounds.yMax; y++)
|
||
|
{
|
||
|
int xMax = y % 2 == 0 ? bounds.xMax : (bounds.xMax - 1);
|
||
|
for (int x = bounds.xMin; x < xMax; x++)
|
||
|
{
|
||
|
Vector3Int pos = new Vector3Int(x, y, 0);
|
||
|
Vector2 offset = new Vector2(x - bounds.xMin, -y + bounds.yMax - 1);
|
||
|
Rect r = flatTop ? new Rect(rect.xMax - offset.y * w - w, rect.yMax - offset.x * h - h, w - 1, h - 1)
|
||
|
: new Rect(rect.xMin + offset.x * w, rect.yMin + offset.y * h, w - 1, h - 1);
|
||
|
|
||
|
if (y % 2 != 0)
|
||
|
{
|
||
|
if (flatTop)
|
||
|
r.y -= h / 2;
|
||
|
else
|
||
|
r.x += w / 2;
|
||
|
}
|
||
|
|
||
|
RuleMatrixIconOnGUI(tilingRule, neighbors, pos, r);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Creates a Preview for the HexagonalRuleTile.
|
||
|
/// </summary>
|
||
|
protected override void CreatePreview()
|
||
|
{
|
||
|
base.CreatePreview();
|
||
|
|
||
|
m_PreviewGrid.cellLayout = GridLayout.CellLayout.Hexagon;
|
||
|
m_PreviewGrid.cellSize = new Vector3(0.8659766f, 1.0f, 1.0f);
|
||
|
m_PreviewGrid.cellSwizzle = hexTile.m_FlatTop ? GridLayout.CellSwizzle.YXZ : GridLayout.CellSwizzle.XYZ;
|
||
|
|
||
|
foreach (var tilemap in m_PreviewTilemaps)
|
||
|
{
|
||
|
tilemap.tileAnchor = Vector3.zero;
|
||
|
tilemap.ClearAllTiles();
|
||
|
}
|
||
|
|
||
|
for (int x = -1; x <= 0; ++x)
|
||
|
for (int y = -1; y <= 1; ++y)
|
||
|
m_PreviewTilemaps[0].SetTile(new Vector3Int(x, y, 0), tile);
|
||
|
|
||
|
m_PreviewTilemaps[1].SetTile(new Vector3Int(1, -1, 0), tile);
|
||
|
m_PreviewTilemaps[1].SetTile(new Vector3Int(2, 0, 0), tile);
|
||
|
m_PreviewTilemaps[1].SetTile(new Vector3Int(2, 1, 0), tile);
|
||
|
|
||
|
for (int x = -1; x <= 1; x++)
|
||
|
m_PreviewTilemaps[2].SetTile(new Vector3Int(x, -2, 0), tile);
|
||
|
|
||
|
m_PreviewTilemaps[3].SetTile(new Vector3Int(1, 1, 0), tile);
|
||
|
|
||
|
foreach (var tilemapRenderer in m_PreviewTilemapRenderers)
|
||
|
tilemapRenderer.sortOrder = TilemapRenderer.SortOrder.TopRight;
|
||
|
|
||
|
m_PreviewTilemapRenderers[0].sortingOrder = 0;
|
||
|
m_PreviewTilemapRenderers[1].sortingOrder = -1;
|
||
|
m_PreviewTilemapRenderers[2].sortingOrder = 1;
|
||
|
m_PreviewTilemapRenderers[3].sortingOrder = 0;
|
||
|
}
|
||
|
}
|
||
|
}
|