コード例 #1
0
 /// <summary>
 /// Constructs a new vertical motion constraint.
 /// </summary>
 /// <param name="characterBody">Character body governed by the constraint.</param>
 /// <param name="supportFinder">Support finder used by the character.</param>
 /// <param name="maximumGlueForce">Maximum force the vertical motion constraint is allowed to apply in an attempt to keep the character on the ground.</param>
 public VerticalMotionConstraint(Entity characterBody, SupportFinder supportFinder,
                                 float maximumGlueForce = 5000)
 {
     this.characterBody = characterBody;
     this.supportFinder = supportFinder;
     MaximumGlueForce   = maximumGlueForce;
 }
コード例 #2
0
 /// <summary>
 /// Constructs a new horizontal motion constraint.
 /// </summary>
 /// <param name="characterBody">Character body to be governed by this constraint.</param>
 /// <param name="supportFinder">Helper used to find supports for the character.</param>
 public HorizontalMotionConstraint(Entity characterBody, SupportFinder supportFinder)
 {
     this.characterBody = characterBody;
     this.supportFinder = supportFinder;
     CollectInvolvedEntities();
     MaximumAccelerationForce = float.MaxValue;
 }
コード例 #3
0
        /// <summary>
        /// Constructs a new character controller.
        /// </summary>
        /// <param name="position">Initial position of the character.</param>
        /// <param name="height">Height of the character body while standing.</param>
        /// <param name="crouchingHeight">Height of the character body while crouching.</param>
        /// <param name="proneHeight">Height of the character body while prone.</param>
        /// <param name="radius">Radius of the character body.</param>
        /// <param name="margin">Radius of 'rounding' applied to the cylindrical body. Higher values make the cylinder's edges more rounded.
        /// The margin is contained within the cylinder's height and radius, so it must not exceed the radius or height of the cylinder.
        /// To change the collision margin later, use the CharacterController.CollisionMargin property.</param>
        /// <param name="mass">Mass of the character body.</param>
        /// <param name="maximumTractionSlope">Steepest slope, in radians, that the character can maintain traction on.</param>
        /// <param name="maximumSupportSlope">Steepest slope, in radians, that the character can consider a support.</param>
        /// <param name="standingSpeed">Speed at which the character will try to move while crouching with a support that provides traction.
        /// Relative velocities with a greater magnitude will be decelerated.</param>
        /// <param name="crouchingSpeed">Speed at which the character will try to move while crouching with a support that provides traction.
        /// Relative velocities with a greater magnitude will be decelerated.</param>
        /// <param name="proneSpeed">Speed at which the character will try to move while prone with a support that provides traction.
        /// Relative velocities with a greater magnitude will be decelerated.</param>
        /// <param name="tractionForce">Maximum force that the character can apply while on a support which provides traction.</param>
        /// <param name="slidingSpeed">Speed at which the character will try to move while on a support that does not provide traction.
        /// Relative velocities with a greater magnitude will be decelerated.</param>
        /// <param name="slidingForce">Maximum force that the character can apply while on a support which does not provide traction</param>
        /// <param name="airSpeed">Speed at which the character will try to move with no support.
        /// The character will not be decelerated while airborne.</param>
        /// <param name="airForce">Maximum force that the character can apply with no support.</param>
        /// <param name="jumpSpeed">Speed at which the character leaves the ground when it jumps</param>
        /// <param name="slidingJumpSpeed">Speed at which the character leaves the ground when it jumps without traction</param>
        /// <param name="maximumGlueForce">Maximum force the vertical motion constraint is allowed to apply in an attempt to keep the character on the ground.</param>
        public CharacterController(
            Vector3 position           = new Vector3(),
            float height               = 1.7f, float crouchingHeight = 1.7f * .7f, float proneHeight = 1.7f * 0.3f,
            float radius               = 0.6f, float margin          = 0.1f, float mass = 10f,
            float maximumTractionSlope = 0.8f, float maximumSupportSlope = 1.3f,
            float standingSpeed        = 8f, float crouchingSpeed     = 3f, float proneSpeed = 1.5f, float tractionForce = 1000,
            float slidingSpeed         = 6, float slidingForce        = 50, float airSpeed   = 1, float airForce = 250,
            float jumpSpeed            = 4.5f, float slidingJumpSpeed = 3,
            float maximumGlueForce     = 5000
            )
        {
            if (margin > radius || margin > crouchingHeight || margin > height)
            {
                throw new ArgumentException("Margin must not be larger than the character's radius or height.");
            }

            Body = new Cylinder(position, height, radius, mass);
            Body.IgnoreShapeChanges =
                true; //Wouldn't want inertia tensor recomputations to occur when crouching and such.
            Body.CollisionInformation.Shape.CollisionMargin = margin;
            //Making the character a continuous object prevents it from flying through walls which would be pretty jarring from a player's perspective.
            Body.PositionUpdateMode        = PositionUpdateMode.Continuous;
            Body.LocalInertiaTensorInverse = new Matrix3x3();
            //TODO: In v0.16.2, compound bodies would override the material properties that get set in the CreatingPair event handler.
            //In a future version where this is changed, change this to conceptually minimally required CreatingPair.
            Body.CollisionInformation.Events.DetectingInitialCollision += RemoveFriction;
            Body.LinearDamping         = 0;
            ContactCategorizer         = new CharacterContactCategorizer(maximumTractionSlope, maximumSupportSlope);
            QueryManager               = new QueryManager(Body, ContactCategorizer);
            SupportFinder              = new SupportFinder(Body, QueryManager, ContactCategorizer);
            HorizontalMotionConstraint = new HorizontalMotionConstraint(Body, SupportFinder);
            HorizontalMotionConstraint.PositionAnchorDistanceThreshold = radius * 0.25f;
            VerticalMotionConstraint = new VerticalMotionConstraint(Body, SupportFinder, maximumGlueForce);
            StepManager = new StepManager(Body, ContactCategorizer, SupportFinder, QueryManager,
                                          HorizontalMotionConstraint);
            StanceManager = new StanceManager(Body, crouchingHeight, proneHeight, QueryManager, SupportFinder);
            PairLocker    = new CharacterPairLocker(Body);

            StandingSpeed    = standingSpeed;
            CrouchingSpeed   = crouchingSpeed;
            ProneSpeed       = proneSpeed;
            TractionForce    = tractionForce;
            SlidingSpeed     = slidingSpeed;
            SlidingForce     = slidingForce;
            AirSpeed         = airSpeed;
            AirForce         = airForce;
            JumpSpeed        = jumpSpeed;
            SlidingJumpSpeed = slidingJumpSpeed;

            //Enable multithreading for the characters.
            IsUpdatedSequentially = false;
            //Link the character body to the character controller so that it can be identified by the locker.
            //Any object which replaces this must implement the ICharacterTag for locking to work properly.
            Body.CollisionInformation.Tag = new CharacterSynchronizer(Body);
        }
コード例 #4
0
            .1f;     //There's a little extra space above the maximum step height to start the obstruction and downcast test rays.  Helps when a step is very close to the max step height.

        /// <summary>
        /// Constructs a new step manager for a character.
        /// </summary>
        /// <param name="characterBody">The character's body.</param>
        /// <param name="contactCategorizer">Contact categorizer used by the character.</param>
        /// <param name="supportFinder">Support finder used by the character.</param>
        /// <param name="queryManager">Query provider to use in checking for obstructions.</param>
        /// <param name="horizontalMotionConstraint">Horizontal motion constraint used by the character. Source of 3d movement direction.</param>
        public StepManager(Cylinder characterBody, CharacterContactCategorizer contactCategorizer,
                           SupportFinder supportFinder, QueryManager queryManager,
                           HorizontalMotionConstraint horizontalMotionConstraint)
        {
            this.characterBody         = characterBody;
            currentQueryObject         = new ConvexCollidable <CylinderShape>(characterBody.CollisionInformation.Shape);
            ContactCategorizer         = contactCategorizer;
            SupportFinder              = supportFinder;
            QueryManager               = queryManager;
            HorizontalMotionConstraint = horizontalMotionConstraint;
            //The minimum step height is just barely above where the character would generally find the ground.
            //This helps avoid excess tests.
            minimumUpStepHeight =
                CollisionDetectionSettings.AllowedPenetration *
                1.1f; // Math.Max(0, -.01f + character.Body.CollisionInformation.Shape.CollisionMargin * (1 - character.SupportFinder.sinMaximumSlope));
        }
コード例 #5
0
        /// <summary>
        /// Constructs a stance manager for a character.
        /// </summary>
        /// <param name="characterBody">The character's body entity.</param>
        /// <param name="crouchingHeight">Crouching height of the character.</param>
        /// <param name="proneHeight">Prone height of the character.</param>
        /// <param name="queryManager">Provider of queries used by the stance manager to test if it is okay to change stances.</param>
        /// <param name="supportFinder">Support finder used by the character.</param>
        public StanceManager(Cylinder characterBody, float crouchingHeight, float proneHeight,
                             QueryManager queryManager, SupportFinder supportFinder)
        {
            QueryManager       = queryManager;
            SupportFinder      = supportFinder;
            this.characterBody = characterBody;
            standingHeight     = characterBody.Height;
            if (crouchingHeight < standingHeight)
            {
                this.crouchingHeight = crouchingHeight;
            }
            else
            {
                throw new ArgumentException("Crouching height must be less than standing height.");
            }

            if (proneHeight < crouchingHeight)
            {
                this.proneHeight = proneHeight;
            }
            else
            {
                throw new ArgumentException("Prone height must be less than crouching height.");
            }

            //We can share the real shape with the query objects.
            currentQueryObject  = new ConvexCollidable <CylinderShape>(characterBody.CollisionInformation.Shape);
            standingQueryObject = new ConvexCollidable <CylinderShape>(
                new CylinderShape(StandingHeight, characterBody.Radius)
            {
                CollisionMargin = currentQueryObject.Shape.CollisionMargin
            });
            crouchingQueryObject = new ConvexCollidable <CylinderShape>(
                new CylinderShape(CrouchingHeight, characterBody.Radius)
            {
                CollisionMargin = currentQueryObject.Shape.CollisionMargin
            });
            proneQueryObject = new ConvexCollidable <CylinderShape>(new CylinderShape(proneHeight, characterBody.Radius)
            {
                CollisionMargin = currentQueryObject.Shape.CollisionMargin
            });
            //Share the collision rules between the main body and its query objects.  That way, the character's queries return valid results.
            currentQueryObject.CollisionRules   = characterBody.CollisionInformation.CollisionRules;
            standingQueryObject.CollisionRules  = characterBody.CollisionInformation.CollisionRules;
            crouchingQueryObject.CollisionRules = characterBody.CollisionInformation.CollisionRules;
            proneQueryObject.CollisionRules     = characterBody.CollisionInformation.CollisionRules;
        }
コード例 #6
0
        /// <summary>
        /// Constructs a new character controller.
        /// </summary>
        /// <param name="position">Initial position of the character.</param>
        /// <param name="radius">Radius of the character body.</param>
        /// <param name="mass">Mass of the character body.</param>
        /// <param name="maximumTractionSlope">Steepest slope, in radians, that the character can maintain traction on.</param>
        /// <param name="maximumSupportSlope">Steepest slope, in radians, that the character can consider a support.</param>
        /// <param name="speed">Speed at which the character will try to move while crouching with a support that provides traction.
        /// Relative velocities with a greater magnitude will be decelerated.</param>
        /// <param name="tractionForce">Maximum force that the character can apply while on a support which provides traction.</param>
        /// <param name="slidingSpeed">Speed at which the character will try to move while on a support that does not provide traction.
        /// Relative velocities with a greater magnitude will be decelerated.</param>
        /// <param name="slidingForce">Maximum force that the character can apply while on a support which does not provide traction</param>
        /// <param name="airSpeed">Speed at which the character will try to move with no support.
        /// The character will not be decelerated while airborne.</param>
        /// <param name="airForce">Maximum force that the character can apply with no support.</param>
        /// <param name="jumpSpeed">Speed at which the character leaves the ground when it jumps</param>
        /// <param name="slidingJumpSpeed">Speed at which the character leaves the ground when it jumps without traction</param>
        /// <param name="maximumGlueForce">Maximum force the vertical motion constraint is allowed to apply in an attempt to keep the character on the ground.</param>
        public SphereCharacterController(
            Vector3 position           = new Vector3(),
            float radius               = .85f, float mass = 10f,
            float maximumTractionSlope = 0.8f, float maximumSupportSlope = 1.3f,
            float speed            = 8f, float tractionForce      = 1000, float slidingSpeed = 6, float slidingForce = 50,
            float airSpeed         = 1, float airForce            = 250,
            float jumpSpeed        = 4.5f, float slidingJumpSpeed = 3,
            float maximumGlueForce = 5000)
        {
            Body = new Sphere(position, radius, mass);
            Body.IgnoreShapeChanges = true; //Wouldn't want inertia tensor recomputations to occur if the shape changes.
            //Making the character a continuous object prevents it from flying through walls which would be pretty jarring from a player's perspective.
            Body.PositionUpdateMode        = PositionUpdateMode.Continuous;
            Body.LocalInertiaTensorInverse = new Matrix3x3();
            //TODO: In v0.16.2, compound bodies would override the material properties that get set in the CreatingPair event handler.
            //In a future version where this is changed, change this to conceptually minimally required CreatingPair.
            Body.CollisionInformation.Events.DetectingInitialCollision += RemoveFriction;
            Body.LinearDamping         = 0;
            ContactCategorizer         = new CharacterContactCategorizer(maximumTractionSlope, maximumSupportSlope);
            QueryManager               = new QueryManager(Body, ContactCategorizer);
            SupportFinder              = new SupportFinder(Body, QueryManager, ContactCategorizer);
            HorizontalMotionConstraint = new HorizontalMotionConstraint(Body, SupportFinder);
            HorizontalMotionConstraint.PositionAnchorDistanceThreshold = 3f / 17f * radius;
            VerticalMotionConstraint = new VerticalMotionConstraint(Body, SupportFinder, maximumGlueForce);
            PairLocker = new CharacterPairLocker(Body);

            Speed            = speed;
            TractionForce    = tractionForce;
            SlidingSpeed     = slidingSpeed;
            SlidingForce     = slidingForce;
            AirSpeed         = airSpeed;
            AirForce         = airForce;
            JumpSpeed        = jumpSpeed;
            SlidingJumpSpeed = slidingJumpSpeed;

            //Enable multithreading for the sphere characters.
            //See the bottom of the Update method for more information about using multithreading with this character.
            IsUpdatedSequentially = false;

            //Link the character body to the character controller so that it can be identified by the locker.
            //Any object which replaces this must implement the ICharacterTag for locking to work properly.
            Body.CollisionInformation.Tag = new CharacterSynchronizer(Body);
        }