### SphereCast Example Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/collision-queries.md An example of how to perform a sphere cast using Unity Physics. ```csharp public unsafe Entity SphereCast(float3 RayFrom, float3 RayTo, float radius) { // Set up Entity Query to get PhysicsWorldSingleton // If doing this in SystemBase or ISystem, call GetSingleton()/SystemAPI.GetSingleton() directly. EntityQueryBuilder builder = new EntityQueryBuilder(Allocator.Temp).WithAll(); EntityQuery singletonQuery = World.DefaultGameObjectInjectionWorld.EntityManager.CreateEntityQuery(builder); var collisionWorld = singletonQuery.GetSingleton().CollisionWorld; singletonQuery.Dispose(); var filter = new CollisionFilter() { BelongsTo = ~0u, CollidesWith = ~0u, // all 1s, so all layers, collide with everything GroupIndex = 0 }; SphereGeometry sphereGeometry = new SphereGeometry() { Center = float3.zero, Radius = radius }; BlobAssetReference sphereCollider = SphereCollider.Create(sphereGeometry, filter); ColliderCastInput input = new ColliderCastInput() { Collider = (Collider*)sphereCollider.GetUnsafePtr(), Orientation = quaternion.identity, Start = RayFrom, End = RayTo }; ColliderCastHit hit = new ColliderCastHit(); bool haveHit = collisionWorld.CastCollider(input, out hit); if (haveHit) { return hit.Entity; } sphereCollider.Dispose(); return Entity.Null; } ``` -------------------------------- ### Usage example Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/physics-singletons.md Examples demonstrating how to access and use PhysicsWorldSingleton in both ISystem and SystemBase versions. ```csharp // ISystem version [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))] [UpdateBefore(typeof(PhysicsSystemGroup))] // Make sure that the running order of systems is correct public partial struct CastRayISystemExample : ISystem { [BurstCompile] public partial struct CastRayJob : IJob { public PhysicsWorldSingleton World; public void Execute() { World.CastRay(...); } } [BurstCompile] public void OnUpdate(ref SystemState state) { PhysicsWorldSingleton physicsWorldSingleton = SystemAPI.GetSingleton(); // Version that schedules a job state.Dependency = new CastRayJob { World = physicsWorldSingleton }.Schedule(state.Dependency); // Main thread version - be sure to complete the dependency state.CompleteDependency(); physicsWorldSingleton.CastRay(...); // It is also possible to access the PhysicsWorld PhysicsWorld world = physicsWorldSingleton.PhysicsWorld; } } // SystemBase version [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))] [UpdateBefore(typeof(PhysicsSystemGroup))] // Make sure that the running order of systems is correct public partial class CastRaySystemBaseExample : SystemBase { public partial struct CastRayJob : IJob { public PhysicsWorldSingleton World; [BurstCompile] public void Execute() { World.CastRay(...); } } protected override void OnUpdate() { PhysicsWorldSingleton physicsWorldSingleton = GetSingleton(); // Version that schedules a job state.Dependency = new CastRayJob { World = physicsWorldSingleton }.Schedule(state.Dependency); // Main thread version - be sure to complete the dependency CompleteDependency(); physicsWorldSingleton.CastRay(...); // It is also possible to access the PhysicsWorld PhysicsWorld world = physicsWorldSingleton.PhysicsWorld; } } ``` -------------------------------- ### Raycast Example Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/collision-queries.md A C# example demonstrating how to perform a raycast query in Unity Physics to find the closest hit entity. ```csharp using Unity.Entities; using Unity.Mathematics; using Unity.Physics; public Entity Raycast(float3 RayFrom, float3 RayTo) { // Set up Entity Query to get PhysicsWorldSingleton // If doing this in SystemBase or ISystem, call GetSingleton()/SystemAPI.GetSingleton() directly. EntityQueryBuilder builder = new EntityQueryBuilder(Allocator.Temp).WithAll(); EntityQuery singletonQuery = World.DefaultGameObjectInjectionWorld.EntityManager.CreateEntityQuery(builder); var collisionWorld = singletonQuery.GetSingleton().CollisionWorld; singletonQuery.Dispose(); RaycastInput input = new RaycastInput() { Start = RayFrom, End = RayTo, Filter = new CollisionFilter() { BelongsTo = ~0u, CollidesWith = ~0u, // all 1s, so all layers, collide with everything GroupIndex = 0 } }; RaycastHit hit = new RaycastHit(); bool haveHit = collisionWorld.CastRay(input, out hit); if (haveHit) { return hit.Entity; } return Entity.Null; } ``` -------------------------------- ### CustomPhysicsSystemGroup Example Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/group-body.md Example of creating a custom physics group for a specific world index and a system that checks the current world index. ```csharp [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))] public partial class UserPhysicsGroup : CustomPhysicsSystemGroup { public UserPhysicsGroup() : base(1, true) {} // our physics group will simulate entities with world index 1, and share static entities with main world } [UpdateInGroup(PhysicsInitializeGroup)] // As the system updates inside [PhysicsSinitializeGroup], it will automatically be ran inside UserPhysicsGroup as well public partial class CheckWorldIndexSystem : SystemBase { protected override void OnUpdate() { var physicsWorldSingleton = GetSingleton(); if (physicsWorldSingleton.PhysicsWorldIndex.Value == 0) { // ... // When ran as part of main physics group, this code path will be hit. } else { // ... // When ran as part of UserPhysicsGroup, this code path will be hit. } } } ``` -------------------------------- ### Trigger events job example Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/simulation-results.md Example of how to implement and schedule an ITriggerEventsJob to count the number of trigger events. ```csharp [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))] [UpdateAfter(typeof(PhysicsSimulationGroup))] // We are updating after `PhysicsSimulationGroup` - this means that we will get the events of the current frame. public partial struct GetNumTriggerEventsSystem : ISystem { [BurstCompile] public partial struct CountNumTriggerEvents : ITriggerEventsJob { public NativeReference NumTriggerEvents; public void Execute(TriggerEvent collisionEvent) { NumTriggerEvents.Value++; } } [BurstCompile] public void OnUpdate(ref SystemState state) { NativeReference numTriggerEvents = new NativeReference(0, Allocator.TempJob); state.Dependency = new CountNumTriggerEvents { NumTriggerEvents = numTriggerEvents }.Schedule(SystemAPI.GetSingleton()); // ... } } ``` -------------------------------- ### Collision events job example Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/simulation-results.md Example of how to implement and schedule an ICollisionEventsJob to count the number of collision events. ```csharp [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))] [UpdateBefore(typeof(PhysicsSimulationGroup))] // We are updating before `PhysicsSimulationGroup` - this means that we will get the events of the previous frame public partial struct GetNumCollisionEventsSystem : ISystem { [BurstCompile] public partial struct CountNumCollisionEvents : ICollisionEventsJob { public NativeReference NumCollisionEvents; public void Execute(CollisionEvent collisionEvent) { NumCollisionEvents.Value++; } } [BurstCompile] public void OnUpdate(ref SystemState state) { NativeReference numCollisionEvents = new NativeReference(0, Allocator.TempJob); state.Dependency = new CountNumCollisionEvents { NumCollisionEvents = numCollisionEvents }.Schedule(SystemAPI.GetSingleton()); // ... } } ``` -------------------------------- ### SetFrictionToZeroSystem Example Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/simulation-modification.md An example system that implements IJacobiansJob to set friction to zero for all contacts. This demonstrates how to access and modify Jacobian data. ```csharp [BurstCompile] [UpdateInGroup(typeof(PhysicsSimulationGroup))] [UpdateAfter(typeof(PhysicsCreateJacobiansGroup))] [UpdateBefore(typeof(PhysicsSolveAndIntegrateGroup))] public partial struct SetFrictionToZeroSystem : ISystem { [BurstCompile] public partial struct SetFrictionToZeroJob : IJacobiansJob // Note: there are much more performant ways of setting friction to zero, this is just for demonstration purposes { // Don't do anything for triggers public void Execute(ref ModifiableJacobianHeader h, ref ModifiableTriggerJacobian j) {} [BurstCompile] public void Execute(ref ModifiableJacobianHeader jacHeader, ref ModifiableContactJacobian contactJacobian) { var friction0 = contactJacobian.Friction0; friction0.AngularA = 0.0f; friction0.AngularB = 0.0f; contactJacobian.Friction0 = friction0; var friction1 = contactJacobian.Friction1; friction1.AngularA = 0.0f; friction1.AngularB = 0.0f; contactJacobian.Friction1 = friction1; var angularFriction = contactJacobian.AngularFriction; angularFriction.AngularA = 0.0f; angularFriction.AngularB = 0.0f; contactJacobian.AngularFriction = angularFriction; } } [BurstCompile] public void OnUpdate(ref SystemState state) { state.Dependency = new SetFrictionToZeroJob() .Schedule(SystemAPI.GetSingletonRW(), ref SystemAPI.GetSingletonRW().PhysicsWorld, state.Dependency); } } ``` -------------------------------- ### Updating SystemGroup Attributes Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/upgrade-guide.md Examples of how to update system group attributes when migrating from older systems like StepPhysicsWorld and BuildPhysicsWorld to the new PhysicsSystemGroup. ```csharp [UpdateInGroup(typeof(PhysicsSystemGroup))][Update(After|Before)(typeof(PhysicsSimulationGroup))] ``` ```csharp [UpdateBefore(typeof(PhysicsSystemGroup))] or [UpdateInGroup(typeof(PhysicsSystemGroup))][UpdateAfter(typeof(PhysicsInitializeGroup))] ``` ```csharp [UpdateInGroup(typeof(PhysicsSystemGroup))][UpdateBefore(typeof(ExportPhysicsWorld))] or [UpdateAfter(typeof(PhysicsSystemGroup))] ``` ```csharp [UpdateAfter(typeof(PhysicsSystemGroup))] ``` -------------------------------- ### Deprecated Methods and Replacements Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/upgrade-guide.md This section lists deprecated methods and their new signatures, including the addition of a uniform scale argument. ```csharp AppendMeshColliders.GetMeshes.AppendSphere(SphereCollider* sphere, RigidTransform worldFromCollider, ref List results) ``` ```csharp AppendSphere(ref List results, SphereCollider* sphere, RigidTransform worldFromCollider, float uniformScale = 1) ``` ```csharp AppendMeshColliders.GetMeshes.AppendCapsule(CapsuleCollider* capsule, RigidTransform worldFromCollider, ref List results) ``` ```csharp AppendCapsule(ref List results, CapsuleCollider* capsule, RigidTransform worldFromCollider, float uniformScale = 1) ``` ```csharp AppendMeshColliders.GetMeshes.AppendMesh(MeshCollider* meshCollider, RigidTransform worldFromCollider, ref List results) ``` ```csharp AppendMesh(ref List results, MeshCollider* meshCollider, RigidTransform worldFromCollider, float uniformScale = 1) ``` ```csharp AppendMeshColliders.GetMeshes.AppendCompound(CompoundCollider* compoundCollider, RigidTransform worldFromCollider, ref List results) ``` ```csharp AppendCompound(ref List results, CompoundCollider* compoundCollider, RigidTransform worldFromCollider, float uniformScale = 1) ``` ```csharp AppendMeshColliders.GetMeshes.AppendTerrain(TerrainCollider* terrainCollider, RigidTransform worldFromCollider, ref List results) ``` ```csharp AppendTerrain(ref List results, TerrainCollider* terrainCollider, RigidTransform worldFromCollider, float uniformScale = 1) ``` ```csharp AppendMeshColliders.GetMeshes.AppendCollider(Collider* collider, RigidTransform worldFromCollider, ref List results) ``` ```csharp AppendCollider(ref List results, Collider* collider, RigidTransform worldFromCollider, float uniformScale = 1) ``` ```csharp ColliderDistanceInput.ColliderDistanceInput(BlobAssetReference collider, RigidTransform transform, float maxDistance) ``` ```csharp ColliderDistanceInput(BlobAssetReference collider, float maxDistance, RigidTransform transform, float uniformScale = 1) ``` ```csharp Collider.GetLeafCollider(Collider* root, RigidTransform rootTransform, ColliderKey key, out ChildCollider leaf) ``` ```csharp GetLeafCollider(out ChildCollider leaf, Collider* root, ColliderKey key, RigidTransform rootTransform, float rootUniformScale = 1) ``` ```csharp Math.TransformAabb(RigidTransform transform, Aabb aabb) ``` ```csharp Math.TransformAabb(Aabb aabb, RigidTransform transform, float uniformScale = 1) ``` ```csharp Math.TransformAabb(MTransform transform, Aabb aabb) ``` ```csharp Math.TransformAabb(Aabb aabb, MTransform transform, float uniformScale = 1) ``` -------------------------------- ### OnUpdate Method Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/create-body.md This method is part of a `SystemBase` and is called every update. It demonstrates creating a primitive sphere, setting up its rendering components, destroying the primitive, and then creating a physics entity using `CreateDynamicSphere`. ```csharp protected override void OnUpdate() { var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); var renderer = sphere.GetComponent(); var mesh = sphere.GetComponent().mesh; var renderMeshDescription = new RenderMeshDescription(renderer); var renderMeshArray = new RenderMeshArray(new[] { renderer.material }, new[] { mesh }); var materialMeshInfo = MaterialMeshInfo.FromRenderMeshArrayIndices(0, 0); Object.DestroyImmediate(sphere); var entity = CreateDynamicSphere(EntityManager, renderMeshArray, materialMeshInfo, renderMeshDescription, 1, 0.5f, new float3(0, 5, 0), quaternion.identity); EntityManager.SetName(entity, "Sphere"); Enabled = false; } ``` -------------------------------- ### CreateFromMeshDataJob Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/physics-collider-components.md Example of how to create a MeshCollider from a UnityEngine.Mesh in a job. ```csharp struct CreateFromMeshDataJob : IJobParallelFor { [ReadOnly] public NativeArray MeshData; [WriteOnly] public NativeArray> ColliderBlobReference; public void Execute(int i) { ColliderBlobReference[i] = MeshCollider.Create(MeshData[i], CollisionFilter.Default, Material.Default); } } public void MeshCollider_CreateFromJob(UnityEngine.Mesh engineMesh) { int num = 3; // We are 3 creating colliders of the same mesh for example purposes only. var colliderBlobReferenceTracking = new NativeArray>(num, Allocator.Persistent); using var meshData = new NativeArray(num, Allocator.TempJob); for (int i = 0; i < num; i++) { var meshDataArray = UnityEngine.Mesh.AcquireReadOnlyMeshData(engineMesh); meshData[i] = meshDataArray[0]; } new CreateFromMeshDataJob() { MeshData = meshData, ColliderBlobReference = colliderBlobReferenceTracking }.Run(num); for (int i = 0; i < num; i++) { var physicsCollider = new PhysicsCollider { Value = colliderBlobReferenceTracking[i] }; // do stuff } // Make sure to dispose of the collider blobs that are tracked in // colliderBlobReferenceTracking once the blobs are no longer required. ... } ``` -------------------------------- ### EnableSurfaceVelocitySystem Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/simulation-modification.md An example system that implements IContactsJob to enable surface velocity for contacts. ```csharp [UpdateInGroup(typeof(PhysicsSimulationGroup))] [UpdateAfter(typeof(PhysicsCreateContactsGroup))] [UpdateBefore(typeof(PhysicsCreateJacobiansGroup))] [BurstCompile] public partial struct EnableSurfaceVelocitySystem : ISystem { // This sets some data on the contact, to get propagated to the jacobian // for processing in our jacobian modifier job. This is necessary because some flags require extra data to // be allocated along with the jacobian (e.g., SurfaceVelocity data typically does not exist). [BurstCompile] public partial struct EnableSurfaceVelocityJob : IContactsJob { public void Execute(ref ModifiableContactHeader manifold, ref ModifiableContactPoint contact) { manifold.JacobianFlags |= JacobianFlags.EnableSurfaceVelocity; } } [BurstCompile] public void OnUpdate(ref SystemState state) { state.Dependency = new EnableSurfaceVelocityJob() .Schedule(SystemAPI.GetSingletonRW(), ref SystemAPI.GetSingletonRW().PhysicsWorld, state.Dependency); } } ``` -------------------------------- ### Creating a dynamic physics body Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/create-body.md This code snippet demonstrates how to create a dynamic physics body by setting its mass, velocity, damping, and gravity factor. ```csharp entityManager.SetComponentData(entity, PhysicsMass.CreateDynamic(colliderPtr->MassProperties, mass)); /*entityManager.SetComponentData(entity, new PhysicsMass { Transform = new RigidTransform { pos = new float3(0, 0, 0), rot = quaternion.identity }, InverseMass = 1, InverseInertia = new float3(10, 10, 10), AngularExpansionFactor = 0 });*/ // Calculate the angular velocity in local space from rotation and world angular velocity float3 angularVelocityLocal = math.mul(math.inverse(colliderPtr->MassProperties.MassDistribution.Transform.rot), angularVelocity); entityManager.SetComponentData(entity, new PhysicsVelocity() { Linear = linearVelocity, Angular = angularVelocityLocal }); entityManager.SetComponentData(entity, new PhysicsDamping() { Linear = 0.01f, Angular = 0.05f }); entityManager.SetComponentData(entity, new PhysicsGravityFactor { Value = 1 }); return entity; } } ``` -------------------------------- ### DisableDynamicDynamicPairsSystem Source: https://github.com/needle-mirror/com.unity.physics/blob/master/Documentation~/simulation-modification.md An example system that implements IBodyPairsJob to disable interactions between dynamic bodies. ```csharp [UpdateInGroup(typeof(PhysicsSimulationGroup))] [UpdateAfter(typeof(PhysicsCreateBodyPairsGroup))] [UpdateBefore(typeof(PhysicsCreateContactsGroup))] public partial struct DisableDynamicDynamicPairsSystem : ISystem { [BurstCompile] struct DisableDynamicDynamicPairsJob : IBodyPairsJob { public int NumDynamicBodies; public unsafe void Execute(ref ModifiableBodyPair pair) { // Disable the pair if it's dynamic-dynamic bool isDynamicDynamic = pair.BodyIndexA < NumDynamicBodies && pair.BodyIndexB < NumDynamicBodies; if (isDynamicDynamic) { pair.Disable(); } } } [BurstCompile] public void OnUpdate(ref SystemState state) { PhysicsWorldSingleton worldSingleton = SystemAPI.GetSingletonRW(); SimulationSingleton simulationSingleton = SystemAPI.GetSingletonRW(); state.Dependency = new DisableDynamicDynamicPairsJob { NumDynamicBodies = worldSingleton.PhysicsWorld.NumDynamicBodies }.Schedule(simulationSingleton, ref worldSingleton.PhysicsWorld, state.Dependency); } } ```