Skip to content

Commit e9955e7

Browse files
authored
Prefab brush for Instantiating a selected prefab in editor. Moved the old functionality to PrefabRandomBrush.cs (Unity-Technologies#184)
* Add new prefab brush. Moved the old functionality to PrefabRandomBrush.cs * Add new summary for fields and methods * Fix custom editor * Add base class for general logic of PrefabBrushes
1 parent 758ebd7 commit e9955e7

File tree

10 files changed

+280
-142
lines changed

10 files changed

+280
-142
lines changed

Editor/Brushes/PrefabBrush/PrefabBrush.cs

Lines changed: 0 additions & 142 deletions
This file was deleted.
File renamed without changes.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
using UnityEngine;
2+
3+
namespace UnityEditor.Tilemaps
4+
{
5+
/// <summary>
6+
/// This base class for PrefabBrushes that contains common functionality
7+
/// </summary>
8+
public class BasePrefabBrush : GridBrush
9+
{ /// <summary>
10+
/// Anchor Point of the Instantiated Prefab in the cell when painting
11+
/// </summary>
12+
public Vector3 m_Anchor = new Vector3(0.5f, 0.5f, 0.5f);
13+
14+
/// <summary>
15+
/// GameObject to instantiating
16+
/// </summary>
17+
protected GameObject Prefab = null;
18+
19+
protected static Transform GetObjectInCell(GridLayout grid, Transform parent, Vector3Int position)
20+
{
21+
var childCount = parent.childCount;
22+
for (var i = 0; i < childCount; i++)
23+
{
24+
var child = parent.GetChild(i);
25+
if (position == grid.WorldToCell(child.position))
26+
{
27+
return child;
28+
}
29+
}
30+
return null;
31+
}
32+
33+
public override void Erase(GridLayout grid, GameObject brushTarget, Vector3Int position)
34+
{
35+
if (brushTarget.layer == 31)
36+
{
37+
return;
38+
}
39+
40+
var erased = GetObjectInCell(grid, brushTarget.transform, position);
41+
if (erased != null)
42+
{
43+
Undo.DestroyObjectImmediate(erased.gameObject);
44+
}
45+
}
46+
47+
public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
48+
{
49+
// Do not allow editing palettes
50+
if (brushTarget.layer == 31 || brushTarget == null)
51+
return;
52+
53+
var tileObject = GetObjectInCell(grid, brushTarget.transform, position);
54+
if (tileObject)
55+
{
56+
return;
57+
}
58+
var instance = (GameObject)PrefabUtility.InstantiatePrefab(Prefab);
59+
if (instance != null)
60+
{
61+
Undo.MoveGameObjectToScene(instance, brushTarget.scene, "Paint Prefabs");
62+
Undo.RegisterCreatedObjectUndo((Object)instance, "Paint Prefabs");
63+
instance.transform.SetParent(brushTarget.transform);
64+
instance.transform.position = grid.LocalToWorld(grid.CellToLocalInterpolated(position + m_Anchor));
65+
}
66+
}
67+
}
68+
69+
public class BasePrefabBrushEditor : GridBrushEditor
70+
{
71+
private SerializedProperty m_Anchor;
72+
protected SerializedObject m_SerializedObject;
73+
74+
protected override void OnEnable()
75+
{
76+
base.OnEnable();
77+
m_SerializedObject = new SerializedObject(target);
78+
m_Anchor = m_SerializedObject.FindProperty("m_Anchor");
79+
}
80+
81+
/// <summary>
82+
/// Callback for painting the inspector GUI for the PrefabBrush in the Tile Palette.
83+
/// The PrefabBrush Editor overrides this to have a custom inspector for this Brush.
84+
/// </summary>
85+
public override void OnPaintInspectorGUI()
86+
{
87+
m_SerializedObject.UpdateIfRequiredOrScript();
88+
EditorGUILayout.PropertyField(m_Anchor);
89+
m_SerializedObject.ApplyModifiedPropertiesWithoutUndo();
90+
}
91+
}
92+
}

Editor/Brushes/PrefabBrushes/BasePrefabBrush.cs.meta

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

Editor/Brushes/PrefabBrushes/PrefabBrush.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
using UnityEngine;
2+
3+
namespace UnityEditor.Tilemaps
4+
{
5+
/// <summary>
6+
/// This Brush instances and places a selected prefab onto the targeted location and parents the instanced object to the paint target.
7+
/// </summary>
8+
[CreateAssetMenu(fileName = "Prefab brush", menuName = "Brushes/Prefab brush")]
9+
[CustomGridBrush(false, true, false, "Prefab Brush")]
10+
public class PrefabBrush : BasePrefabBrush
11+
{
12+
/// <summary>
13+
/// The selection of Prefab to paint from
14+
/// </summary>
15+
public GameObject m_Prefab;
16+
/// <summary>
17+
/// Use to remove all prefabs in the cell or just the one that is currently selected in m_Prefab
18+
/// </summary>
19+
public bool m_ForceDelete;
20+
/// <summary>
21+
/// Paints Prefabs into a given position within the selected layers.
22+
/// The PrefabBrush overrides this to provide Prefab painting functionality.
23+
/// </summary>
24+
/// <param name="grid">Grid used for layout.</param>
25+
/// <param name="brushTarget">Target of the paint operation. By default the currently selected GameObject.</param>
26+
/// <param name="position">The coordinates of the cell to paint data to.</param>
27+
28+
public override void Paint(GridLayout grid, GameObject brushTarget, Vector3Int position)
29+
{
30+
31+
32+
Prefab = m_Prefab;
33+
var tileObject = GetObjectInCell(grid, brushTarget.transform, position);
34+
if (tileObject == null || tileObject.name != m_Prefab.name)
35+
{
36+
base.Paint(grid, brushTarget, position);
37+
}
38+
}
39+
40+
/// <summary>
41+
/// Erases all Prefabs in a given position within the selected layers if ForceDelete is true.
42+
/// Erase only selected Prefabs in a given position within the selected layers if ForceDelete is false.
43+
/// The PrefabBrush overrides this to provide Prefab erasing functionality.
44+
/// </summary>
45+
/// <param name="grid">Grid used for layout.</param>
46+
/// <param name="brushTarget">Target of the erase operation. By default the currently selected GameObject.</param>
47+
/// <param name="position">The coordinates of the cell to erase data from.</param>
48+
public override void Erase(GridLayout grid, GameObject brushTarget, Vector3Int position)
49+
{
50+
var erased = GetObjectInCell(grid, brushTarget.transform, position);
51+
if (erased == null)
52+
{
53+
return;
54+
}
55+
if (m_ForceDelete || (!m_ForceDelete && erased.gameObject.name == m_Prefab.name))
56+
{
57+
base.Erase(grid, brushTarget, position);
58+
}
59+
}
60+
}
61+
62+
/// <summary>
63+
/// The Brush Editor for a Prefab Brush.
64+
/// </summary>
65+
[CustomEditor(typeof(PrefabBrush))]
66+
public class PrefabBrushEditor : BasePrefabBrushEditor
67+
{
68+
private SerializedProperty m_Prefab;
69+
private SerializedProperty m_ForceDelete;
70+
71+
protected override void OnEnable()
72+
{
73+
base.OnEnable();
74+
m_Prefab = m_SerializedObject.FindProperty("m_Prefab");
75+
m_ForceDelete = m_SerializedObject.FindProperty("m_ForceDelete");
76+
}
77+
78+
/// <summary>
79+
/// Callback for painting the inspector GUI for the PrefabBrush in the Tile Palette.
80+
/// The PrefabBrush Editor overrides this to have a custom inspector for this Brush.
81+
/// </summary>
82+
public override void OnPaintInspectorGUI()
83+
{
84+
base.OnPaintInspectorGUI();
85+
m_SerializedObject.UpdateIfRequiredOrScript();
86+
EditorGUILayout.PropertyField(m_Prefab, true);
87+
EditorGUILayout.PropertyField(m_ForceDelete, true);
88+
m_SerializedObject.ApplyModifiedPropertiesWithoutUndo();
89+
}
90+
}
91+
}

Editor/Brushes/PrefabBrushes/PrefabRandomBrush.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.

0 commit comments

Comments
 (0)