예제 #1
0
        /// <summary>
        ///     Movement while considering actionblockers, weightlessness, etc.
        /// </summary>
        /// <param name="mover"></param>
        /// <param name="physicsComponent"></param>
        /// <param name="mobMover"></param>
        protected void HandleMobMovement(IMoverComponent mover, PhysicsComponent physicsComponent,
                                         IMobMoverComponent mobMover)
        {
            // TODO: Look at https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/CharacterControllers.html?highlight=controller as it has some adviceo n kinematic controllersx
            if (!UseMobMovement(_broadPhaseSystem, physicsComponent, _mapManager))
            {
                return;
            }

            var transform = mover.Owner.Transform;

            var(walkDir, sprintDir) = mover.VelocityDir;

            var weightless = transform.Owner.IsWeightless(physicsComponent, mapManager: _mapManager);

            // Handle wall-pushes.
            if (weightless)
            {
                // No gravity: is our entity touching anything?
                var touching = IsAroundCollider(_broadPhaseSystem, transform, mobMover, physicsComponent);

                if (!touching)
                {
                    transform.WorldRotation = physicsComponent.LinearVelocity.GetDir().ToAngle();
                    return;
                }
            }

            // Regular movement.
            // Target velocity.
            // This is relative to the map / grid we're on.
            var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed);

            var worldTotal = _relativeMovement ?
                             new Angle(transform.Parent !.WorldRotation.Theta).RotateVec(total) :
                             total;

            DebugTools.Assert(MathHelper.CloseTo(total.Length, worldTotal.Length));

            if (weightless)
            {
                worldTotal *= mobMover.WeightlessStrength;
            }

            if (worldTotal != Vector2.Zero)
            {
                // This should have its event run during island solver soooo
                transform.DeferUpdates  = true;
                transform.WorldRotation = worldTotal.GetDir().ToAngle();
                transform.DeferUpdates  = false;
                HandleFootsteps(mover, mobMover);
            }

            physicsComponent.LinearVelocity = worldTotal;
        }
예제 #2
0
 // TODO: Need a predicted client version that only plays for our own entity and then have server-side ignore our session (for that entity only)
 protected virtual void HandleFootsteps(IMoverComponent mover, IMobMoverComponent mobMover)
 {
 }
예제 #3
0
        /// <summary>
        ///     Used for weightlessness to determine if we are near a wall.
        /// </summary>
        /// <param name="broadPhaseSystem"></param>
        /// <param name="transform"></param>
        /// <param name="mover"></param>
        /// <param name="collider"></param>
        /// <returns></returns>
        public static bool IsAroundCollider(SharedBroadphaseSystem broadPhaseSystem, ITransformComponent transform, IMobMoverComponent mover, IPhysBody collider)
        {
            var enlargedAABB = collider.GetWorldAABB().Enlarged(mover.GrabRange);

            foreach (var otherCollider in broadPhaseSystem.GetCollidingEntities(transform.MapID, enlargedAABB))
            {
                if (otherCollider == collider)
                {
                    continue;                            // Don't try to push off of yourself!
                }
                // Only allow pushing off of anchored things that have collision.
                if (otherCollider.BodyType != BodyType.Static ||
                    !otherCollider.CanCollide ||
                    ((collider.CollisionMask & otherCollider.CollisionLayer) == 0 &&
                     (otherCollider.CollisionMask & collider.CollisionLayer) == 0) ||
                    (otherCollider.Owner.TryGetComponent(out SharedPullableComponent? pullable) && pullable.BeingPulled))
                {
                    continue;
                }

                return(true);
            }

            return(false);
        }
예제 #4
0
        protected void HandleMobMovement(IMoverComponent mover, PhysicsComponent physicsComponent, IMobMoverComponent mobMover)
        {
            // TODO: Look at https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/CharacterControllers.html?highlight=controller as it has some adviceo n kinematic controllersx
            if (!UseMobMovement(_broadPhaseSystem, physicsComponent, _physicsManager))
            {
                return;
            }

            var transform = mover.Owner.Transform;

            var(walkDir, sprintDir) = mover.VelocityDir;

            var weightless = transform.Owner.IsWeightless(_physicsManager);

            // Handle wall-pushes.
            if (weightless)
            {
                // No gravity: is our entity touching anything?
                var touching = IsAroundCollider(_broadPhaseSystem, transform, mobMover, physicsComponent);

                if (!touching)
                {
                    transform.LocalRotation = physicsComponent.LinearVelocity.GetDir().ToAngle();
                    return;
                }
            }

            // Regular movement.
            // Target velocity.
            var total = (walkDir * mover.CurrentWalkSpeed + sprintDir * mover.CurrentSprintSpeed);

            if (weightless)
            {
                total *= mobMover.WeightlessStrength;
            }

            if (total != Vector2.Zero)
            {
                // This should have its event run during island solver soooo
                transform.DeferUpdates  = true;
                transform.LocalRotation = total.GetDir().ToAngle();
                transform.DeferUpdates  = false;
                HandleFootsteps(mover, mobMover);
            }

            physicsComponent.LinearVelocity = total;
        }