Progress character movement
This commit is contained in:
parent
08e27ca2f1
commit
01f38a19a1
@ -4,6 +4,7 @@ using Unity.Entities;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
using Unity.CharacterController;
|
||||
using Unity.NetCode;
|
||||
|
||||
[Serializable]
|
||||
public struct FirstPersonCharacterComponent : IComponentData
|
||||
@ -22,7 +23,7 @@ public struct FirstPersonCharacterComponent : IComponentData
|
||||
public float MaxViewAngle;
|
||||
|
||||
public Entity ViewEntity;
|
||||
public float ViewPitchDegrees;
|
||||
[GhostField] public float ViewPitchDegrees;
|
||||
public quaternion ViewLocalRotation;
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ using Unity.Physics;
|
||||
using Unity.Transforms;
|
||||
using Unity.CharacterController;
|
||||
using Unity.Burst.Intrinsics;
|
||||
using Unity.NetCode;
|
||||
|
||||
[UpdateInGroup(typeof(KinematicCharacterPhysicsUpdateGroup))]
|
||||
[BurstCompile]
|
||||
@ -72,10 +73,9 @@ public partial struct FirstPersonCharacterPhysicsUpdateSystem : ISystem
|
||||
}
|
||||
}
|
||||
|
||||
[UpdateInGroup(typeof(SimulationSystemGroup))]
|
||||
[UpdateAfter(typeof(FixedStepSimulationSystemGroup))]
|
||||
[UpdateInGroup(typeof(PredictedSimulationSystemGroup))]
|
||||
[UpdateAfter(typeof(PredictedFixedStepSimulationSystemGroup))]
|
||||
[UpdateAfter(typeof(FirstPersonPlayerVariableStepControlSystem))]
|
||||
[UpdateBefore(typeof(TransformSystemGroup))]
|
||||
[BurstCompile]
|
||||
public partial struct FirstPersonCharacterVariableUpdateSystem : ISystem
|
||||
{
|
||||
|
||||
@ -1,18 +1,26 @@
|
||||
using System;
|
||||
using Unity.Collections;
|
||||
using Unity.Entities;
|
||||
using Unity.Mathematics;
|
||||
using Unity.NetCode;
|
||||
|
||||
[Serializable]
|
||||
public struct FirstPersonPlayer : IComponentData
|
||||
{
|
||||
public Entity ControlledCharacter;
|
||||
[GhostField] public Entity ControlledCharacter;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct FirstPersonPlayerInputs : IComponentData
|
||||
public struct FirstPersonPlayerInputs : IInputComponentData
|
||||
{
|
||||
public float2 MoveInput;
|
||||
public float2 LookInput;
|
||||
public FixedInputEvent JumpPressed;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
[GhostComponent(SendTypeOptimization = GhostSendType.OnlyPredictedClients)]
|
||||
public struct FirstPersonPlayerNetworkInput : IComponentData
|
||||
{
|
||||
[GhostField()]
|
||||
public float2 LastProcessedLookInput;
|
||||
}
|
||||
@ -16,6 +16,7 @@ public class FirstPersonPlayerAuthoring : MonoBehaviour
|
||||
ControlledCharacter = GetEntity(authoring.ControlledCharacter, TransformUsageFlags.Dynamic),
|
||||
});
|
||||
AddComponent<FirstPersonPlayerInputs>(entity);
|
||||
AddComponent<FirstPersonPlayerNetworkInput>(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,26 +1,26 @@
|
||||
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(InitializationSystemGroup))]
|
||||
[UpdateInGroup(typeof(GhostInputSystemGroup))]
|
||||
[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation)]
|
||||
public partial class FirstPersonPlayerInputsSystem : SystemBase
|
||||
{
|
||||
protected override void OnCreate()
|
||||
{
|
||||
RequireForUpdate<FixedTickSystem.Singleton>();
|
||||
RequireForUpdate<NetworkTime>();
|
||||
RequireForUpdate(SystemAPI.QueryBuilder().WithAll<FirstPersonPlayer, FirstPersonPlayerInputs>().Build());
|
||||
}
|
||||
|
||||
protected override void OnUpdate()
|
||||
{
|
||||
uint tick = SystemAPI.GetSingleton<FixedTickSystem.Singleton>().Tick;
|
||||
var time = SystemAPI.GetSingleton<FixedTickSystem.Singleton>();
|
||||
|
||||
foreach (var (playerInputs, player) in SystemAPI.Query<RefRW<FirstPersonPlayerInputs>, FirstPersonPlayer>())
|
||||
foreach (var (playerInputs, player) in SystemAPI.Query<RefRW<FirstPersonPlayerInputs>, FirstPersonPlayer>().WithAll<GhostOwnerIsLocal>())
|
||||
{
|
||||
playerInputs.ValueRW.MoveInput = new float2
|
||||
{
|
||||
@ -28,11 +28,13 @@ public partial class FirstPersonPlayerInputsSystem : SystemBase
|
||||
y = (Input.GetKey(KeyCode.W) ? 1f : 0f) + (Input.GetKey(KeyCode.S) ? -1f : 0f),
|
||||
};
|
||||
|
||||
playerInputs.ValueRW.LookInput = new float2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
|
||||
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(tick);
|
||||
playerInputs.ValueRW.JumpPressed.Set(time.Tick);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -41,28 +43,33 @@ public partial class FirstPersonPlayerInputsSystem : SystemBase
|
||||
/// <summary>
|
||||
/// Apply inputs that need to be read at a variable rate
|
||||
/// </summary>
|
||||
[UpdateInGroup(typeof(SimulationSystemGroup))]
|
||||
[UpdateAfter(typeof(FixedStepSimulationSystemGroup))]
|
||||
[UpdateInGroup(typeof(PredictedSimulationSystemGroup))]
|
||||
[UpdateAfter(typeof(PredictedFixedStepSimulationSystemGroup))]
|
||||
[BurstCompile]
|
||||
public partial struct FirstPersonPlayerVariableStepControlSystem : ISystem
|
||||
{
|
||||
[BurstCompile]
|
||||
public void OnCreate(ref SystemState state)
|
||||
{
|
||||
state.RequireForUpdate<NetworkTime>();
|
||||
state.RequireForUpdate(SystemAPI.QueryBuilder().WithAll<FirstPersonPlayer, FirstPersonPlayerInputs>().Build());
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
public void OnUpdate(ref SystemState state)
|
||||
{
|
||||
foreach (var (playerInputs, player) in SystemAPI.Query<FirstPersonPlayerInputs, FirstPersonPlayer>().WithAll<Simulate>())
|
||||
foreach (var (playerInputs, playerNetworkInput, player) in SystemAPI.Query<FirstPersonPlayerInputs, RefRW<FirstPersonPlayerNetworkInput>, FirstPersonPlayer>().WithAll<Simulate>())
|
||||
{
|
||||
// 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<FirstPersonCharacterControl>(player.ControlledCharacter))
|
||||
{
|
||||
FirstPersonCharacterControl characterControl = SystemAPI.GetComponent<FirstPersonCharacterControl>(player.ControlledCharacter);
|
||||
|
||||
characterControl.LookDegreesDelta = playerInputs.LookInput;
|
||||
|
||||
characterControl.LookDegreesDelta = lookInputDelta;
|
||||
SystemAPI.SetComponent(player.ControlledCharacter, characterControl);
|
||||
}
|
||||
}
|
||||
@ -73,21 +80,22 @@ public partial struct FirstPersonPlayerVariableStepControlSystem : ISystem
|
||||
/// 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.
|
||||
/// </summary>
|
||||
[UpdateInGroup(typeof(FixedStepSimulationSystemGroup), OrderFirst = true)]
|
||||
[UpdateInGroup(typeof(PredictedFixedStepSimulationSystemGroup), OrderFirst = true)]
|
||||
[BurstCompile]
|
||||
public partial struct FirstPersonPlayerFixedStepControlSystem : ISystem
|
||||
{
|
||||
[BurstCompile]
|
||||
public void OnCreate(ref SystemState state)
|
||||
{
|
||||
state.RequireForUpdate<FixedTickSystem.Singleton>();
|
||||
|
||||
state.RequireForUpdate<NetworkTime>();
|
||||
state.RequireForUpdate(SystemAPI.QueryBuilder().WithAll<FirstPersonPlayer, FirstPersonPlayerInputs>().Build());
|
||||
}
|
||||
|
||||
[BurstCompile]
|
||||
public void OnUpdate(ref SystemState state)
|
||||
{
|
||||
uint tick = SystemAPI.GetSingleton<FixedTickSystem.Singleton>().Tick;
|
||||
var time = SystemAPI.GetSingleton<FixedTickSystem.Singleton>();
|
||||
|
||||
foreach (var (playerInputs, player) in SystemAPI.Query<FirstPersonPlayerInputs, FirstPersonPlayer>().WithAll<Simulate>())
|
||||
{
|
||||
@ -104,7 +112,7 @@ public partial struct FirstPersonPlayerFixedStepControlSystem : ISystem
|
||||
characterControl.MoveVector = MathUtilities.ClampToMaxLength(characterControl.MoveVector, 1f);
|
||||
|
||||
// Jump
|
||||
characterControl.Jump = playerInputs.JumpPressed.IsSet(tick);
|
||||
characterControl.Jump = playerInputs.JumpPressed.IsSet(time.Tick);
|
||||
|
||||
SystemAPI.SetComponent(player.ControlledCharacter, characterControl);
|
||||
}
|
||||
|
||||
52
Assets/Scripts/Common/GhostVariants.cs
Normal file
52
Assets/Scripts/Common/GhostVariants.cs
Normal file
@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using Unity.Entities;
|
||||
using Unity.Mathematics;
|
||||
using Unity.NetCode;
|
||||
using Unity.CharacterController;
|
||||
|
||||
public partial class DefaultVariantSystem : DefaultVariantSystemBase
|
||||
{
|
||||
protected override void RegisterDefaultVariants(Dictionary<ComponentType, Rule> defaultVariants)
|
||||
{
|
||||
defaultVariants.Add(typeof(KinematicCharacterBody), Rule.ForAll(typeof(KinematicCharacterBody_DefaultVariant)));
|
||||
defaultVariants.Add(typeof(CharacterInterpolation), Rule.ForAll(typeof(CharacterInterpolation_GhostVariant)));
|
||||
defaultVariants.Add(typeof(TrackedTransform), Rule.ForAll(typeof(TrackedTransform_DefaultVariant)));
|
||||
}
|
||||
}
|
||||
|
||||
[GhostComponentVariation(typeof(KinematicCharacterBody))]
|
||||
[GhostComponent()]
|
||||
public struct KinematicCharacterBody_DefaultVariant
|
||||
{
|
||||
// These two fields represent the basic synchronized state data that all networked characters will need.
|
||||
[GhostField()]
|
||||
public float3 RelativeVelocity;
|
||||
[GhostField()]
|
||||
public bool IsGrounded;
|
||||
|
||||
// The following fields are only needed for characters that need to support parent entities (stand on moving platforms).
|
||||
// You can safely omit these from ghost sync if your game does not make use of character parent entities (any entities that have a TrackedTransform component).
|
||||
[GhostField()]
|
||||
public Entity ParentEntity;
|
||||
[GhostField()]
|
||||
public float3 ParentLocalAnchorPoint;
|
||||
[GhostField()]
|
||||
public float3 ParentVelocity;
|
||||
}
|
||||
|
||||
// Character interpolation must only exist on predicted clients:
|
||||
// - for remote interpolated ghost characters, interpolation is handled by netcode.
|
||||
// - for server, interpolation is superfluous.
|
||||
[GhostComponentVariation(typeof(CharacterInterpolation))]
|
||||
[GhostComponent(PrefabType = GhostPrefabType.PredictedClient)]
|
||||
public struct CharacterInterpolation_GhostVariant
|
||||
{
|
||||
}
|
||||
|
||||
[GhostComponentVariation(typeof(TrackedTransform))]
|
||||
[GhostComponent()]
|
||||
public struct TrackedTransform_DefaultVariant
|
||||
{
|
||||
[GhostField()]
|
||||
public RigidTransform CurrentFixedRateTransform;
|
||||
}
|
||||
2
Assets/Scripts/Common/GhostVariants.cs.meta
Normal file
2
Assets/Scripts/Common/GhostVariants.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad968c3972f1b5d45a01ff13d76c6073
|
||||
46
Assets/Scripts/Common/InputDeltaUtilities.cs
Normal file
46
Assets/Scripts/Common/InputDeltaUtilities.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using Unity.Mathematics;
|
||||
|
||||
public static class InputDeltaUtilities
|
||||
{
|
||||
public const float InputWrapAroundValue = 2000f;
|
||||
|
||||
public static void AddInputDelta(ref float input, float addedDelta)
|
||||
{
|
||||
input = math.fmod(input + addedDelta, InputWrapAroundValue);
|
||||
}
|
||||
|
||||
public static void AddInputDelta(ref float2 input, float2 addedDelta)
|
||||
{
|
||||
input = math.fmod(input + addedDelta, InputWrapAroundValue);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
3
Assets/Scripts/Common/InputDeltaUtilities.cs.meta
Normal file
3
Assets/Scripts/Common/InputDeltaUtilities.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edf2b03f9a1d4b22b732a2d347673c5a
|
||||
timeCreated: 1738609617
|
||||
@ -56,7 +56,17 @@ MonoBehaviour:
|
||||
- rid: 7930710930656067584
|
||||
- rid: 4055230942537842688
|
||||
m_RuntimeSettings:
|
||||
m_List: []
|
||||
m_List:
|
||||
- rid: 6852985685364965378
|
||||
- rid: 6852985685364965379
|
||||
- rid: 6852985685364965380
|
||||
- rid: 6852985685364965381
|
||||
- rid: 6852985685364965384
|
||||
- rid: 6852985685364965385
|
||||
- rid: 6852985685364965392
|
||||
- rid: 6852985685364965394
|
||||
- rid: 8712630790384254976
|
||||
- rid: 7930710930656067584
|
||||
m_AssetVersion: 8
|
||||
m_ObsoleteDefaultVolumeProfile: {fileID: 0}
|
||||
m_RenderingLayerNames:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user