Character jumping behaviour

Character jumping behaviour

Mensagempor Treehouse Games » 25 Abr 2012, 11:13

Hi,

We're working on a platformer game and we need to be able to tweak the movement while the character is jumping. First we were using the standard CharacterController, but we couldn't change the jumping behaviour. So now, we have built a custom characterController, characterObject and bepuPhysicsWorld. These are currently all based on the standard code in the engine, that we got from the google repository.
We believe we have to change the HandleHorizontalMotion method of the CharacterController, but we don't fully understand what the function of supportLocationVelocity and the supportNormal are. If you could clarify this code a bit, it would help us out alot.
We think the solution lies in that code, but we're not entirely sure. If there is another (easier) way to change the jumping behaviour, please let us know.

Código: Selecionar todos
/// <summary>
        /// Manages movement acceleration, deceleration, and sliding.
        /// </summary>
        /// <param name="supportLocationVelocity">Velocity of the support point connected to the supportEntity.</param>
        /// <param name="supportNormal">The normal at the surface where the ray hit the entity.</param>
        /// <param name="dt">Timestep of the simulation.</param>
        private void HandleHorizontalMotion(Vector3 supportLocationVelocity, Vector3 supportNormal, float dt)
        {
            if (HasTraction && MovementDirection != Vector2.Zero)
            {
                //Identify a coordinate system that uses the support normal as Y.
                //X is the axis point along the left (negative) and right (positive) relative to the movement direction.
                //Z points forward (positive) and backward (negative) in the movement direction modified to be parallel to the surface.
                Vector3 x = Vector3.Cross(new Vector3(MovementDirection.X, 0, MovementDirection.Y), supportNormal);
                Vector3 z = Vector3.Cross(supportNormal, x);

                //Remove from the character a portion of velocity which pushes it horizontally off the desired movement track defined by the movementDirection.
                float bodyXVelocity = Vector3.Dot(Body.LinearVelocity, x);
                float supportEntityXVelocity = Vector3.Dot(supportLocationVelocity, x);
                float velocityChange = MathHelper.Clamp(bodyXVelocity - supportEntityXVelocity, -dt * TractionDeceleration, dt * TractionDeceleration);
                Body.LinearVelocity -= velocityChange * x;


                float bodyZVelocity = Vector3.Dot(Body.LinearVelocity, z);
                float supportEntityZVelocity = Vector3.Dot(supportLocationVelocity, z);
                float netZVelocity = bodyZVelocity - supportEntityZVelocity;
                //The velocity difference along the Z axis should accelerate/decelerate to match the goal velocity (max speed).
                if (netZVelocity > MaxSpeed)
                {
                    //Decelerate
                    velocityChange = Math.Min(dt * TractionDeceleration, netZVelocity - MaxSpeed);
                    Body.LinearVelocity -= velocityChange * z;
                }
                else
                {
                    //Accelerate
                    velocityChange = Math.Min(dt * Acceleration, MaxSpeed - netZVelocity);
                    Body.LinearVelocity += velocityChange * z;
                }
            }
            else
            {
                float deceleration;
                if (HasTraction)
                    deceleration = dt * TractionDeceleration;
                else
                    deceleration = dt * SlidingDeceleration;
                //Remove from the character a portion of velocity defined by the deceleration.
                Vector3 bodyHorizontalVelocity = Body.LinearVelocity - Vector3.Dot(Body.LinearVelocity, supportNormal) * supportNormal;
                Vector3 supportHorizontalVelocity = supportLocationVelocity - Vector3.Dot(supportLocationVelocity, supportNormal) * supportNormal;
                Vector3 relativeVelocity = bodyHorizontalVelocity - supportHorizontalVelocity;
                float speed = relativeVelocity.Length();
                if (speed > 0)
                {
                    Vector3 horizontalDirection = relativeVelocity / speed;
                    float velocityChange = Math.Min(speed, deceleration);
                    Body.LinearVelocity -= velocityChange * horizontalDirection;
                }
            }
        }
Treehouse Games
 
Mensagens: 1
Registrado em: 27 Mar 2012, 15:21
Area: Programador

Re: Character jumping behaviour

Mensagempor tpastor » 26 Abr 2012, 22:21

hi,

first of all, what behavior you want to achieve ?

before changing the functions you mentioned, my advice to you is to change the parameters of the following objects:
HorizontalMotionConstraint
VerticalMotionConstraint
and the properties of the CharacterController.

The word "Support" is used to mean the place where the character is in contact with (like the floor, a wall .....)

SupportVelocity is the speed of the entity you are in contact with (maybe the floor is not a static geometry ....)
Supportnormal is the normal where the ray with the origin in the character hits the support

To help you, here is the function that finds the support for the character (very commented)

Código: Selecionar todos
        /// <summary>
        /// Locates the closest support entity by performing a raycast at collected candidates.
        /// </summary>
        /// <param name="supportEntity">The closest supporting entity.</param>
        /// <param name="supportLocation">The support location where the ray hit the entity.</param>
        /// <param name="supportNormal">The normal at the surface where the ray hit the entity.</param>
        /// <param name="supportDistance">Distance from the character to the support location.</param>
        /// <returns>Whether or not a support was located.</returns>
        private bool FindSupport(out BEPUphysics.Entities.Entity supportEntity, out Vector3 supportLocation, out Vector3 supportNormal, out float supportDistance)
        {
            supportEntity = null;
            supportLocation = Toolbox.NoVector;
            supportNormal = Toolbox.NoVector;
            supportDistance = float.MaxValue;

            Vector3 rayOrigin = Body.Position + rayOriginOffset;
            for (int i = 0; i < collisionPairCollector.CollisionInformation.Pairs.Count; i++)
            {
                var pair = collisionPairCollector.CollisionInformation.Pairs[i];
                //Determine which member of the collision pair is the possible support.
                Collidable candidate = (pair.BroadPhaseOverlap.EntryA == collisionPairCollector.CollisionInformation ? pair.BroadPhaseOverlap.EntryB : pair.BroadPhaseOverlap.EntryA) as Collidable;
                //Ensure that the candidate is a valid supporting entity.
                if (candidate.CollisionRules.Personal >= CollisionRule.NoSolver)
                    continue; //It is invalid!

                //The maximum length is supportHeight * 2 instead of supportHeight alone because the character should be able to step downwards.
                //This acts like a sort of 'glue' to help the character stick on the ground in general.
                float maximumDistance;
                //The 'glue' effect should only occur if the character has a solid hold on the ground though.
                //Otherwise, the character is falling or sliding around uncontrollably.
                if (HasTraction)
                    maximumDistance = supportHeight * 2;
                else
                    maximumDistance = supportHeight;

                RayHit rayHit;
                //Fire a ray at the candidate and determine some details!
                if (candidate.RayCast(new Ray(rayOrigin, Vector3.Down), maximumDistance, out rayHit))
                {
                    //We want to find the closest support, so compare it against the last closest support.
                    if (rayHit.T < supportDistance)
                    {
                        supportDistance = rayHit.T;
                        supportLocation = rayHit.Location;
                        supportNormal = rayHit.T > 0 ? rayHit.Normal : Vector3.Up;

                        var entityInfo = candidate as EntityCollidable;
                        if (entityInfo != null)
                            supportEntity = entityInfo.Entity;
                        else
                            supportEntity = null;
                    }
                }
            }
            supportNormal.Normalize();
            return supportDistance < float.MaxValue;
        }


Here is where the jump is calculated
Código: Selecionar todos
//Attempt to jump.
            if (tryToJump && StanceManager.CurrentStance != Stance.Crouching) //Jumping while crouching would be a bit silly.
            {
                //In the following, note that the jumping velocity changes are computed such that the separating velocity is specifically achieved,
                //rather than just adding some speed along an arbitrary direction.  This avoids some cases where the character could otherwise increase
                //the jump speed, which may not be desired.
                if (SupportFinder.HasTraction)
                {
                    //The character has traction, so jump straight up.
                    float currentUpVelocity = Vector3.Dot(Body.OrientationMatrix.Up, relativeVelocity);
                    //Target velocity is JumpSpeed.
                    float velocityChange = Math.Max(jumpSpeed - currentUpVelocity, 0);
                    ApplyJumpVelocity(ref supportData, Body.OrientationMatrix.Up * velocityChange, ref relativeVelocity);


                    //Prevent any old contacts from hanging around and coming back with a negative depth.
                    foreach (var pair in Body.CollisionInformation.Pairs)
                        pair.ClearContacts();
                    SupportFinder.ClearSupportData();
                    supportData = new SupportData();
                }
                else if (SupportFinder.HasSupport)
                {
                    //The character does not have traction, so jump along the surface normal instead.
                    float currentNormalVelocity = Vector3.Dot(supportData.Normal, relativeVelocity);
                    //Target velocity is JumpSpeed.
                    float velocityChange = Math.Max(slidingJumpSpeed - currentNormalVelocity, 0);
                    ApplyJumpVelocity(ref supportData, supportData.Normal * -velocityChange, ref relativeVelocity);

                    //Prevent any old contacts from hanging around and coming back with a negative depth.
                    foreach (var pair in Body.CollisionInformation.Pairs)
                        pair.ClearContacts();
                    SupportFinder.ClearSupportData();
                    supportData = new SupportData();
                }
            }



Apply jump function
Código: Selecionar todos
void ApplyJumpVelocity(ref SupportData supportData, Vector3 velocityChange, ref Vector3 relativeVelocity)
        {

            Body.LinearVelocity += velocityChange;
            var entityCollidable = supportData.SupportObject as EntityCollidable;
            if (entityCollidable != null)
            {
                if (entityCollidable.Entity.IsDynamic)
                {
                    Vector3 change = velocityChange * jumpForceFactor;
                    entityCollidable.Entity.LinearMomentum += change * -Body.Mass;
                    velocityChange += change;
                }
            }

            //Update the relative velocity as well.  It's a ref parameter, so this update will be reflected in the calling scope.
            Vector3.Add(ref relativeVelocity, ref velocityChange, out relativeVelocity);

        }


The jump functions do just this:
Jumps the character off of whatever it's currently standing on. If it has traction, it will go straight up.
it doesn't have traction, but is still supported by something, it will jump in the direction of the surface normal.
PloobsEngine
Creator and Developer
ploobs.com.br/?page_id=1381
Avatar do usuário
tpastor
TechDemo
 
Mensagens: 700
Registrado em: 25 Mar 2011, 16:40

Re: Character jumping behaviour

Mensagempor studenthand » 13 Ago 2013, 03:23

The next time you are up for calvin klein sale on the net shopping, Niceorders will need to definitely be on top rated of your priorities.

Calvin klein underwear sale , Consumers frequently apply perfume on for the inner wrists, as they may be effective pulse points. In the 1990's small time rapper Marky Mark was featured on billboard ads wearing Calvin Klein boxers.

Calvin klein underwear australia , Coming to Calvin Klein they have retained a extremely monochromatic and thin garment aesthetic that has translated nicely towards the well-liked spirit of style.Calvin Klein Underwear is amongst the optimum and most reasonably priced lines of menswear you might ever consider.

Calvin klein underwear , Niceorders also provide ralph lauren, G Star Raw, Dsquared2, D&G,Hackett, Diesel, Abercrombie and lots of even more at outstanding price.

Calvin klein underwear cheap , The best aspect is that you don't get a stain in your favorite clothes when you are spraying it on your silky gowns.

Calvin klein underwear online , In addition the colors and the styles which are to be had for men's underwear have augmented the choices that guys have in selecting underwear for themselves.
studenthand
 
Mensagens: 5
Registrado em: 13 Ago 2013, 03:13
Area: Beta-tester


Voltar para Dúvidas

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

cron