Prefab Spawner for Scene View Prefab Spawner for Scene View

Prefab Spawner for Scene View

The prefab spawning tool allows level designers to click in the scene view to instantiate prefabs at the clicked location.

This tool was created for the game Cloud 9-5 which used voxel levels. The level designer on the project mentioned that iterating on the level took significant time and how they wished the experience would feel more like minecraft. In response I created a simple tool that enabled the requested behavior plus some enhancements for modifying aspects of the newly instantiated prefab.

Optional modifiers include:

  • Randomized position, rotation and scale offset within designated ranges
  • Grid snap prefabs using your grid snap preference value
  • Align to normal of clicked surface
  • Spawn as a prefab or non-prefab gameObject

How it works

A lot of cool techniques went into making this project work. I think this project makes for a great first step into tool development for Unity.

Creating an editor window with UI Builder and UI Toolkit

I recommend seeing Unity’s documentation about UI Builder and UI Toolkit as at the time of this writing, these features are still in development and subject to changes.

What I can share is how I then queried for and bound UXML elements with my C# code.

private void InitFields()
{
spawnablePrefab = rootVisualElement.Q<ObjectField>("SpawnablePrefab");
raycastLayerMask = rootVisualElement.Q<LayerMaskField>("RaycastLayerMask");
parentTransform = rootVisualElement.Q<ObjectField>("ParentTransform");
minRotation = rootVisualElement.Q<Vector3Field>("MinRotation");
maxRotation = rootVisualElement.Q<Vector3Field>("MaxRotation");
alignToNormals = rootVisualElement.Q<ToolbarToggle>("SnapToGrid");
spawnAsPrefab = rootVisualElement.Q<ToolbarToggle>("SpawnAsPrefab");
gridSnapped = rootVisualElement.Q<ToolbarToggle>("SnapToGrid");
active = rootVisualElement.Q<Toggle>("Active");
}

Capturing input inside the editor

Classes that inherit from EditorWindow have access to the OnSceneGUI function which grants access to scene view information.

private void OnSceneGUI(SceneView obj)
{
if (!active?.value ?? true)
{
return;
}
Event eventCurrent = Event.current;
// If left mouse down
if (eventCurrent.type == EventType.MouseDown &&
eventCurrent.button == 0)
{
RaycastSpawn(eventCurrent);
}
}

Spawning prefabs with Prefab Utility

In the following example, spawnablePrefab is a field that we know contains a prefab GameObject. It is important to note that the PrefabUtility class is only accessible in editor and NOT in builds.

private GameObject SpawnAsGameObject(Transform parent = null)
{
// Instantiate prefab
GameObject go = (GameObject)Instantiate(spawnablePrefab.value, parent);
// this would normally be of type Object not GameObject
return go;
}
private GameObject SpawnAsPrefab(Transform parent = null)
{
// Instantiate prefab
GameObject go = (GameObject)PrefabUtility.InstantiatePrefab(spawnablePrefab.value, parent);
// this would normally be of type Object not GameObject
return go;
}

← Back to projects