Architecture
Player
The main Player
script handles essential functionalities such as input processing for movement and weapon control. It also determines the visibility of the correct player visual representation, toggling between first-person visual for local player (just hands with weapons) and third-person visual for other players that the local player sees (full body characters). Third-person animations are also controlled within this script.
Player input is handled by the PlayerInput
class, which accumulates input from devices (keyboard/mouse). The accumulated input is then consumed via the standard Fusion OnInput
callback.
Player health is stored in the Health
script. During gameplay, the player has a short period of immortality after spawning. Immortality is immediately stopped if the player fires from a weapon.
Footsteps in the Simple FPS are audible to all players, with the local player hearing their own footsteps slightly quieter.
SimpleKCC
(simple kinematic character controller) component resolves player movement and collisions. For more information please refer to the Simple KCC.
BodyHitbox
, a child of the standard Fusion Hitbox
component, is utilized to implement hitboxes with different damage modifiers for various body parts. For example, the head receives double damage, while the legs receive reduced damage. It's worth noting that the player hitboxes' positions are not influenced by animations for simplicity, and they are set up in a static pose that represents the most common player pose - holding a weapon.
For more information about animations in Fusion please refer to the Animation page in Fusion Manual and Animations technical sample. Note these samples are built with Fusion V1.
Weapons
The Weapons
script handles the general functionality of weapons in the game, holding references to all player weapons and allowing actions such as firing and reloading. All weapons are already included in the player prefab hierarchy, which is a straightforward approach when only a few weapons are present in the game.
The Simple FPS sample incorporates hitscan weapons, which fire a raycast with a specified maximum distance, allowing for immediate hit evaluation. Although projectiles do not physically travel over time, the sample employs a dummy projectile visual (handled by ProjectileVisual
script) that creates the illusion of travel through a fast yellow bullet with a trail. This trail accurately represents the direction and endpoint of the raycast.
For each projectile shot, a small data structure ProjectileData
is stored in an array within the Weapon
script. This array is networked and functions as a circular data buffer, meaning that when the end of the array is reached, projectiles are stored from the beginning again. Using this array, projectiles are fired on all clients, ensuring efficient projectile networking.
C#
private struct ProjectileData : INetworkStruct
{
public Vector3 HitPosition;
public Vector3 HitNormal;
public NetworkBool ShowHitEffect;
}
For a more in-depth understanding of projectiles and their networking, a comprehensive exploration can be found in the Projectile Essentials and Projectile Advanced samples. Note these samples are built with Fusion V1.
Pickups
There are two types of pickups in the sample: weapon pickup and health pickup. Both pickups are automatically collected when players walk over them. The HealthPickup
instantly heals players by a specified amount, restoring their health. The WeaponPickup
grants the player a new weapon or refills their ammunition if the player has already acquired that particular weapon.
Gameplay
The Gameplay
script serves as the central script of the game, handling various aspects of the gameplay experience in the Simple FPS. It is responsible for player spawning, calculating player scores, and managing the transitions between different gameplay states.
The gameplay mode in Simple FPS is a classic deathmatch, where players engage in combat to eliminate each other. Upon elimination, players respawn after a certain amount of time after death. The match concludes when the time runs out, and the player with the highest number of kills emerges as the winner.
The gameplay system operates through several states, including Skirmish
, Running
, and Finished
. In the Skirmish
state, a solo player can freely explore the arena without any time constraints. Once a second player connects to the game, the gameplay switches to the Running
state, and the match timer starts. Finally, the Finished
state is reached when the match concludes, and the results are displayed.
Connected players are managed by the Gameplay
script using a players data dictionary (replicated to all players). Within this dictionary, each player is associated with a PlayerData
data structure that holds vital information about the player. PlayerData
includes details such as the player's nickname, the number of kills and deaths they have accumulated, and their current status (whether they are alive or not).
C#
public struct PlayerData : INetworkStruct
{
[Networked, Capacity(24)]
public string Nickname { get => default; set {} }
public PlayerRef PlayerRef;
public int Kills;
public int Deaths;
public int LastKillTick;
public int StatisticPosition;
public bool IsAlive;
public bool IsConnected;
}
The PlayerData
data structure allows for efficient tracking of players and their statistics throughout the gameplay experience.
UI
The user interface in the Simple FPS is handled in a straightforward manner, without relying on any specific UI framework. The main script responsible for UI management is the GameUI
script. It enables the appropriate UI game objects that should be visible during gameplay. Additionally, the GameUI
script maintains references to other UI elements and updates the player UI when a player is spawned.
In addition to the general UI handling, the game features gameplay announcements that provide important feedback to the players. These announcements, such as "Lead Lost" or "Lead Taken," are managed by the UIGameplayInfo
script, which is responsible for the gameplay info panel. The script enables specific announcement game objects based on changes in the players' statistics, ensuring that relevant messages are displayed to the players at the appropriate times.
The UI implementation in Simple FPS focuses on simplicity and functionality, ensuring that players receive the necessary information without the need for a complex UI framework.
Back to top