Revision Difference
World_UI#551380
<cat>UI.Intro</cat>
<title>World UI</title>
<upload src="a5727/8d982ea77614757.png" size="1495562" name="image.png" />
WorldPanels let you render and interact with [UI](UI) within the world. They are actually being drawn in the world, in the right transparent draw order. So they draw behind things and in front of things like you'd expect. Great for name tags etc.
A WorldPanel inherits all the behavior of a RootPanel meaning you can use it exactly the same as any standard UI panel, the only difference is it renders to the world.
# Creating world panels
Creating world panels is nearly identical to [creating any other UI panel](UI), however instead of deriving from a Panel we derive from a WorldPanel.
```csharp
using Sandbox.UI;
using Sandbox.UI.Construct;
class MyWorldPanel : WorldPanel
{
public MyWorldPanel()
{
StyleSheet.Load( "/UI/MyWorldPanel.scss" );
Add.Label( "hello world" );
}
}
```
It's also possible to just spawn a new instance of WorldPanel and add children to it programmatically.
# Spawning WorldPanels
The world panel can then be spawned simply as if it's an entity, setting its position and rotation. Note that you need to update the transform of the world panel, not its children.
```csharp
var worldPanel = new MyWorldPanel();
worldPanel.Transform = Game.LocalPawn.Transform;
```
WorldPanels have to be created **clientside**. To easily sync them across clients you can make a serverside entity that creates the WorldPanel when it gets replicated clientside ([ClientSpawn](https://asset.party/api/Sandbox.Entity.ClientSpawn())).
```csharp
public class WorldPanelCreator : Entity
{
public override void ClientSpawn()
{
base.ClientSpawn();
var worldPanel = new WorldPanel();
// ...
}
}
```
⤶
# Interacting with WorldPanels
⤶
#Resizing WorldPanels
The panel cannot be resized using styles, you must change PanelBounds to do this.⤶
⤶
```csharp⤶
public class BlackRectangle : WorldPanel⤶
{⤶
public BlackRectangle()⤶
{⤶
⤶
var bounds = new Rect() { Width = 300f, Height = 600f }; ⤶
PanelBounds= bounds;⤶
}⤶
}⤶
```⤶
⤶
⤶
# Interacting with WorldPanels⤶
In order to interact with WorldPanels your game needs a WorldInput - you provide a ray and simulated mouse inputs.
```csharp
partial class MinimalPlayer : Player
{
WorldInput WorldInput = new();
public override void BuildInput()
{
WorldInput.Ray = AimRay;
WorldInput.MouseLeftPressed = Input.Down( "attack1" );
}
}
```
## Suppressing Input Events
If you want a tool or weapon to NOT fire when interacting with a certain WorldPanel, you have to suppress its input.
It can be done like this:
```csharp
partial class MinimalPlayer : Player
{
WorldInput WorldInput = new();
public override void BuildInput()
{
WorldInput.Ray = AimRay;
WorldInput.MouseLeftPressed = Input.Down( "attack1" );
if ( WorldInput.Hovered is MyWorldPanel && Input.Down( "attack1" ) )
{
Input.ClearActions();
}
}
}
partial class MyWorldPanel : WorldPanel { }
```
# Deleting WorldPanels
Like entities, world panels are not garbage collected - in order to remove your panel you need to call `WorldPanel.Delete()`.