using Unity.Burst; using Unity.Entities; 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() { var time = SystemAPI.GetSingleton(); foreach (var (playerInputs, player) in SystemAPI.Query, FirstPersonPlayer>().WithAll()) { playerInputs.ValueRW.MoveInput = new float2 { x = (Input.GetKey(KeyCode.D) ? 1f : 0f) + (Input.GetKey(KeyCode.A) ? -1f : 0f), y = (Input.GetKey(KeyCode.W) ? 1f : 0f) + (Input.GetKey(KeyCode.S) ? -1f : 0f), }; InputDeltaUtilities.AddInputDelta(ref playerInputs.ValueRW.LookInput.x, Input.GetAxis("Mouse X")); InputDeltaUtilities.AddInputDelta(ref playerInputs.ValueRW.LookInput.y, Input.GetAxis("Mouse Y")); playerInputs.ValueRW.JumpPressed = default; if (Input.GetKeyDown(KeyCode.Space)) { playerInputs.ValueRW.JumpPressed.Set(); } } } } /// /// 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); } } } } /// /// 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 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); } } } }