protected override JobHandle OnUpdate(JobHandle inputDeps) { var collisionHistory = m_physicsHistory.CollisionHistory; uint predictingTick = m_predictionGroup.PredictingTick; // Do not perform hit-scan when rolling back, only when simulating the latest tick if (!m_predictionGroup.IsFinalPredictionTick) { return(inputDeps); } var isServer = m_IsServer; // Not using burst since there is a static used to update the UI var handle = Entities.WithoutBurst().ForEach((DynamicBuffer <RayTraceCommand> commands, in CommandDataInterpolationDelay delay) => { // If there is no data for the tick or a fire was not requested - do not process anything if (!commands.GetDataAtTick(predictingTick, out var cmd)) { return; } if (cmd.lastFire != predictingTick) { return; } // Get the collision world to use given the tick currently being predicted and the interpolation delay for the connection collisionHistory.GetCollisionWorldFromTick(predictingTick, LagUI.EnableLagCompensation ? delay.Delay : 0, out var collWorld); var rayInput = new Unity.Physics.RaycastInput(); rayInput.Start = cmd.origin; rayInput.End = cmd.origin + cmd.direction * 100; rayInput.Filter = Unity.Physics.CollisionFilter.Default; bool hit = collWorld.CastRay(rayInput); if (isServer) { LagUI.ServerTick = predictingTick; LagUI.ServerHit = hit; } else { LagUI.ClientTick = predictingTick; LagUI.ClientHit = hit; } }).Schedule(JobHandle.CombineDependencies(inputDeps, m_physicsHistory.LastPhysicsJobHandle)); m_physicsHistory.LastPhysicsJobHandle = handle; return(handle); }
// This should be a job rather than happening on the main thread. However, it doesn't really take a long time, and happens infrequently. protected override void OnUpdate() { var physicsWorldSystem = World.Active.GetExistingSystem <Unity.Physics.Systems.BuildPhysicsWorld>(); var collisionWorld = physicsWorldSystem.PhysicsWorld.CollisionWorld; Entities.With(mRaycastRequestsQuery).ForEach((Entity entity, ref RayRequest r) => { Unity.Physics.RaycastInput input = new Unity.Physics.RaycastInput() { Start = r.Value.Origin, End = r.Value.Displacement, Filter = Unity.Physics.CollisionFilter.Default, }; Debug.DrawLine(input.Start, input.End, Color.blue, 0.5f); var hit = new Unity.Physics.RaycastHit(); if (collisionWorld.CastRay(input, out hit)) { var e = physicsWorldSystem.PhysicsWorld.Bodies[hit.RigidBodyIndex].Entity; if (EntityManager.HasComponent <IFCGuidUIPosition>(e)) { PostUpdateCommands.RemoveComponent <IFCGuidUIPosition>(e); PostUpdateCommands.AddComponent <DeselectedTag>(e); } else { PostUpdateCommands.AddComponent(e, new IFCGuidUIPosition { Value = hit.Position }); } } PostUpdateCommands.DestroyEntity(entity); }); }