# Physics Queries Intermediate Programmer **Physics Queries** are a set of operation to test and retrieve physics object in a given simulation, the most well known form of those queries is the `RayCast` which traces an invisible line through the scene to find intersecting [Collidables](colliders.md). This is useful, for example, to check which objects are in a gun's line of fire, or are under the mouse cursor when the user clicks. > [!Note] > Physics queries uses **collider shapes** to find objects. It ignores entities that have no Collidable Component attached or no collider shape set, see [Collidables](colliders.md). To raycast in the current [Simulation](xref:Stride.BepuPhysics.BepuSimulation), see the [Simulation API](xref:Stride.BepuPhysics.BepuSimulation). For an example of raycasting, see the **Physics Sample** project included with Stride. ## Examples On left click, if there is a 'HostileUnit' in front of 'MyGun', deal damage to it ```cs public override void Update() { var simulation = Entity.GetSimulation(); MyGun.Transform.GetWorldTransformation(out var rayStart, out var worldRot, out _); var rayDir = worldRot * Vector3.UnitZ; float range = 10; // All layers except 0 & 1 var layers = CollisionMask.Everything & ~(CollisionMask.Layer0 | CollisionMask.Layer1); if (Input.IsMouseButtonPressed(MouseButton.Left) && simulation.RayCast(rayStart, rayDir, range, out HitInfo hitResult, layers)) { var hostile = hitResult.Collidable.Entity.Get(); if (hostile is not null) hostile.DealDamage(10); } } ``` Using the non-alloc version of a penetrating query to find multiple objects intersecting with the ray ```cs var simulation = Entity.GetSimulation(); Entity.Transform.GetWorldTransformation(out var rayStart, out var worldRot, out _); var rayDir = worldRot * Vector3.UnitZ; // Allocates a working buffer on the stack for the penetrating test, // The 16 specified here would be the maximum item this test would keep track of, // if the test finds more than 16 objects, it will yield the 16 closest ones System.Span buffer = stackalloc HitInfoStack[16]; // The order in which elements are yielded throughout this foreach is not guaranteed // Some hitInfo with a smaller distance may be returned after one with a larger one, // and the opposite is also true. foreach (var hitInfo in simulation.RayCastPenetrating(rayStart, rayDir, 100f, buffer)) { Log.Warning($"T: {hitInfo.Distance}\nNormal: {hitInfo.Normal}\nEntity : {hitInfo.Collidable.Entity}"); } ``` Moves a box through the scene and return what it collided with ```cs var simulation = Entity.GetSimulation(); Entity.Transform.GetWorldTransformation(out var center, out var worldRot, out _); var rayDir = worldRot * Vector3.UnitZ; var initialPose = new RigidPose(center, worldRot); var displacement = new BodyVelocity(rayDir, default); var shape = new Box(0.25f, 0.25f, 0.25f); if (simulation.SweepCast(shape, initialPose, displacement, 10, out HitInfo hitInfo)) { Log.Warning($"T: {hitInfo.Distance}\nNormal: {hitInfo.Normal}\nEntity : {hitInfo.Collidable.Entity}"); } ``` Find up to 16 physics object a box placed at that position would overlap with ```cs var simulation = Entity.GetSimulation(); Entity.Transform.GetWorldTransformation(out var center, out var worldRot, out _); var initialPose = new RigidPose(center, worldRot); var shape = new Box(0.25f, 0.25f, 0.25f); System.Span buffer = stackalloc CollidableStack[16]; foreach (var hit in simulation.Overlap(shape, initialPose, buffer)) { Log.Warning($"Entity : {hit.Entity}"); } ``` Send a raycast from the mouse's screen position: ```cs public static bool ScreenPositionToWorldPositionRaycast(Vector2 screenPos, CameraComponent camera) { Matrix invViewProj = Matrix.Invert(camera.ViewProjectionMatrix); // Reconstruct the projection-space position in the (-1, +1) range. // Don't forget that Y is down in screen coordinates, but up in projection space Vector3 sPos; sPos.X = screenPos.X * 2f - 1f; sPos.Y = 1f - screenPos.Y * 2f; // Compute the near (start) point for the raycast // It's assumed to have the same projection space (x,y) coordinates and z = 0 (lying on the near plane) // We need to unproject it to world space sPos.Z = 0f; var vectorNear = Vector3.Transform(sPos, invViewProj); vectorNear /= vectorNear.W; // Compute the far (end) point for the raycast // It's assumed to have the same projection space (x,y) coordinates and z = 1 (lying on the far plane) // We need to unproject it to world space sPos.Z = 1f; var vectorFar = Vector3.Transform(sPos, invViewProj); vectorFar /= vectorFar.W; var delta = (vectorFar - vectorNear).XYZ(); var maxDistance = delta.Length(); var dir = delta / maxDistance; // normalize delta // Raycast from the point on the near plane to the point on the far plane and get the collision result return camera.Entity.GetSimulation().RayCast(vectorNear.XYZ(), dir, maxDistance, out HitInfo hit); } ``` >[!Note] >There are multiple ways to retrieve a reference to this `Simulation` from inside one of your `ScriptComponent`: >- The recommended way is through a reference to a physics component, something like `myBody.Simulation` as it is the fastest. >- Or through the `Entity.GetSimulation()` extension method. ## See also * [Colliders](colliders.md)