0
\$\begingroup\$

I'm working on a Spider-Man like game and I've run into a problem. Whenever I'm near a wall and press the w key, the player starts climbing the wall. But when on the wall, I want it to face the direction of the input on the Z-axis only, such that, if I press , its head starts facing left, when I press , it rotates toward right and so on.

I've tried everything to no avail. I should add that I'm average at math so I'm really bad at rotations and quaternions, etc.

Attaching links to videos of the movement on wall, how I want the player to rotate and here's the function I'm using to climb.

/// <summary>
/// Move player RB in the climbing state.
/// </summary>
/// <param name="moveDir"></param>
protected void ClimbMovementRB()
{
    Vector3 inputVector = new Vector3(x: playerStateMachine.InputReader.HorizontalInput,
                                      y: playerStateMachine.InputReader.VerticalInput, z: 0);

    playerStateMachine.RB.velocity = playerStateMachine.transform
                                    .TransformDirection(inputVector * playerStateMachine.PlayerProperties.ClimbSpeed);

    playerStateMachine.PlayerModel.transform.rotation = Quaternion.Lerp(playerStateMachine.PlayerModel.transform.rotation,
                                                    Quaternion.LookRotation(inputVector, -playerStateMachine.transform.forward),
                                                    Time.deltaTime * playerStateMachine.PlayerProperties.RotationDamping);

    DragControl();
    ClimbSpeedControl();
}

The videos showing the problems.

\$\endgroup\$
0

2 Answers 2

0
\$\begingroup\$

Try something like this:

// Get camera 
// (you can cache this to avoid a search):
var cam =  Camera.main.transform;

// Transform input from screen space 
// (player perspective) to world space:
var worldDirection = cam.TransformDirection(inputVector);

// Capture direction of the wall we should align to
// (can also use a raycast and use the negative normal);
var intoWall = playerStateMachine.PlayerModel.transform.forward;

// Construct an orientation whose forward vector
// points exactly into the wall being climbed,
// and whose up vector points as close as 
// possible to worldDirection:
var orientation = Quaternion.LookRotation(
                     intoWall,
                     worldDirection
                  );

You can now lerp or slerp to this new orientation. It will keep the forward vector pointed into the wall, and point the player's up vector (which I'd assume points toward their head) to align with the screenspace direction pressed.


If your character model is oriented differently in the climbing pose - say with its "down" vector pointing into the wall and its head facing "forward", then you can tweak the orientation like so:

orientation = orientation * Quaternion.Euler(-90, 0, 0);

(And swap the definition of intoWall to use negative up instead)

\$\endgroup\$
1
  • \$\begingroup\$ Thank u so much. This solved multiple problems I was having. I really appreciate the help. \$\endgroup\$ Commented May 16 at 4:25
0
\$\begingroup\$

I am going to delete my earlier answer and build on DMGregory's answer instead ....

If your character model is oriented differently in the climbing pose...

If you have two poses "crawling" and "walking" technically you can be in either pose, either when on the floor or attached to the wall (although walking on the wall would look a bit weird).

Given this, when on the floor your up vector is locked to (0,1,0) when on the wall the up vector is locked to the surface normal.

Cutting to the chase, all you need to do when attaching to the wall is:

  • Switch the pose.
  • Rotate the root of the player character (90 degrees).
  • Lock up to the walls normal.
  • Move the player to the wall (after the pose switch, they will probably be a foot or two away)

All movements and rotations can now be applied to the players root directly - due to the rotation forward and up are initially the same thing - rotations will also work correctly when applied in the players local axes.

\$\endgroup\$
2
  • \$\begingroup\$ There was some good content in the previous version of the answer too, which fortunately is still preserved in the edit history. Folks can click the "edited" link at the bottom of the post if they want to review past versions. \$\endgroup\$
    – DMGregory
    Commented May 15 at 21:11
  • \$\begingroup\$ Thank u for the in detail explanation in both this and the edited version of your comment. Appreciate it. \$\endgroup\$ Commented May 16 at 4:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .