-
Notifications
You must be signed in to change notification settings - Fork 39
DisplayKit DeletingElements
This guide covers how to remove elements and canvases.
- Hide or Delete
- Removing a Single Element
- Removing All Children
- Despawning a Canvas
- Cleanup Best Practices
As covered in ModifyingElements and CreatingElements, we recommend temporarily hiding an element from a player rather than removing it and adding it back later. Reusing existing elements is generally more efficient, as creating new elements has overhead both on the networking side and within Unity UI Toolkit system.
Remove an element from the hierarchy with the Remove() method:
// Remove an element from the hierarchy and all of its children
myElement.Remove(); // Removes from all clients and server- Removes element from its parent's children list
- Sends removal message to all clients observing the canvas
- Recursively removes all children elements
- Cleans up network resources
public void RemoveNotification(DisplayElement notification)
{
notification.Remove();
}Remove all child elements from a parent:
public void ClearPanel(DisplayElement panel)
{
// Create a copy of the list since we're modifying it
List<IDisplayElement> children = ListPool<IDisplayElement>.Shared.Rent(panel.Children.Count);
children.AddRange(panel.Children);
foreach (IDisplayElement child in children)
{
child.Remove();
}
ListPool<IDisplayElement>.Shared.Return(children);
}Destroys a canvas from all players and clean up:
// Remove a canvas from all players and clean up
canvas.Destroy();- Sends destruction message to all observers
- Removes canvas from
DisplayKitManager.ServerCanvases - Cleans up network resources
- Recycles the canvas ID for future use
- When the UI is no longer needed
- When your plugin disables
- When a round/game ends
- When all players leave
public class MyUI : CustomEventsHandler
{
private DisplayCanvas canvas;
public override void OnServerWaitingForPlayers()
{
canvas = DisplayCanvas.Create();
// ... setup canvas ...
canvas.Spawn();
}
public override void OnServerRoundEnded(RoundEndedEventArgs ev)
{
canvas?.Destroy();
}
}When using per-player canvases, track them for cleanup:
public class HealthBarUI
{
private Dictionary<Player, DisplayCanvas> playerCanvases = new Dictionary<Player, DisplayCanvas>();
public void OnPlayerJoined(Player player)
{
DisplayCanvas canvas = CreateHealthBarCanvas();
canvas.Spawn(player.ReferenceHub);
playerCanvases[player] = canvas;
}
public void OnPlayerLeft(Player player)
{
if (playerCanvases.TryGetValue(player, out DisplayCanvas canvas))
{
canvas.Destroy();
playerCanvases.Remove(player);
}
}
public void OnDisabled()
{
// Clean up all canvases
foreach (DisplayCanvas canvas in playerCanvases.Values)
{
canvas.Destroy();
}
playerCanvases.Clear();
}
}public void OnDisabled()
{
// Safe even if canvas is null
canvas?.Destroy();
// Also set to null to prevent accidental use
canvas = null;
}public override void OnServerRoundEnded(RoundEndedEventArgs ev)
{
// Despawn all UI canvases
foreach (DisplayCanvas canvas in _myCanvases)
{
canvas.Destroy();
}
//additional cleanup
}public override void OnPlayerLeft(PlayerLeftEventArgs ev)
{
// Remove player's inventory UI
if (customUI.TryGetValue(ev.Player, out DisplayCanvas inventoryCanvas))
{
inventoryCanvas.Destroy();
customUI.Remove(ev.Player);
}
}public override void Disable()
{
// Clean up global UI, this is just an example
globalAnnouncementCanvas?.Destroy();
scoreboardCanvas?.Destroy();
// Clean up all per-player UI
foreach (var kvp in playerCanvases)
{
kvp.Value.Destroy();
}
playerCanvases.Clear();
}Warning
Always destroy canvases when done to prevent memory leaks and network issues
Destroy vs Hide - Use Destroy() when completely done, use canvas.Hide() for temporary hiding
Element cleanup - Elements are automatically cleaned up when their canvas is destroyed
Caution
Don't reuse destroyed canvases - Create new canvases instead
- Sending to Players - Understanding canvas scope