x


Walljumping and Vector.Reflect

/Free Cake for anyone who can solve this/

I'm trying to write a Walljumping function using Vector.Reflect, and I managed to getting to work somewhat, but the reflection only works when the character is facing the forward direction (if the camera is facing behind him).

//=====================================================================
// ApplyWalljump
// -Not Working all the way yet........................................
//=====================================================================
function ApplyWallJump ()
{
    var jumpButtonPressed = Input.GetButtonDown("Jump"); 

    //Checks to see if the player is against a wall and trips a flag
    if ((controller.collisionFlags & CollisionFlags.CollidedSides) != 0 )
    {isAgainstWall = true;}
    else
    {isAgainstWall = false;}

    // We must actually jump against a wall for this to work
    if (!isJumping)
    return;

    if (isAgainstWall && jumpButtonPressed && !controller.isGrounded )
    {
        //isWalljumping = true;
       var reflectedMoveDirection : Vector3 = Vector3.Reflect (moveDirection, transform.forward);

       reflectedMoveDirection.y = y;
       reflectedMoveDirection.y -= gravity * Time.deltaTime;     

       transform.rotation = Quaternion.LookRotation(Vector3(reflectedMoveDirection.x, 0, reflectedMoveDirection.z)); 
       controller.Move(reflectedMoveDirection * Time.deltaTime);
    }  
}

How can I adjust the Reflection Direction so that the character will go into the opposite direction when he jumps against the wall, no matter where he jumps from?

If you need to see how the movement is set up, check it below:


//=====================================================================
// CalculateMovement
//=====================================================================
function CalculateMovement()
{
    //Get the Inputs
    x  = Input.GetAxis("Horizontal");
    z  = Input.GetAxis("Vertical"); 
    y  = moveDirection.y;

    var jumpButton = Input.GetButton("Jump");
    var jumpButtonPressed = Input.GetButtonDown("Jump"); //SMH
    controller = GetComponent(CharacterController);

    var cameraTransform : Transform  = Camera.main.transform;

    //Get the forward vector from the camera
    var forward : Vector3 = cameraTransform.TransformDirection(Vector3.forward);
    forward.y = 0;
    forward = forward.normalized;

    // Right vector relative to the camera 
    var right = Vector3(forward.z, 0, -forward.x);

    //Make sure that the movement is relative to the camera
    moveDirection = x * right + z * forward;

    //Speed the Character up
    moveDirection *= speed;

    //Orient the Player Accordingly
    if (moveDirection != Vector3.zero  && !onLedge)
    {
       transform.rotation = Quaternion.LookRotation(Vector3(moveDirection.x, 0, moveDirection.z));   
    }
    //This is needed, otherwise the character can't move while jumping
    moveDirection.y = y;

    //MAKE SURE JUMP ALWAYS COME AFTER ROTATION!!!!
    if (jumpButtonPressed && controller.isGrounded && canJump) 
    {
         ApplyJump(jumpHeight);
        isJumping = true;
    }
    else if (jumpButtonPressed && !controller.isGrounded && canJump && canDoubleJump) 
    {
       ApplyJump(jumpBoost);
       canJump = false;
    }

    //This Area is For Gliding
    if (jumpButton && !controller.isGrounded && moveDirection.y <= 0.0 && canGlide)
    {isGliding = true;}
    else
    {isGliding = false;}

    //If not on the ground
    if (!controller.isGrounded)
    {
       isAirborne = true;
    }
    //This checks to see if the player is on the ground, or if the player is on the ground and decides to walk off the side of something
    else if (controller.isGrounded && moveDirection.y <= 0.0)
    {
       isAirborne = false;     
       isJumping = false;
       canJump = true;
       isWalljumping=false;
       moveDirection.y = 0;
    }
}


//=====================================================================
// ApplyMovement
//=====================================================================
function ApplyMovement()
{
    if (!isGliding && (!onLedge && !onWall))
    {
       // Apply gravity
       moveDirection.y -= gravity * Time.deltaTime;
    }
    else
    {
       // Apply gravity at a reduced rate
       moveDirection.y -= glideGravity * Time.deltaTime;
    }

    // Move the controller
    if (!onLedge && !onWall && !isWalljumping)
    {
       controller.Move(moveDirection * Time.deltaTime);
    }

}
more ▼

asked Sep 25 '11 at 03:21 AM

SirVictory gravatar image

SirVictory
1.8k 66 77 107

(comments are locked)
10|3000 characters needed characters left

2 answers: sort voted first

Like Bunny said, you want to use hit.normal. However, you don't want to reflect it at all. What you would actually want to do is to apply the normal + Vector3.up when the character is using the wall jump. You also might want to apply a wall jump variable. Like so:

if(isWalljumping)
    {
       controller.Move(hit.normal*Time.deltaTime+Vector3.up*wallJump);
    }

Also be aware that you might need to change your character's forward to match the new direction.

This is much different than a true reflection of the character's velocity. As you may have noticed, most games make the player jump between two walls to get to the top. They take the perpendicular direction (the normal) and send the character that way.

Now just make sure you trip your flag off once the total force is applied.

more ▼

answered Sep 27 '11 at 01:09 AM

SirGive gravatar image

SirGive
1.2k 25 32 50

Thanks, kinda got it working for the most part, the tripping flag tripping however needs to be tweaked, because the player will just stop and free fall...

Sep 27 '11 at 01:17 AM SirVictory

Of course that's another way but it's an unnatural movement. If you jump at the wall in an narrow angle you would suggest to jump from the wall in the same angle and not 90° off the wall. Adding additional up-speed is self-evident since you perform a jump.

Sep 27 '11 at 03:13 AM Bunny83
(comments are locked)
10|3000 characters needed characters left

You have to reflect the movedirection at the surface normal and not at Vector3.forward. You have to save the normal-vector when you hit the wall so you can use it when you want to walljump.

You have to implement a OnControllerColliderHit function and there check for a side-collision and save the hit.normal in a variable.

more ▼

answered Sep 25 '11 at 11:52 AM

Bunny83 gravatar image

Bunny83
46.9k 12 50 210

how do you do this? could you give an example?

Nov 30 '12 at 03:49 AM shane.rachel

Just use Vector3.Reflect like in the question above but use the hit normal as surface normal ;)

Nov 30 '12 at 09:30 AM Bunny83

It's funny. A year later, and this is also seems elementary to me :D

Nov 30 '12 at 09:33 AM SirVictory
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1948
x205
x13
x3
x1

asked: Sep 25 '11 at 03:21 AM

Seen: 1338 times

Last Updated: Nov 30 '12 at 09:33 AM