### Client Game Setup System (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-thirdperson.md The ClientGameSetupSystem is intended for client-side simulation and thin client simulation. Its purpose is to handle the initialization and setup of game entities on the client, likely in response to server-initiated events or configurations. ```cs using Unity.Burst; using Unity.Entities; [BurstCompile] [WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ThinClientSimulation)] public partial struct ClientGameSetupSystem : ISystem { } ``` -------------------------------- ### Server Game Setup System (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-thirdperson.md The ServerGameSetupSystem handles the server-side logic for spawning and configuring character, player, and camera prefabs when a client requests to join. It uses EntityCommandBuffer for efficient entity manipulation and NetCode for network communication. ```cs using Unity.Burst; using Unity.Entities; using Unity.NetCode; using Unity.Mathematics; public struct ClientJoinRequest : IRpcCommand { } public struct LocalInitialized : IComponentData { } [BurstCompile] [WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)] public partial struct ServerGameSetupSystem : ISystem { private Unity.Mathematics.Random _random; [BurstCompile] void OnCreate(ref SystemState state) { _random = Random.CreateFromIndex(0); } [BurstCompile] void OnUpdate(ref SystemState state) { if (SystemAPI.HasSingleton()) { EntityCommandBuffer ecb = SystemAPI.GetSingletonRW().ValueRW.CreateCommandBuffer(state.WorldUnmanaged); GameSetup gameSetup = SystemAPI.GetSingleton(); foreach (var (receiveRPC, joinRequest, entity) in SystemAPI.Query().WithEntityAccess()) { Entity characterEntity = ecb.Instantiate(gameSetup.CharacterPrefab); Entity playerEntity = ecb.Instantiate(gameSetup.PlayerPrefab); Entity cameraEntity = ecb.Instantiate(gameSetup.CameraPrefab); ecb.AppendToBuffer(receiveRPC.SourceConnection, new LinkedEntityGroup { Value = characterEntity }); ecb.AppendToBuffer(receiveRPC.SourceConnection, new LinkedEntityGroup { Value = playerEntity }); ecb.AppendToBuffer(receiveRPC.SourceConnection, new LinkedEntityGroup { Value = cameraEntity }); int clientConnectionId = SystemAPI.GetComponent(receiveRPC.SourceConnection).Value; ecb.SetComponent(characterEntity, new GhostOwner { NetworkId = clientConnectionId }); ecb.SetComponent(playerEntity, new GhostOwner { NetworkId = clientConnectionId }); ecb.SetComponent(cameraEntity, new GhostOwner { NetworkId = clientConnectionId }); ThirdPersonPlayer player = SystemAPI.GetComponent(gameSetup.PlayerPrefab); player.ControlledCharacter = characterEntity; player.ControlledCamera = cameraEntity; ecb.SetComponent(playerEntity, player); ecb.SetComponent(characterEntity, LocalTransform.FromPosition(_random.NextFloat3(new float3(-5f,0f,-5f), new float3(5f,0f,5f)))); ecb.AddComponent(receiveRPC.SourceConnection); ecb.DestroyEntity(entity); } } } } ``` -------------------------------- ### Unity Scene Initialization System Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/basic.md The SceneInitializationSystem initializes the game by looking for a SceneInitialization singleton. If found, it spawns player, character, and camera prefabs, establishing necessary references for scene setup. ```C# public class SceneInitializationSystem : SystemBase { protected override void OnUpdate() { // Logic to find SceneInitialization singleton and spawn prefabs } } ``` -------------------------------- ### GameSetup Component (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-thirdperson.md Defines the GameSetup component, which holds references to character, player, and camera prefabs. This component is used to store essential entities needed for game setup and is marked as serializable for inspector use. ```cs using System; using Unity.Entities; [Serializable] public struct GameSetup : IComponentData { public Entity CharacterPrefab; public Entity PlayerPrefab; public Entity CameraPrefab; } ``` -------------------------------- ### Build Game in Unity Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/OnlineFPSSample/building-playing.md This snippet describes the process of building the OnlineFPS sample project for online play. It guides users to the 'File > Build Profiles' menu within the Unity editor to create a playable build, noting that a 'Windows' build profile is pre-configured. ```Unity Editor File > Build Profiles ``` -------------------------------- ### Unity Orbit Camera System Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/basic.md The OrbitCameraSystem manages camera handling, providing functionality similar to the third-person standard character's camera setup. It is responsible for the camera's behavior and positioning in the scene. ```C# public class OrbitCameraSystem : SystemBase { protected override void OnUpdate() { // Camera handling logic } } ``` -------------------------------- ### GameManager Initialization and Session Creation Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/OnlineFPSSample/game-management.md The GameManager is a MonoBehaviour that initializes the game and manages network sessions. It's responsible for setting up UI state, creating local or networked GameSessions, and loading GameResources. It also handles starting the game directly from scenes if an AutoNetcodePlayMode component is present. ```C# public class GameManager : MonoBehaviour { protected virtual void OnInitialize() { // Initialize game UI state // Create local or networked GameSession // Load GameResources subscene // Detect AutoNetcodePlayMode for direct scene play } } ``` -------------------------------- ### ServerGameSetupSystem (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-firstperson.md The ServerGameSetupSystem handles spawning character and player prefabs when a client requests to join. It instantiates prefabs, links them to the client's connection, sets ownership, configures player-character relationships, positions the character, and marks the client as in-game. Requires Unity.Burst, Unity.Entities, Unity.NetCode, and Unity.Mathematics namespaces. ```cs using Unity.Burst; using Unity.Entities; using Unity.NetCode; using Unity.Mathematics; public struct ClientJoinRequest : IRpcCommand { } public struct LocalInitialized : IComponentData { } [BurstCompile] [WorldSystemFilter(WorldSystemFilterFlags.ServerSimulation)] public partial struct ServerGameSetupSystem : ISystem { private Unity.Mathematics.Random _random; [BurstCompile] void OnCreate(ref SystemState state) { _random = Random.CreateFromIndex(0); } [BurstCompile] void OnUpdate(ref SystemState state) { if (SystemAPI.HasSingleton()) { EntityCommandBuffer ecb = SystemAPI.GetSingletonRW().ValueRW.CreateCommandBuffer(state.WorldUnmanaged); GameSetup gameSetup = SystemAPI.GetSingleton(); foreach (var (recieveRPC, joinRequest, entity) in SystemAPI.Query().WithEntityAccess()) { Entity characterEntity = ecb.Instantiate(gameSetup.CharacterPrefab); Entity playerEntity = ecb.Instantiate(gameSetup.PlayerPrefab); ecb.AppendToBuffer(recieveRPC.SourceConnection, new LinkedEntityGroup { Value = characterEntity }); ecb.AppendToBuffer(recieveRPC.SourceConnection, new LinkedEntityGroup { Value = playerEntity }); int clientConnectionId = SystemAPI.GetComponent(recieveRPC.SourceConnection).Value; ecb.SetComponent(characterEntity, new GhostOwner { NetworkId = clientConnectionId }); ecb.SetComponent(playerEntity, new GhostOwner { NetworkId = clientConnectionId }); FirstPersonPlayer player = SystemAPI.GetComponent(gameSetup.PlayerPrefab); player.ControlledCharacter = characterEntity; ecb.SetComponent(playerEntity, player); ecb.SetComponent(characterEntity, LocalTransform.FromPosition(_random.NextFloat3(new float3(-5f,0f,-5f), new float3(5f,0f,5f)))); ecb.AddComponent(recieveRPC.SourceConnection); ecb.DestroyEntity(entity); } } } } ``` -------------------------------- ### ClientGameSetupSystem (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-firstperson.md The ClientGameSetupSystem is responsible for initiating the game join process on the client side. It queries for connections that are not yet in the game stream and sends a join request to the server. Requires Unity.Burst, Unity.Entities, and Unity.NetCode namespaces. ```cs using Unity.Burst; using Unity.Entities; using Unity.NetCode; [BurstCompile] [WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation | WorldSystemFilterFlags.ThinClientSimulation)] public partial struct ClientGameSetupSystem : ISystem { [BurstCompile] void OnUpdate(ref SystemState state) { EntityCommandBuffer ecb = SystemAPI.GetSingletonRW().ValueRW.CreateCommandBuffer(state.WorldUnmanaged); foreach (var (netId, entity) in SystemAPI.Query().WithNone().WithEntityAccess()) { // Mark our connection as ready to go in game ``` -------------------------------- ### GameSetup Component (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-firstperson.md The GameSetup component holds references to character and player prefabs, intended for use with Unity's DOTS. It requires the Unity.Entities and System namespaces. ```cs using System; using Unity.Entities; [Serializable] public struct GameSetup : IComponentData { public Entity CharacterPrefab; public Entity PlayerPrefab; } ``` -------------------------------- ### Assign Weapon to Character in Unity Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/OnlineFPSSample/weapons.md The ServerGameSystem spawns weapons and assigns them as the character's ActiveWeapon. The ActiveWeaponSystem then handles setup, including parenting the weapon to the character's view transform and setting the shot raycast origin. ```C# ServerGameSystem.HandleCharacters ActiveWeaponSystem ``` -------------------------------- ### GameSetupAuthoring Script (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-thirdperson.md The GameSetupAuthoring script allows developers to assign character, player, and camera prefabs in the Unity inspector. It includes a Baker class that converts these GameObject references into Entity references during the baking process, creating a GameSetup component. ```cs using Unity.Entities; using UnityEngine; public class GameSetupAuthoring : MonoBehaviour { public GameObject CharacterPrefab; public GameObject PlayerPrefab; public GameObject CameraPrefab; class Baker : Baker { public override void Bake(GameSetupAuthoring authoring) { AddComponent(GetEntity(authoring, TransformUsageFlags.None), new GameSetup { CharacterPrefab = GetEntity(authoring.CharacterPrefab, TransformUsageFlags.None), PlayerPrefab = GetEntity(authoring.PlayerPrefab, TransformUsageFlags.None), CameraPrefab = GetEntity(authoring.CameraPrefab, TransformUsageFlags.None) }); } } } ``` -------------------------------- ### Get Input Delta with Wrap-around Handling (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-inpututil.md Calculates the difference between a current and previous input value, correctly handling cases where the input may have wrapped around its maximum value. This ensures accurate delta calculations for cyclical inputs. Supports both single float and float2 inputs. ```cs using Unity.Mathematics; public static class InputDeltaUtilities { public const float InputWrapAroundValue = 2000f; public static float GetInputDelta(float currentValue, float previousValue) { float delta = currentValue - previousValue; // When delta is very large, consider that the input has wrapped around if(math.abs(delta) > (InputWrapAroundValue * 0.5f)) { delta += (math.sign(previousValue - currentValue) * InputWrapAroundValue); } return delta; } public static float2 GetInputDelta(float2 currentValue, float2 previousValue) { float2 delta = currentValue - previousValue; // When delta is very large, consider that the input has wrapped around if(math.abs(delta.x) > (InputWrapAroundValue * 0.5f)) { delta.x += (math.sign(previousValue.x - currentValue.x) * InputWrapAroundValue); } if(math.abs(delta.y) > (InputWrapAroundValue * 0.5f)) { delta.y += (math.sign(previousValue.y - currentValue.y) * InputWrapAroundValue); } return delta; } } ``` -------------------------------- ### MovingPlatform System (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-movingplatforms.md The DOTS system that updates the movement of platforms. It queries for entities with `MovingPlatform`, `PhysicsVelocity`, `PhysicsMass`, and `LocalTransform` components. It calculates target positions and rotations based on time and component data, then applies physics velocity to move the platform kinematically. ```C# using Unity.Entities; using Unity.Mathematics; using Unity.Physics; using Unity.Physics.Systems; using Unity.Transforms; [UpdateInGroup(typeof(BeforePhysicsSystemGroup))] public partial class MovingPlatformSystem : SystemBase { protected override void OnUpdate() { float deltaTime = SystemAPI.Time.DeltaTime; float invDeltaTime = 1f / deltaTime; float time = (float)World.Time.ElapsedTime; foreach(var (movingPlatform, physicsVelocity, physicsMass, localTransform, entity) in SystemAPI.Query, RefRW, PhysicsMass, LocalTransform>().WithEntityAccess()) { if(!movingPlatform.ValueRW.IsInitialized) { // Remember initial pos/rot, because our calculations depend on them movingPlatform.ValueRW.OriginalPosition = localTransform.Position; movingPlatform.ValueRW.OriginalRotation = localTransform.Rotation; movingPlatform.ValueRW.IsInitialized = true; } float3 targetPos = movingPlatform.ValueRW.OriginalPosition + (math.normalizesafe(movingPlatform.ValueRW.TranslationAxis) * math.sin(time * movingPlatform.ValueRW.TranslationSpeed) * movingPlatform.ValueRW.TranslationAmplitude); quaternion rotationFromMovement = quaternion.Euler(math.normalizesafe(movingPlatform.ValueRW.RotationAxis) * movingPlatform.ValueRW.RotationSpeed * time); quaternion targetRot = math.mul(rotationFromMovement, movingPlatform.ValueRW.OriginalRotation); // Move with velocity physicsVelocity.ValueRW = PhysicsVelocity.CalculateVelocityToTarget(in physicsMass, localTransform.Position, localTransform.Rotation, new RigidTransform(targetRot, targetPos), invDeltaTime); } } } ``` -------------------------------- ### Initialize Network Stream and Send Join Request (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-firstperson.md Initializes a network stream for a given entity and sends an RPC command to the server requesting to join the game. This involves creating an entity for the RPC and adding components for the join request and target connection. ```csharp ecb.AddComponent(entity, new NetworkStreamInGame()); // Send an RPC that asks the server if we can join Entity joinRPC = ecb.CreateEntity(); ecb.AddComponent(joinRPC, new ClientJoinRequest()); ecb.AddComponent(joinRPC, new SendRpcCommandRequest { TargetConnection = entity }); ``` -------------------------------- ### GameSetupAuthoring Component (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-firstperson.md The GameSetupAuthoring component allows developers to assign character and player prefabs in the Unity inspector. It uses a Baker class to convert these GameObjects into DOTS entities during the baking process. Requires Unity.Entities and UnityEngine namespaces. ```cs using Unity.Entities; using UnityEngine; public class GameSetupAuthoring : MonoBehaviour { public GameObject CharacterPrefab; public GameObject PlayerPrefab; class Baker : Baker { public override void Bake(GameSetupAuthoring authoring) { AddComponent(GetEntity(authoring, TransformUsageFlags.None), new GameSetup { CharacterPrefab = GetEntity(authoring.CharacterPrefab, TransformUsageFlags.None), PlayerPrefab = GetEntity(authoring.PlayerPrefab, TransformUsageFlags.None), }); } } } ``` -------------------------------- ### Create Jump Pad Authoring Component (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-jumppad.md Provides the authoring component for the JumpPad, allowing the jump force to be set in the Unity Editor. It includes a Baker class to convert the authoring component to the DOTS component. ```csharp using UnityEngine; using Unity.Entities; public class JumpPadAuthoring : MonoBehaviour { public float JumpForce; class Baker : Baker { public override void Bake(JumpPadAuthoring authoring) { AddComponent(new JumpPad { JumpForce = authoring.JumpForce }); } } } ``` -------------------------------- ### Scene Initialization System Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/platformer.md Responsible for game initialization in the Platformer Sample. It spawns Player, Character, and Camera prefabs based on the SceneInitialization singleton. ```C# `SceneInitializationSystem` is responsible game initialization. It looks for the presence of a `SceneInitialization` singleton in the world (it is created by a `SceneInitialization` authoring object in the subscene). If present, it spawns the Player, Character, and Camera prefabs that are stored in the `SceneInitialization` singleton, and sets up references between these. This is how the character gets set-up in the scene when pressing Play. ``` -------------------------------- ### MovingPlatform Authoring Script (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-movingplatforms.md The authoring script for the moving platform, responsible for baking the `MovingPlatform` component into the entity. It inherits from `MonoBehaviour` and uses a `Baker` class to convert `MonoBehaviour` data to `IComponentData` for DOTS. ```C# using Unity.Entities; using UnityEngine; public class MovingPlatformAuthoring : MonoBehaviour { public MovingPlatform MovingPlatform; public class Baker : Baker { public override void Bake(MovingPlatformAuthoring authoring) { AddComponent(authoring.MovingPlatform); } } } ``` -------------------------------- ### Implement Jump Pad System (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-jumppad.md Implements the JumpPadSystem to handle trigger events and apply jump forces to characters. It queries for JumpPad components and StatefulTriggerEvents, modifying the KinematicCharacterBody component. ```csharp using Unity.Entities; using Unity.Mathematics; using Unity.Physics.Stateful; using Unity.Physics.Systems; using Unity.CharacterController; // Update after events processing system [UpdateInGroup(typeof(AfterPhysicsSystemGroup))] [UpdateBefore(typeof(KinematicCharacterPhysicsUpdateGroup))] public partial class JumpPadSystem : SystemBase { protected override void OnUpdate() { // Iterate on all jump pads with trigger event buffers foreach (var (jumpPad, triggerEventsBuffer, entity) in SystemAPI.Query>().WithEntityAccess()) { // Go through each trigger event of the jump pad... for (int i = 0; i < triggerEventsBuffer.Length; i++) { StatefulTriggerEvent triggerEvent = triggerEventsBuffer[i]; Entity otherEntity = triggerEvent.GetOtherEntity(entity); // If a character has entered the trigger... if (triggerEvent.State == StatefulEventState.Enter && SystemAPI.HasComponent(otherEntity)) { KinematicCharacterBody characterBody = SystemAPI.GetComponent(otherEntity); // Cancel out character velocity in the jump force's direction // (this helps make the character jump up even if it is falling down on the jump pad at high speed) characterBody.RelativeVelocity = MathUtilities.ProjectOnPlane(characterBody.RelativeVelocity, math.normalizesafe(jumpPad.JumpForce)); // Add the jump pad force to the character characterBody.RelativeVelocity += jumpPad.JumpForce; // Unground the character // (without this, the character would snap right back to the ground on the next frame) characterBody.IsGrounded = false; // Don't forget to write back to the component SystemAPI.SetComponent(otherEntity, characterBody); } } } } } ``` -------------------------------- ### Initialize Local Character and Camera (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-firstperson.md Handles the initialization of local character entities in Unity's ECS. It queries for characters with specific components and assigns the main camera to the character's view entity, marking the character as locally initialized. ```csharp // Handle initialization for our local character (mark main camera entity) foreach (var (character, entity) in SystemAPI.Query().WithAll().WithNone().WithEntityAccess()) { ecb.AddComponent(character.ViewEntity, new MainEntityCamera()); ecb.AddComponent(entity, new LocalInitialized()); } ``` -------------------------------- ### MovingPlatform Component (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-movingplatforms.md Defines the data structure for a moving platform, including translation and rotation parameters, and initialization state. This component is used by the DOTS system to control the platform's movement. ```C# using System; using Unity.Entities; using Unity.Mathematics; using UnityEngine; [Serializable] public struct MovingPlatform : IComponentData { public float3 TranslationAxis; public float TranslationAmplitude; public float TranslationSpeed; public float3 RotationAxis; public float RotationSpeed; [HideInInspector] public bool IsInitialized; [HideInInspector] public float3 OriginalPosition; [HideInInspector] public quaternion OriginalRotation; } ``` -------------------------------- ### Orbit Camera System Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/platformer.md Handles camera logic in the Platformer Sample, including smooth transitions between different camera targets and parameters based on the character's state. It uses Unity's new input system. ```C# Camera handling is mostly the same as in the third-person standard character. It is handled in `OrbitCameraSystem`. The main addition in this sample is the management of smooth transitions between different camera targets & parameters that are specific to which state our character is in. This is all handled in `OrbitCameraSystem`, under the `// Camera target handling` comment. ``` -------------------------------- ### Unity Character Controller OnUpdate Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-gamesetup-thirdperson.md This C# code snippet, designed for Unity's ECS, handles the update logic for character controllers. It manages joining a network game by sending a client request and initializes the local character's camera. It uses BurstCompile for performance optimization and requires Unity's Netcode for GameObjects and ECS packages. ```csharp [BurstCompile] void OnUpdate(ref SystemState state) { EntityCommandBuffer ecb = SystemAPI.GetSingletonRW().ValueRW.CreateCommandBuffer(state.WorldUnmanaged); // Send a join request to the server if we haven't done so yet foreach (var (netId, entity) in SystemAPI.Query().WithNone().WithEntityAccess()) { // Mark our connection as ready to go in game ecb.AddComponent(entity, new NetworkStreamInGame()); // Send an RPC that asks the server if we can join Entity joinRPC = ecb.CreateEntity(); ecb.AddComponent(joinRPC, new ClientJoinRequest()); ecb.AddComponent(joinRPC, new SendRpcCommandRequest { TargetConnection = entity }); } // Handle initialization for our local character camera (mark main camera entity) foreach (var (camera, entity) in SystemAPI.Query().WithAll().WithNone().WithEntityAccess()) { ecb.AddComponent(entity, new MainEntityCamera()); ecb.AddComponent(entity, new LocalInitialized()); } } ``` -------------------------------- ### Query Sprint Input in ThirdPersonPlayerInputsSystem Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-sprint.md Updates the `ThirdPersonPlayerInputsSystem` to query the state of the left shift key from the input system and store it in the `SprintHeld` field of the `ThirdPersonPlayerInputs` component. ```C# using Unity.Entities; using Unity.Networking.Transport; using UnityEngine.InputSystem; public partial class ThirdPersonPlayerInputsSystem : SystemBase { // (...) protected override void OnUpdate() { foreach (var (playerInputs, player) in SystemAPI.Query, ThirdPersonPlayer>()) { // (...) playerInputs.ValueRW.SprintHeld = Keyboard.current.leftShiftKey.isPressed; } } } ``` -------------------------------- ### Define Jump Pad Component (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-jumppad.md Defines the JumpPad component data, storing the jump force to be applied. This is a simple struct implementing IComponentData for use with Unity's DOTS. ```csharp using Unity.Entities; using Unity.Mathematics; public struct JumpPad : IComponentData { public float3 JumpForce; } ``` -------------------------------- ### ClientGameSystem Responsibilities Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/OnlineFPSSample/game-management.md The ClientGameSystem operates in the client world and manages client-side logic. It handles sending join requests to the server, setting up spawned character ghosts, activating the respawn screen upon local character death, and returning to the menu on connection timeout. ```C# public class ClientGameSystem : SystemBase { protected override void OnUpdate() { // HandleSendJoinRequest() // HandleWaitForJoinConfirmation() // HandleCharacterSetup() // HandleRespawnScreen() // HandleDisconnect() } } ``` -------------------------------- ### Unity C# Orbit Camera Simulation System Configuration Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-prediction-thirdperson.md This C# code configures the `OrbitCameraSimulationSystem` in Unity's DOTS. It dictates that the system operates within the `PredictedSimulationSystemGroup` and executes after several other systems, including `PredictedFixedStepSimulationSystemGroup`, `ThirdPersonPlayerVariableStepControlSystem`, and `ThirdPersonCharacterVariableUpdateSystem`. This ordering ensures the camera simulation correctly follows character and input updates. ```C# [UpdateInGroup(typeof(PredictedSimulationSystemGroup))] [UpdateAfter(typeof(PredictedFixedStepSimulationSystemGroup))] [UpdateAfter(typeof(ThirdPersonPlayerVariableStepControlSystem))] [UpdateAfter(typeof(ThirdPersonCharacterVariableUpdateSystem))] [BurstCompile] public partial struct OrbitCameraSimulationSystem : ISystem { // ... } ``` -------------------------------- ### Implement Variable Step Control System (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-prediction-firstperson.md This system applies player inputs that require variable rate updates, such as look rotation. It runs in the PredictedSimulationSystemGroup and uses InputDeltaUtilities to calculate and apply look deltas. ```cs using Unity.Burst; using Unity.Collections; using Unity.Entities; using Unity.Jobs; using Unity.Mathematics; using Unity.Transforms; using UnityEngine; using Unity.CharacterController; using Unity.NetCode; /// /// Apply inputs that need to be read at a variable rate /// [UpdateInGroup(typeof(PredictedSimulationSystemGroup))] [UpdateAfter(typeof(PredictedFixedStepSimulationSystemGroup))] [BurstCompile] public partial struct FirstPersonPlayerVariableStepControlSystem : ISystem { [BurstCompile] public void OnCreate(ref SystemState state) { state.RequireForUpdate(); state.RequireForUpdate(SystemAPI.QueryBuilder().WithAll().Build()); } [BurstCompile] public void OnUpdate(ref SystemState state) { foreach (var (playerInputs, playerNetworkInput, player) in SystemAPI.Query, FirstPersonPlayer>().WithAll()) { // Compute input deltas, compared to last known values float2 lookInputDelta = InputDeltaUtilities.GetInputDelta( playerInputs.LookInput, playerNetworkInput.ValueRO.LastProcessedLookInput); playerNetworkInput.ValueRW.LastProcessedLookInput = playerInputs.LookInput; if (SystemAPI.HasComponent(player.ControlledCharacter)) { FirstPersonCharacterControl characterControl = SystemAPI.GetComponent(player.ControlledCharacter); characterControl.LookDegreesDelta = lookInputDelta; SystemAPI.SetComponent(player.ControlledCharacter, characterControl); } } } } ``` -------------------------------- ### Implement Client Input Gathering System (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-prediction-firstperson.md This system runs on clients within the GhostInputSystemGroup to gather player inputs from keyboard and mouse. It updates movement, look delta, and jump events, synchronizing them via Netcode. ```cs using Unity.Burst; using Unity.Collections; using Unity.Entities; using Unity.Jobs; using Unity.Mathematics; using Unity.Transforms; using UnityEngine; using Unity.CharacterController; using Unity.NetCode; [UpdateInGroup(typeof(GhostInputSystemGroup))] [WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation)] public partial class FirstPersonPlayerInputsSystem : SystemBase { protected override void OnCreate() { RequireForUpdate(); RequireForUpdate(SystemAPI.QueryBuilder().WithAll().Build()); } protected override void OnUpdate() { foreach (var (playerInputs, player) in SystemAPI.Query, FirstPersonPlayer>().WithAll()) { playerInputs.ValueRW.MoveInput = new float2 { x = (Keyboard.current.dKey.isPressed ? 1f : 0f) + (Keyboard.current.aKey.isPressed ? -1f : 0f), y = (Keyboard.current.wKey.isPressed ? 1f : 0f) + (Keyboard.current.sKey.isPressed ? -1f : 0f), }; InputDeltaUtilities.AddInputDelta(ref playerInputs.ValueRW.LookInput, Mouse.current.delta.ReadValue()); playerInputs.ValueRW.JumpPressed = default; if (Keyboard.current.spaceKey.wasPressedThisFrame) { playerInputs.ValueRW.JumpPressed.Set(); } } } } ``` -------------------------------- ### Unity StressTest Manager for Runtime Options Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/stresstest.md The StressTestManager handles the sample's UI and runtime logic, including spawning characters, selecting environments, and toggling performance-related features like multithreading, physics steps, and rendering. ```Unity C# public class StressTestManager : MonoBehaviour { // UI elements and logic for spawning characters and managing settings public void SpawnCharacters(int count) { // Spawning logic } public void SetEnvironment(GameObject prefab) { // Environment switching logic } public void ToggleMultithreading(bool enabled) { // Multithreading toggle logic } // ... other toggles for Physics Step, Rendering, SlopeChanges, etc. } ``` -------------------------------- ### Author CharacterFrictionSurface Component (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-frictionsurface.md Provides the authoring component for CharacterFrictionSurface, allowing it to be added to GameObjects in the Unity editor. It includes a Baker class to convert the authoring component into the ECS component during the baking process. ```C# using UnityEngine; using Unity.Entities; public class CharacterFrictionSurfaceAuthoring : MonoBehaviour { public float VelocityFactor; class Baker : Baker { public override void Bake(CharacterFrictionSurfaceAuthoring authoring) { AddComponent(new CharacterFrictionSurface { VelocityFactor = authoring.VelocityFactor }); } } } ``` -------------------------------- ### Unity Basic Player Input System Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/basic.md This system handles player input using Unity's new input system package. It polls input data within the BasicPlayerInputsSystem, differing from the standard character's use of the built-in input system. ```C# public class BasicPlayerInputsSystem : SystemBase { protected override void OnUpdate() { // Logic to poll input from Unity's new input system package } } ``` -------------------------------- ### Unity Basic Character Aspect Physics Interactions Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/basic.md The BasicCharacterAspect in Unity allows for custom physics interactions. It includes logic to ignore grounding, collisions, and step handling on physics bodies with specific tags, and modify mass ratios and velocity projection against dynamic physics bodies. ```C# public struct BasicCharacterAspect : IAspect { // Properties and methods for physics interactions // e.g., IsGroundedOnHit, CanCollideWithHit, OverrideDynamicHitMasses } ``` -------------------------------- ### Synchronize FirstPersonCharacterComponent Ghost Component Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-ghostfields-firstperson.md This C# code snippet shows how to make the `FirstPersonCharacterComponent` a ghost component and synchronize its `ViewPitchDegrees` field. This ensures that the character's view pitch is correctly replicated to clients. ```csharp using Unity.Entities; [GhostComponent] public struct FirstPersonCharacterComponent : IComponentData { // ... [GhostField] public float ViewPitchDegrees; } ``` -------------------------------- ### Unity Netcode Auto-Connect Bootstrap Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters.md This C# script extends Unity's ClientServerBootstrap to automatically connect clients to the server with a predefined port. It's useful for simplifying testing in Netcode projects. ```csharp using Unity.NetCode; public class AutoConnectBootstrap : ClientServerBootstrap { public override bool Initialize(string defaultWorldName) { AutoConnectPort = 7979; CreateDefaultClientServerWorlds(); return true; } } ``` -------------------------------- ### Platformer Character Animation Authoring Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/platformer.md Defines animation clip indexes for the mecanim animation controller in the Platformer Sample. This script is part of the hybrid GameObject/ECS animation solution. ```C# PlatformerCharacterAnimationAuthoring: Defines the clip indexes of the various animation clips, as defined in the mecanim animation controller. ``` -------------------------------- ### Unity Character Controller: Step Handling Configuration Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-steps-and-slopes.md Demonstrates the configuration of step handling in Unity's Character Controller. This involves enabling step handling, setting the maximum step height a character can overcome, and defining the horizontal distance for extra raycasts to detect valid steps. ```UnityScript // Example of enabling step handling and setting parameters // CharacterController.StepHandling = true; // CharacterController.MaxStepHeight = 0.5f; // Example value in meters // CharacterController.ExtraStepsCheckDistance = 0.2f; // Example value in meters ``` -------------------------------- ### Unity C# Third Person Player Fixed Step Control System Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-prediction-thirdperson.md This C# system, designed for Unity's DOTS (Data-Oriented Technology Stack), applies player inputs at a fixed rate. It requires the `PredictedFixedStepSimulationSystemGroup` and `BurstCompile` for performance. The system queries for `ThirdPersonPlayerInputs` and `ThirdPersonPlayer` components, then updates the `ThirdPersonCharacterControl` component based on movement and jump inputs, considering camera orientation. ```C# /// /// Apply inputs that need to be read at a fixed rate. /// It is necessary to handle this as part of the fixed step group, in case your framerate is lower than the fixed step rate. /// [UpdateInGroup(typeof(PredictedFixedStepSimulationSystemGroup), OrderFirst = true)] [BurstCompile] public partial struct ThirdPersonPlayerFixedStepControlSystem : ISystem { [BurstCompile] public void OnCreate(ref SystemState state) { state.RequireForUpdate(SystemAPI.QueryBuilder().WithAll().Build()); } [BurstCompile] public void OnUpdate(ref SystemState state) { foreach (var (playerInputs, player) in SystemAPI.Query().WithAll()) { if (SystemAPI.HasComponent(player.ControlledCharacter)) { ThirdPersonCharacterControl characterControl = SystemAPI.GetComponent(player.ControlledCharacter); float3 characterUp = MathUtilities.GetUpFromRotation(SystemAPI.GetComponent(player.ControlledCharacter).Rotation); // Get camera rotation, since our movement is relative to it. quaternion cameraRotation = quaternion.identity; if (SystemAPI.HasComponent(player.ControlledCamera)) { // Camera rotation is calculated rather than gotten from transform, because this allows us to // reduce the size of the camera ghost state in a netcode prediction context. // If not using netcode prediction, we could simply get rotation from transform here instead. OrbitCamera orbitCamera = SystemAPI.GetComponent(player.ControlledCamera); cameraRotation = OrbitCameraUtilities.CalculateCameraRotation(characterUp, orbitCamera.PlanarForward, orbitCamera.PitchAngle); } float3 cameraForwardOnUpPlane = math.normalizesafe(MathUtilities.ProjectOnPlane(MathUtilities.GetForwardFromRotation(cameraRotation), characterUp)); float3 cameraRight = MathUtilities.GetRightFromRotation(cameraRotation); // Move characterControl.MoveVector = (playerInputs.MoveInput.y * cameraForwardOnUpPlane) + (playerInputs.MoveInput.x * cameraRight); characterControl.MoveVector = MathUtilities.ClampToMaxLength(characterControl.MoveVector, 1f); // Jump characterControl.Jump = playerInputs.JumpPressed.IsSet; SystemAPI.SetComponent(player.ControlledCharacter, characterControl); } } } } ``` -------------------------------- ### Ground Movement State Logic (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/PlatformerSample/CharacterStates/ground-move.md Handles regular grounded movement, jumping, sprinting, and detection of special surfaces like sticky (walkable walls) and friction (ice) surfaces. It also manages jump grace times, allowing jumps to register even if the input is slightly before landing. ```csharp public class GroundMoveState : State { // Handles regular grounded movement, jumping, sprinting, detecting "sticky surfaces" (walk on walls), and detecting "friction surfaces" (like ice). // It also deals with jumping "grace times": allowing a jump input to be pressed slightly before landing on the ground, but still allowing the jump to happen. // This is controlled by the `JumpBeforeGroundedGraceTime`. // Typically, this state is transitioned to when the character is grounded and not doing any other special action such as crouching. // This state handles adapting the character rotation to match any detected "friction surface". } ``` -------------------------------- ### First-Person Player Fixed-Step Control System (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-prediction-firstperson.md Implements first-person player control logic within a fixed-step simulation group. It processes player inputs to control character movement and jumping, utilizing Burst compilation for performance. Requires `NetworkTime` and components like `FirstPersonPlayer`, `FirstPersonPlayerInputs`, and `FirstPersonCharacterControl`. ```csharp /// [UpdateInGroup(typeof(PredictedFixedStepSimulationSystemGroup), OrderFirst = true)] [BurstCompile] public partial struct FirstPersonPlayerFixedStepControlSystem : ISystem { [BurstCompile] public void OnCreate(ref SystemState state) { state.RequireForUpdate(); state.RequireForUpdate(SystemAPI.QueryBuilder().WithAll().Build()); } [BurstCompile] public void OnUpdate(ref SystemState state) { foreach (var (playerInputs, player) in SystemAPI.Query().WithAll()) { if (SystemAPI.HasComponent(player.ControlledCharacter)) { FirstPersonCharacterControl characterControl = SystemAPI.GetComponent(player.ControlledCharacter); quaternion characterRotation = SystemAPI.GetComponent(player.ControlledCharacter).Rotation; // Move float3 characterForward = MathUtilities.GetForwardFromRotation(characterRotation); float3 characterRight = MathUtilities.GetRightFromRotation(characterRotation); characterControl.MoveVector = (playerInputs.MoveInput.y * characterForward) + (playerInputs.MoveInput.x * characterRight); characterControl.MoveVector = MathUtilities.ClampToMaxLength(characterControl.MoveVector, 1f); // Jump characterControl.Jump = playerInputs.JumpPressed.IsSet; SystemAPI.SetComponent(player.ControlledCharacter, characterControl); } } } } ``` -------------------------------- ### Prefab Weapon Simulation Job Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Samples/OnlineFPSSample/weapons.md Simulates prefab weapons by iterating through weapon entities with the `PrefabWeapon` component. For each projectile event, it spawns a projectile prefab on the server and predicted clients. ```C# public struct PrefabWeaponSimulationJob : IJobEntity { // ... other fields public void Execute(Entity entity, in PrefabWeapon prefabWeapon, in DynamicBuffer projectileEvents) { // ... projectile prefab spawning logic } } ``` -------------------------------- ### Define Networked Player Inputs (C#) Source: https://github.com/unity-technologies/charactercontrollersamples/blob/master/_Documentation/Tutorial/tutorial-netcodecharacters-prediction-firstperson.md Defines the structure for player inputs, including movement and look, and integrates Netcode's InputEvent for jump actions. This structure implements IInputComponentData for networked synchronization. ```cs using Unity.Entities; using Unity.NetCode; using Unity.Mathematics; [Serializable] public struct FirstPersonPlayerInputs : IInputComponentData { public float2 MoveInput; public float2 LookInput; public InputEvent JumpPressed; // This is now an InputEvent } ```