Purpose
This level editor was mainly created for a game I had worked on with a small team. In essence, the environmental style of the game required discrete, hexagonal terrains.
Draw hexagon handle
// Draw handles as a hexagon
static void DrawHandlesHex(Vector3 center)
{
Vector3 offsetX = Vector3.right * hexInnerRadius;
Vector3 offsetY = Vector3.zero;
Vector3 offsetZ = Vector3.forward * 0.5f * hexOuterRadius;
// Set position of 6 points on hexagon
Vector3 p1 = center + offsetY + Vector3.forward;
Vector3 p2 = center + offsetY + offsetX + offsetZ;
Vector3 p3 = center + offsetY + offsetX - offsetZ;
Vector3 p4 = center + offsetY - Vector3.forward;
Vector3 p5 = center + offsetY - offsetX - offsetZ;
Vector3 p6 = center + offsetY - offsetX + offsetZ;
// Draw lines from point to point to form a hexagon
Vector3[] hexPoints = { p1, p2, p3, p4, p5, p6, p1 };
Handles.DrawPolyLine(hexPoints);
}
Add tile
public static void AddTile(Vector3 position, GameObject prefab, bool isOptimizeMode)
{
if (prefab == null) return;
// Instantiate tile prefab
GameObject newTile = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
// Make tile child of level parent
newTile.transform.parent = LevelParent;
// Place tile at current handle position
newTile.transform.position = position;
if (!isOptimizeMode)
{
// Register undo option for add action
Undo.RegisterCreatedObjectUndo(newTile, "Add Tile");
}
// Mark scene as modified
UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();
}
Remove tile
public static void RemoveTile(Vector3 position, bool isOptimizeMode)
{
Transform[] tiles = LevelParent.GetComponentsInChildren<Transform>();
// Iterating through all child of level parent
// int i = 1 ignores parent transform
for (int i = 1; i < tiles.Length; i++)
{
// Store distance squared from current position to tile
float distanceToTileSqr = (tiles[i].position - position).sqrMagnitude;
// If square distance to tile is under threshold square distance
if (distanceToTileSqr <= 2f * hexDepthRadius * hexDepthRadius)
{
// If RemoveTile is used in optimization
if (isOptimizeMode)
{
// Destroy tile, no undo register
DestroyImmediate(tiles[i].gameObject);
}
else
{
// Destroy tile and register option to undo destroy
Undo.DestroyObjectImmediate(tiles[i].gameObject);
}
// Mark scene as modified
UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();
return;
}
}
}
Replace tile
public static void ReplaceTile(Vector3 position, GameObject prefab)
{
if (prefab == null) return;
if (PositionContainsTile(position))
{
// Replace if tiles are not the same
if (!PositionContainsSameTile(position, prefab))
{
RemoveTile(position + Vector3.down * hexDepthRadius, false);
AddTile(position + Vector3.down * hexDepthRadius, prefab, false);
}
}
}