I’m working on Netcode for Entities
There is a player(me) in the scene, and I move it monontone and continuedly. In the absence of other conditions, its moving is smooth
And I create a system which update in PredictedSimulationGroup, the system’s purpose is to create projectile continuedly, it’s written like this:
public struct ProjectileState : IComponentData {
[GhostField]
public uint spawnId;
public float lifeTime;
}
public struct Player : IComponentData {
[GhostField]
public int playerId;
// server
public Entity connectionEnt;
}
public struct TargetActor : IComponentData {
// The actual player entity which has LocalTransform
[GhostField] public Entity actorEnt;
}
[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation)] // [Edit]
[UpdateInGroup(typeof(PredictedSimulationSystemGroup))]
public partial class ActorShootPredictedProcessSystem : SystemBase {
private EntityQuery projectilePrefabQuery;
private float timer;
protected override void OnCreate() {
projectilePrefabQuery = GetEntityQuery(new EntityQueryDesc() {
All = new ComponentType[] {
typeof(GhostInstance),
typeof(ProjectileState),
typeof(Prefab),
},
None = new ComponentType[] {
typeof(InitializedTag)
},
Options = EntityQueryOptions.IncludePrefab,
});
RequireForUpdate<GameLoadedTag>();
}
protected override void OnUpdate() {
timer -= UnityEngine.Time.fixedDeltaTime;
bool isServer = World.IsServer();
var networkTime = SystemAPI.GetSingleton<NetworkTime>();
if (!networkTime.IsFirstTimeFullyPredictingTick) {
return;
}
Entities
.WithStructuralChanges()
.WithAll<Player>()
.ForEach((ref Entity entity, ref TargetActor targetActor) => {
NetworkTick tick = networkTime.ServerTick;
if (timer <= 0) {
if (!isServer) {
Entity projectileClient = SpawnProjectile(prevSampledTick.TickIndexForValidTick + 9999, false, targetActor, new float3(1, 1, 1));
}
timer = 0.05f;
}
}).Run();
}
private Entity SpawnProjectile(uint spawnId, bool isPredictedSpawn, TargetActor targetActor, float3 spawnPosOffset) {
Entity prefab = projectilePrefabQuery.GetSingletonEntity();
Entity projectile = EntityManager.Instantiate(prefab);
EntityManager.AddComponent<EntityPrefabInstanceTag>(projectile);
EntityManager.SetComponentData(projectile, new ProjectileState() {
spawnId = spawnId,
lifeTime = 5,
});
LocalTransform actorTrans = EntityManager.GetComponentData<LocalTransform>(targetActor.actorEnt);
EntityManager.SetComponentData(projectile, new LocalTransform() {
Position = actorTrans.Position + spawnPosOffset,
Rotation = quaternion.identity,
Scale = 1f
});
return projectile;
}
}
After this system start working, I found prediction error in the character’s movement, The phenomenon is that the player is constantly overmove
The projectile has no collider, and there is no any collider in scene except ground, so in theory there is no object blocking the player’s movement
I try to check player’s LocalTransform data, found that its position did roll back. In the ex below, the player is moving right. But in Tick-267, its position occured a big change, but it goes back next tick
Does anyone know something about it?Thank you very much!