Rotating Direction Vector by Character rotation to walk on walls

I am completely lost with this, I thought it would be simple but it just doesn’t seem to be working.

Let me preface this that I have tried using ProjectOnPlane, which just breaks as soon as I start walking on a 90 degree incline.

I’m trying to achieve what is pictured below

However I cannot understand how to rotate my movement vector.

I tried taking the rotation of my character (this.transform.rotation) and multiplying it by my movement Vector, however this doesn’t seem to work as the resulting vector points in seemingly random directions.

How can I rotate my Movement Direction Vector depending on either the ground I’m standing on or the rotation of my character?

You can use TransformDirection() to convert between local and world space. For example:

Vector3 myForward = transform.TransformDirection(Vector3.forward);

… would give you a vector roughly matching Vector3.up in your example picture.

This doesn’t seem to be changing anything.

What determines the local space in TransformDirection?

It converts from world space to the transform’s local space.

For example:

           // world:
           Vector3 input = Vector3.zero;
           input.z = Input.GetAxisRaw("Vertical");

           // local:
           Vector3 direction = transform.TransformDirection(input);

           transform.position += direction.normalized * 10.0f * Time.deltaTime;

Regardless of orientation, this code will always move the object forward. Pretty sure that’s exactly what you’re looking for.

Let me go through what I’m doing here because that is not working at all.

// Getting Inputs from the Stick
Vector3 stickDirection = new Vector3(InputManager.horizontal, 0, InputManager.vertical);

// Getting the Rotation of the camera 
Vector3 CameraDirection = camera.forward;
CameraDirection.y = 0.0f;
Quaternion referentialShift = Quaternion.LookRotation(CameraDirection);

// Multiplying Stick Vector with Camera Quaternion and transforming into world space
moveDirection = transform.TransformDirection(referentialShift * stickDirection);

This creates the red vector here, which is going straight through the wall

The yellow one is after using ProjectOnPlane with the normal of the ground.

What am I missing here?

Don’t multiply it by the rotation. TransformDirection handles all of the rotation and scale math for you.

Now my character doesn’t move depending on where the camera is

I’m not really sure how the camera is relevant. Could you elaborate? My code will move your character “forward” regardless of their orientation, so if they’re walking up a wall, pressing W will walk them up instead of into the wall. Is that not the issue we’re trying to solve?

Here’s an example of my code on objects of various rotations, all moving forward and backward in respect to their orientation, when you press W or S.

Have I misunderstood the problem?

No that is exactly the problem, but the rotation of the camera is needed because I need the character to move depending on the orientation of the camera.

Either way, even while not multiplying my Stick Vector with the Quaternion of the camera, my Movevement Vector (in red) still doesn’t adjust depending on the rotation of my character.

When you wrote “Don’t multiply it by the rotation”, you meant change this:

 moveDirection = transform.TransformDirection(referentialShift * stickDirection);

Into this:

 moveDirection = transform.TransformDirection(stickDirection);

Or did I misunderstand your post?

Yes, that’s what I meant.

Is the transform you’re using in that line of code the character’s transform? Is your character’s default orientation (rotation: 0, 0, 0) looking down the Z axis?

It is, however I am rotating my Armature (the model) and the Collider separately. Could that be the problem?

I’m also moving by changing rb.velocity, and it now dawns on me that it might be why this isn’t working.

Use the transform of whatever has the more accurate representation of the orientation of the character. Moving via velocity shouldn’t matter.

If all else fails, fall back to an empty GameObject with my code and try to figure out what other factors could be giving you incorrect values because like I posted in my gif, the code definitely moves forward and back relative to orientation.

1 Like

I’ve been working with your suggestions and you were completely right.

The first problem was that I wasn’t using a specific rotation to use TransformDirection, so I changed it to use the rotation of my collider. However my collider was also rotating around itself, which meant that moving in any direction would make my character spin on himself.

So I made an empty gameobject, gave it only a Y rotation and a W rotation, then used its rotation with TransformDirection and everything worked.

Thank you!

1 Like