/// <summary> /// Handles horizontal movement on the XZ plane. /// </summary> /// <param name="horizontalVelocity"></param> /// <param name="entity"></param> /// <param name="currPos"></param> /// <param name="currRot"></param> /// <param name="controller"></param> /// <param name="collider"></param> /// <param name="collisionWorld"></param> private void HandleHorizontalMovement( ref float3 horizontalVelocity, ref Entity entity, ref float3 currPos, ref quaternion currRot, ref CharacterControllerComponent controller, ref PhysicsCollider collider, ref CollisionWorld collisionWorld) { if (MathUtils.IsZero(horizontalVelocity)) { return; } float3 targetPos = currPos + horizontalVelocity; NativeList <ColliderCastHit> horizontalCollisions = PhysicsUtils.ColliderCastAll(collider, currPos, targetPos, ref collisionWorld, entity, Allocator.Temp); PhysicsUtils.TrimByFilter(ref horizontalCollisions, ColliderData, PhysicsCollisionFilters.DynamicWithPhysical); if (horizontalCollisions.Length > 0) { // We either have to step or slide as something is in our way. float3 step = new float3(0.0f, controller.MaxStep, 0.0f); PhysicsUtils.ColliderCast(out ColliderCastHit nearestStepHit, collider, targetPos + step, targetPos, ref collisionWorld, entity, PhysicsCollisionFilters.DynamicWithPhysical, null, ColliderData, Allocator.Temp); if (!MathUtils.IsZero(nearestStepHit.Fraction)) { // We can step up. targetPos += (step * (1.0f - nearestStepHit.Fraction)); horizontalVelocity = targetPos - currPos; } else { // We can not step up, so slide. NativeList <DistanceHit> horizontalDistances = PhysicsUtils.ColliderDistanceAll(collider, 1.0f, new RigidTransform() { pos = currPos + horizontalVelocity, rot = currRot }, ref collisionWorld, entity, Allocator.Temp); PhysicsUtils.TrimByFilter(ref horizontalDistances, ColliderData, PhysicsCollisionFilters.DynamicWithPhysical); for (int i = 0; i < horizontalDistances.Length; ++i) { if (horizontalDistances[i].Distance >= 0.0f) { continue; } horizontalVelocity += (horizontalDistances[i].SurfaceNormal * -horizontalDistances[i].Distance); } horizontalDistances.Dispose(); } } horizontalCollisions.Dispose(); }
/// <summary> /// Handles vertical movement from gravity and jumping. /// </summary> /// <param name="entity"></param> /// <param name="currPos"></param> /// <param name="currRot"></param> /// <param name="controller"></param> /// <param name="collider"></param> /// <param name="collisionWorld"></param> private void HandleVerticalMovement( ref float3 verticalVelocity, ref Entity entity, ref float3 currPos, ref quaternion currRot, ref CharacterControllerComponent controller, ref PhysicsCollider collider, ref CollisionWorld collisionWorld) { controller.VerticalVelocity = verticalVelocity; if (MathUtils.IsZero(verticalVelocity)) { return; } verticalVelocity *= DeltaTime; NativeList <ColliderCastHit> verticalCollisions = PhysicsUtils.ColliderCastAll(collider, currPos, currPos + verticalVelocity, ref collisionWorld, entity, Allocator.Temp); PhysicsUtils.TrimByFilter(ref verticalCollisions, ColliderData, PhysicsCollisionFilters.DynamicWithPhysical); if (verticalCollisions.Length > 0) { RigidTransform transform = new RigidTransform() { pos = currPos + verticalVelocity, rot = currRot }; if (PhysicsUtils.ColliderDistance(out DistanceHit verticalPenetration, collider, 1.0f, transform, ref collisionWorld, entity, PhysicsCollisionFilters.DynamicWithPhysical, null, ColliderData, Allocator.Temp)) { if (verticalPenetration.Distance < -0.01f) { verticalVelocity += (verticalPenetration.SurfaceNormal * verticalPenetration.Distance); if (PhysicsUtils.ColliderCast(out ColliderCastHit adjustedHit, collider, currPos, currPos + verticalVelocity, ref collisionWorld, entity, PhysicsCollisionFilters.DynamicWithPhysical, null, ColliderData, Allocator.Temp)) { verticalVelocity *= adjustedHit.Fraction; } } } } verticalVelocity = MathUtils.ZeroOut(verticalVelocity, 0.0001f); verticalCollisions.Dispose(); }