Architecture
This section describes main components available in the Interest Management addon.
The diagram above shows relationship between components from high-level perspective and their usage.
Interest Shape
- Defines area/volume of interest that will be added upon evaluation to target player's interest and converted to Interest Cells (see below).
- Shapes are linked to Interest Providers and Player Interest Views.
- Three basic shapes available:
InterestShpere
InterestBox
InterestCone
- Custom shape can be implemented by deriving from
InterestShape
class.
Interest Provider
- Provides interest related to a specific object in the world. Typically an area around that object.
- Base
InterestProvider
implements:- List of
InterestShape
references. - No filtering rules by default, the interest is processed for all players when evaluated.
- List of
- Custom provider is implemented by deriving from
InterestProvider
class and overridingbool IsPlayerInterested()
method. - Global providers (toggle
IsGlobal
enabled) are automatically registered toGlobalInterestManager
and evaluated for all players. - Providers nesting is supported by linking
Child Providers
.
Following image shows custom InterestByDistance
provider which adds interest of linked InterestBox
shape if a player is within 300m (property VisibilityDistance
) from the object:
Following image shows another example of scene objects providing interest to a player based on distance and view angle:
PlayerInterestManager
andPlayerInterestView
are onAgent
object and provide base interest from player perspective - the cone view.Tower
objects have a component derived fromInterestProvider
which implements filtering rules.- One tower is in player's view within a specific angle and distance => its interest area (
Tower's Interest
- defined by that tower) is added to the player's interest and all objects in that area will be replicated. - The other tower outside of player's view is not included and objects in that area won't be replicated.
Player Interest View
- Special type of interest provider (derived from
InterestProvider
class) that is reserved for players - Input Authority must be valid. - Provides current position of the player and his view/camera. These information are essential for filtering which player is interested in which
InterestProvider
. - There might be more views per player spawned at the same time, but only one can be active - registered in
PlayerInterestManager.InterestView
. - This component is typically added to the player character prefab and represents his default view, for example cones that match camera frustum.
- Automatically registered to
GlobalInterestManager
and available for filtering.
Following image shows PlayerInterestView
on player prefab with references to near and far cones (interest shapes), which cover camera frustum (near cone) and increased visibility towards center of the screen (far cone):
Following image explains usage of PlayerInterestView
:
- In the first case the
Player Interest Manager
points to leftPlayer Interest View
. The player uses interest defined by that view. - In the second case the
Player Interest Manager
switched active interest view (PlayerInterestManager.InterestView
property) to the right one and started using interest of that view. - This makes features like spectator or switching between multiple characters (one active at a time) very easy to implement from interest management perspective.
Player Interest Manager
- Main component that drives evaluation of interest for a specific player - Input Authority must be valid.
- There is always exactly one
PlayerInterestManager
instance per player. - Holds reference to active
PlayerInterestView
. - Automatically registered to
GlobalInterestManager
and available for filtering. - Provides runtime information in inspector and scene view (gizmos).
- This component is typically on the same object as
PlayerInterestView
. - In more advanced cases this component can be added to a special player object - different from character object(s).
PlayerInterestView
which resides on character object is then registered dynamically from code at runtime.
Global Interest Manager
- Global manager (singleton) which resides on NetworkRunner.
- Stores references and provides access to Player Interest Managers, Player Interest Views and global Interest Providers.
Interest Cells
The player's interest is built by combination of common geometric shapes - sphere, box, cone. However Fusion's interest system works internally with a 3D grid of Interest Cells.
Converting interest shapes to cells produces a side effect - the actual area replicated to client is always bigger than area defined by shapes.
Let's compare area covered by cone shapes (representing first person view) and resulting interest cells:
You can see that the area replicated to a client (green boxes) is much bigger than what was designed with cones.
This difference can be reduced by lowering cell size of Fusion's interest system.
In first case (Cell Size = 32m) the resulting volume synchronized equals to 917 504 m3. In second case (Cell Size = 16m) the resulting volume synchronized equals to 327 680 m3 which is 65% less and may have some impact on network traffic. On the other side, CPU must process more cells.
Performance
Generally it is hard to tell what settings and shapes should be used, this must be fine tuned specifically for each game to get best results.
Following factors come into play:
- CPU budget.
- Overall map size.
- Density of networked objects.
- Environment design - objects blocking player's view.
- Number of global interest providers.
- Player count.
- ...
Lowering cell size better reflects designed shapes and generally reduces network traffic (replicated less objects outside the player's view), but requires more CPU power.
The Interest Management however provides ways to optimize that:
- Interest cells evaluated for an Interest Shape are automatically cached and reused if the shape properties remain static (position, radius, ...). Full evaluation is executed on demand.
- Player Interest Manager supports interlaced evaluation by overriding
bool CanUpdatePlayerInterest()
. This can be used to defer evaluation until the player moves by X, rotates by Y or to split execution with other subsystems between even/odd ticks. - When the scene design is complete, it can be post-processed to optimize specific areas with well defined visibility. However this process requires more effort.