Skip to content

Outlines

davidsebesta edited this page Apr 16, 2026 · 7 revisions

Outlines Effects

Overview

System designed to mark a specific object via colored outline with specified thickness and other properties.
The system supports synchronisation from server to client. With additional feature(s) for local spawning for base-game needs, such as marking currently hovered-over pickup (the only locally spawned outline as of 15.0, everything else can be disabled or modified on the server.

How it works

Each outlinable object has OutlineEffectController, this controller is responsible for adding/removing/editing outlines by you.
For easier programming, both base game and wrapper classes for players and pickups have extension methods such as TryAddOutline(..), TryRemoveOutline(..) and so on.
These allow you to add an outline without the need to get the controller from somewhere in the object's hierarchy.

Adding outline

OutlineEffect effect = new OutlineEffect(0, Color.red, 5, 0, true, false, null);

foreach(Player player in Player.ReadyList)
{
	bool res = player.TryAddOutline(effect.Clone());

	// use res for whatever.. will fail if the player is not IFpcRole
}

Caution

Do not add a single outline instance to multiple controllers, it will result in unintended behaviour.
Use OutlineEffect::Clone() or the copy constructor to give it to multiple controllers from 1 template you create.

Removing outline

int outlineId = 12345;
Player player = Player.Get(someHub);

// either remove by outline id

bool res = player.TryRemoveOutline(12345);

//or you can use the reference for the player-specific instance

res = player.TryRemoveOutline(myOutlineEffect);

Properties

Each base outline has these properties:
OutlineId - Server created unique integer identifier for every outline instance, used to correctly sync, remove and edit outlines over the network
TargetControllerNetworkId - Property for correctly syncing the outline to the correct controller
Priority - Priority of the outline in the controller, higher number wins. If 2 outlines have the same priority, then the first one added wins
OutlineColor - Colour property of the outline
OutlineThickness - Overall thickness of the outline
StencilShrink - How much will the outline drawn shrink into the model itself, making the outline more aggressive on body parts such as face, clothes and other sudden changes. Generally recommended to leave at 0
SeeThroughWalls - Whether the outline is seen through walls. This property also handles server-side rolesync, position distribution & client-side culling if it's enabled to be seen properly
Fill - Whether the outline fills the model too
Modifiers - A readonly list of modifiers added with the constructor, all modifiers are synced to the client.

Modifying outlines

Outlines properties are synced only once during creation, but we created a system to allow changes based on other properties, such as distance, health or a custom one.

Implementations

OutlineEffect

Base implementation, which is visible to every player.

RoleBasedOutlineEffect

Synchronises the effect visibility to only players with the specified Role.

TeamBasedOutlineEffect

Let developers pick the target Team to which the outline is visible. Also allows for an exception for role(s) in the team.

Modifiers

There are currently several modifiers which allow you to dynamically change the outline properties.
Most modifiers are client-side by default, but some are synced over the network and handled via AnimationCurve.

DistanceBasedOutlineModifier

The most basic modifier added to all base game outlines. Allows you to fade in and fade out the alpha of the outline based on the player's distance to the target.

Note

Outlines are still rendered and are visible if you walk into the player/item model. This may cause a sudden spike in bright colour, and it is recommended to fade it out when close.

CurveBasedOutlineModifier

Modifier which changes based on curve evaluation based on NetworkTime.time property. Every property can be changed based on a curve, or left null to not be evaluated over time and set to a constant based on the outline property. The evaluation is done client-side.

Note

AnimationCurves sent over the network are automatically set to loop behaviour.

NetworkedCurveModifier

Modifier that is evaluated on the curve, but the evaluation is done via a synchronised value over the network controller by the server.

PlayerStatOutlineModifier

Subclass of NetworkedCurveModifier which automatically changes the value from 0-1f based on the specified player's SyncedStatBase.

Clone this wiki locally