Skip to content

Commit a317f11

Browse files
-Add Group Brush
1 parent c55ba39 commit a317f11

File tree

5 files changed

+218
-0
lines changed

5 files changed

+218
-0
lines changed

Assets/Tilemap/Brushes/Group Brush.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Tilemap/Brushes/Group Brush/Scripts.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/Tilemap/Brushes/Group Brush/Scripts/Editor.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
using UnityEngine.Tilemaps;
5+
6+
namespace UnityEditor
7+
{
8+
[CustomGridBrush(true, false, false, "Group Brush")]
9+
public class GroupBrush : GridBrush
10+
{
11+
public Vector3Int gap
12+
{
13+
get { return m_Gap; }
14+
set
15+
{
16+
m_Gap = value;
17+
if (m_Gap.x < 0)
18+
m_Gap.x = 0;
19+
if (m_Gap.y < 0)
20+
m_Gap.y = 0;
21+
if (m_Gap.z < 0)
22+
m_Gap.z = 0;
23+
}
24+
}
25+
26+
public Vector3Int limit
27+
{
28+
get { return m_Limit; }
29+
set
30+
{
31+
m_Limit = value;
32+
if (m_Limit.x < 0)
33+
m_Limit.x = 0;
34+
if (m_Limit.y < 0)
35+
m_Limit.y = 0;
36+
if (m_Limit.z < 0)
37+
m_Limit.z = 0;
38+
m_VisitedLocations = new BitArray((m_Limit.x * 2 + 1) * (m_Limit.y * 2 + 1) * (m_Limit.z * 2 + 1));
39+
}
40+
}
41+
42+
[SerializeField]
43+
private Vector3Int m_Gap = Vector3Int.one;
44+
[SerializeField]
45+
private Vector3Int m_Limit = Vector3Int.one * 3;
46+
[SerializeField]
47+
private BitArray m_VisitedLocations = new BitArray(7 * 7 * 7);
48+
[SerializeField]
49+
private Stack<Vector3Int> m_NextPosition = new Stack<Vector3Int>();
50+
51+
public override void Pick(GridLayout gridLayout, GameObject brushTarget, BoundsInt position, Vector3Int pickStart)
52+
{
53+
// Do standard pick if user has selected a custom bounds
54+
if (position.size.x > 1 || position.size.y > 1 || position.size.z > 1)
55+
{
56+
base.Pick(gridLayout, brushTarget, position, pickStart);
57+
return;
58+
}
59+
60+
Tilemap tilemap = brushTarget.GetComponent<Tilemap>();
61+
if (tilemap == null)
62+
return;
63+
64+
Reset();
65+
66+
// Determine size of picked locations based on gap and limit
67+
Vector3Int limitOrigin = position.position - limit;
68+
Vector3Int limitSize = Vector3Int.one + limit * 2;
69+
BoundsInt limitBounds = new BoundsInt(limitOrigin, limitSize);
70+
BoundsInt pickBounds = new BoundsInt(position.position, Vector3Int.one);
71+
72+
m_VisitedLocations.SetAll(false);
73+
m_VisitedLocations.Set(GetIndex(position.position, limitOrigin, limitSize), true);
74+
m_NextPosition.Clear();
75+
m_NextPosition.Push(position.position);
76+
77+
while (m_NextPosition.Count > 0)
78+
{
79+
Vector3Int next = m_NextPosition.Pop();
80+
if (tilemap.GetTile(next) != null)
81+
{
82+
Encapsulate(ref pickBounds, next);
83+
BoundsInt gapBounds = new BoundsInt(next - gap, Vector3Int.one + gap * 2);
84+
foreach (var gapPosition in gapBounds.allPositionsWithin)
85+
{
86+
if (!limitBounds.Contains(gapPosition))
87+
continue;
88+
int index = GetIndex(gapPosition, limitOrigin, limitSize);
89+
if (!m_VisitedLocations.Get(index))
90+
{
91+
m_NextPosition.Push(gapPosition);
92+
m_VisitedLocations.Set(index, true);
93+
}
94+
}
95+
}
96+
}
97+
98+
UpdateSizeAndPivot(pickBounds.size, position.position - pickBounds.position);
99+
100+
foreach (Vector3Int pos in pickBounds.allPositionsWithin)
101+
{
102+
Vector3Int brushPosition = new Vector3Int(pos.x - pickBounds.x, pos.y - pickBounds.y, pos.z - pickBounds.z);
103+
if (m_VisitedLocations.Get(GetIndex(pos, limitOrigin, limitSize)))
104+
{
105+
PickCell(pos, brushPosition, tilemap);
106+
}
107+
}
108+
}
109+
110+
private void Encapsulate(ref BoundsInt bounds, Vector3Int position)
111+
{
112+
if (bounds.Contains(position))
113+
return;
114+
115+
if (position.x < bounds.position.x)
116+
{
117+
var increase = bounds.x - position.x;
118+
bounds.position = new Vector3Int(position.x, bounds.y, bounds.z);
119+
bounds.size = new Vector3Int(bounds.size.x + increase, bounds.size.y, bounds.size.z);
120+
}
121+
if (position.x >= bounds.xMax)
122+
{
123+
var increase = position.x - bounds.xMax + 1;
124+
bounds.size = new Vector3Int(bounds.size.x + increase, bounds.size.y, bounds.size.z);
125+
}
126+
if (position.y < bounds.position.y)
127+
{
128+
var increase = bounds.y - position.y;
129+
bounds.position = new Vector3Int(bounds.x, position.y, bounds.z);
130+
bounds.size = new Vector3Int(bounds.size.x, bounds.size.y + increase, bounds.size.z);
131+
}
132+
if (position.y >= bounds.yMax)
133+
{
134+
var increase = position.y - bounds.yMax + 1;
135+
bounds.size = new Vector3Int(bounds.size.x, bounds.size.y + increase, bounds.size.z);
136+
}
137+
if (position.z < bounds.position.z)
138+
{
139+
var increase = bounds.z - position.z;
140+
bounds.position = new Vector3Int(bounds.x, bounds.y, position.z);
141+
bounds.size = new Vector3Int(bounds.size.x, bounds.size.y, bounds.size.z + increase);
142+
}
143+
if (position.z >= bounds.zMax)
144+
{
145+
var increase = position.z - bounds.zMax + 1;
146+
bounds.size = new Vector3Int(bounds.size.x, bounds.size.y, bounds.size.z + increase);
147+
}
148+
}
149+
150+
private int GetIndex(Vector3Int position, Vector3Int origin, Vector3Int size)
151+
{
152+
return (position.z - origin.z) * size.y * size.x
153+
+ (position.y - origin.y) * size.x
154+
+ (position.x - origin.x);
155+
}
156+
157+
private void PickCell(Vector3Int position, Vector3Int brushPosition, Tilemap tilemap)
158+
{
159+
if (tilemap != null)
160+
{
161+
SetTile(brushPosition, tilemap.GetTile(position));
162+
SetMatrix(brushPosition, tilemap.GetTransformMatrix(position));
163+
SetColor(brushPosition, tilemap.GetColor(position));
164+
}
165+
}
166+
167+
[MenuItem("Assets/Create/Group Brush")]
168+
public static void CreateBrush()
169+
{
170+
string path = EditorUtility.SaveFilePanelInProject("Save Group Brush", "New Group Brush", "asset", "Save Group Brush", "Assets");
171+
172+
if (path == "")
173+
return;
174+
175+
AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<GroupBrush>(), path);
176+
}
177+
}
178+
179+
[CustomEditor(typeof(GroupBrush))]
180+
public class GroupBrushEditor : GridBrushEditor
181+
{
182+
}
183+
}

Assets/Tilemap/Brushes/Group Brush/Scripts/Editor/GroupBrush.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)