Hi,
I’m having a wierd issue with my character controller, if I use the character controller, my character jitters alot when FPS is higher than 60 even with a basic movement script (not using the CharacterAspect), but if I replace it by a PhysicsBody or RigidBody, it no longer jitters. This brings me to think that something is not set up properly for my character controller, but I can’t figure out what.
Here is my character authoring :
using System;
using Unity.CharacterController;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
using static CharacterAuthoring;
[Serializable]
public struct CharacterComponent : IComponentData
{
public float RotationSharpness;
public float GroundMaxSpeed;
public float GroundedMovementSharpness;
public float AirAcceleration;
public float AirMaxSpeed;
public float AirDrag;
public float JumpSpeed;
public float3 Gravity;
public bool PreventAirAccelerationAgainstUngroundedHits;
public BasicStepAndSlopeHandlingParameters StepAndSlopeHandling;
public int MaxJumps;
public int CurrentJumps;
public float MaxCoyoteTime;
public float CoyoteTime;
public float AirJumpMultiplier;
}
public struct ExternalForce : IBufferElementData
{
public float3 Force;
}
[DisallowMultipleComponent]
public class CharacterAuthoring : MonoBehaviour
{
public AuthoringKinematicCharacterProperties CharacterProperties = AuthoringKinematicCharacterProperties.GetDefault();
public float RotationSharpness = 25f;
public float GroundMaxSpeed = 10f;
public float GroundedMovementSharpness = 15f;
public float AirAcceleration = 50f;
public float AirMaxSpeed = 10f;
public float AirDrag = 0f;
public float JumpSpeed = 10f;
public float3 Gravity = math.up() * -30f;
public bool PreventAirAccelerationAgainstUngroundedHits = true;
public BasicStepAndSlopeHandlingParameters StepAndSlopeHandling = BasicStepAndSlopeHandlingParameters.GetDefault();
public int MaxJumps = 2;
public float MaxCoyoteTime = 0.125f;
public float AirJumpMultiplier = 0.5f;
public class Baker : Baker<CharacterAuthoring>
{
public override void Bake(CharacterAuthoring authoring)
{
authoring.CharacterProperties.InterpolatePosition = false;
authoring.CharacterProperties.InterpolateRotation = false;
authoring.CharacterProperties.SnapToGround = false;
authoring.CharacterProperties.EnhancedGroundPrecision = true;
KinematicCharacterUtilities.BakeCharacter(this, authoring, authoring.CharacterProperties);
Entity entity = GetEntity(TransformUsageFlags.Dynamic | TransformUsageFlags.WorldSpace);
AddComponent(entity, new CharacterComponent
{
RotationSharpness = authoring.RotationSharpness,
GroundMaxSpeed = authoring.GroundMaxSpeed,
GroundedMovementSharpness = authoring.GroundedMovementSharpness,
AirAcceleration = authoring.AirAcceleration,
AirMaxSpeed = authoring.AirMaxSpeed,
AirDrag = authoring.AirDrag,
JumpSpeed = authoring.JumpSpeed,
Gravity = authoring.Gravity,
PreventAirAccelerationAgainstUngroundedHits = authoring.PreventAirAccelerationAgainstUngroundedHits,
StepAndSlopeHandling = authoring.StepAndSlopeHandling,
MaxJumps = authoring.MaxJumps,
MaxCoyoteTime = authoring.MaxCoyoteTime,
AirJumpMultiplier = authoring.AirJumpMultiplier
});
AddBuffer<ExternalForce>(entity);
}
}
}
Here is the movement script :
using Unity.Collections;
using Unity.Burst;
using Unity.Entities;
using Unity.NetCode;
using Unity.Transforms;
using Unity.Mathematics;
[UpdateInGroup(typeof(PredictedSimulationSystemGroup))]
public partial struct CharacterMovementSystem : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
var builder = new EntityQueryBuilder(Allocator.Temp);
builder.WithAll<PlayerInput>();
state.RequireForUpdate(state.GetEntityQuery(builder));
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var job = new PlayerMovementJob
{
dt = SystemAPI.Time.DeltaTime
};
state.Dependency = job.ScheduleParallel(state.Dependency);
}
}
[BurstCompile]
public partial struct PlayerMovementJob : IJobEntity
{
public float dt;
public void Execute(in PlayerInput input, ref LocalTransform transform)
{
float3 movement = new float3(input.MoveInput.x, 0, input.MoveInput.y) * 10f * dt;
transform.Position = transform.Translate(movement).Position;
}
}
and this is how my character is set up :



