#Rotation based on a different upaxis than normal

1 messages · Page 1 of 1 (latest)

solemn pumice
#

I'm making a game where you can walk on planets and rotate around them, the movement script I have is from CatLikesCoding (will send link on request if needed) And then there's a seperate rotation script which references that to get the velocity directions. I'm having issues to make the rotation work properly, here's how the code looks like for now in the rotation: ```cs
//The upAxis is gained from a CustomGravity script and //returns 2 things, 1: the gravity pull direction, and the //upaxis (which is just the opposite of the pull direction)

//the GetLookDirection() returns the player velocity, //normalized
if (!playerMovement.OnGround)
{
Vector3 forwardDirection = playerMovement.GetLookDirection();
Vector3 upAxis = playerMovement.UpAxis;

        Quaternion rotation = Quaternion.LookRotation(forwardDirection, upAxis);
        //rotation.Normalize();
        rotation.x = 0f;

//player kept tiling on the x-axis so set that to 0
transform.rotation = rotation;
}
else if (inputs.magnitude > velocityThreshHold && !playerMovement.DesiredJump)
{
Vector3 forwardDirection = playerMovement.GetLookDirection();
Vector3 upAxis = playerMovement.UpAxis;

        Quaternion rotation = Quaternion.LookRotation(forwardDirection, upAxis);
        //rotation.Normalize();
        transform.rotation = rotation;
    }
#

found it hard to google as well as usually people don't change the upAxis🥹

solemn pumice
#

Rotation based on a different upaxis than normal

pure agate
#

@solemn pumice what does the player look direction func look like

#

and why is it so badly named

solemn pumice
# pure agate <@265155253513486337> what does the player look direction func look like

It's a bad name because 1. its a rough draft, 2. rotations/directions are confusing to me so I have little experience to know how to create a good naming convention around that:P Here's the function: alongside what how the "velocity" is calculated. I also want to add, that code is from CatLikeCoding and is relative movement ```cs

public Vector3 GetLookDirection()
{
// Debug.Log("forwardaxis: " + forwardAxis + " velocity direction???: " + velocity.normalized);
return velocity.normalized;
}

//the upcoming part has with changing the velocity to do

void AdjustVelocity() //changed
{
float acceleration;
Vector3 xAxis, zAxis;

    walkOrRunSpeed = (Input.GetKey(KeyCode.LeftShift)) ? maxRunSpeed : maxWalkSpeed;
    acceleration = OnGround ? maxAcceleration : maxAirAcceleration;

    xAxis = rightAxis;
    zAxis = forwardAxis;
    
    xAxis = ProjectDirectionOnPlane(xAxis, contactNormal);
    zAxis = ProjectDirectionOnPlane(zAxis, contactNormal);

    //Debug.Log("xAxis: " + xAxis + "zAxis: " + zAxis);

    Vector3 relativeVelocity = velocity - connectionVelocity;
    float currentX = Vector3.Dot(relativeVelocity, xAxis);
    float currentZ = Vector3.Dot(relativeVelocity, zAxis);

    //float acceleration = OnGround ? maxAcceleration : maxAirAcceleration;
    float maxSpeedChange = acceleration * Time.deltaTime;

    float newX = Mathf.MoveTowards(currentX, playerInput.x * walkOrRunSpeed, maxSpeedChange);
    float newZ = Mathf.MoveTowards(currentZ, playerInput.y * walkOrRunSpeed, maxSpeedChange);

    velocity += xAxis * (newX - currentX) + zAxis * (newZ - currentZ);
}
#

Also since you pointed it out, can you come with an example to how I can make a better naming convention for it? I want to improve :). Generally I name things for what they are/do (which I've read in a book about clean code) However practise makes perfect. So that's what I thought I did for that as well, by naming it GetLookDirection....

#

I suppose a better name could be GetVelocity .. cause that's exactly what it does... :(

pure agate
#

Or getvelocitynormalized 👍

#

So is this rigidbody based movement or transform manipulation

solemn pumice
solemn pumice
pure agate
#

what is this velocity variable

solemn pumice
#

It stores the calculated/desired movement and applies it to the rigidbody, let me show some more code:

#
void FixedUpdate(){

EvaluateGravitySource();
        
        UpdateState();
        AdjustVelocity();

        if (desiredJump)
        {
            desiredJump = false;
            Jump(gravity);
        }

        if (desiredDash)
        {
            desiredDash = false;
            Dash();
        }
        
        if (OnGround && velocity.sqrMagnitude < 0.01f)
        {
            velocity += contactNormal * (Vector3.Dot(gravity, contactNormal) * Time.deltaTime);
        }
        else
        {
            velocity += gravity * Time.deltaTime;
        }

body.velocity = velocity;
        transform.up = upAxis;
        ClearState();
}
pure agate
#

don't be afraid to show more it's not like I'm going to run off with your game lol

solemn pumice
#

it's also available on catlikescoding xD

#

but yeah you are right

pure agate
#

so does catlike get the rotation working? how is your system different?

solemn pumice
#

He doesn't include it at all :/

#

or in his last course, but that's for rotating a ball, so he's using some PI math that is relevant for how a ball would rotate

#

I would show the whole script, but it's 440 lines and not everything is related (at least I doubt very much that it is)

pure agate
#

Do you want to firmly lock the rotation so it's always aligned with the planet normal?

#

Or more of a slerp solution

solemn pumice
#

First option, at least for now. I think that's more responsive for the player to get the quick rotation feel.. I might be wrong

pure agate
#

The naming killed you

#

You're pretending that the normalized velocity is the forward when it's not

#

Perfectly explains why the player tilts when jumping

solemn pumice
#

🫠 damn.. so how do I get the forward?

#

is it as simple as the zAxis🤔 feel like I've already tried that a couple days ago

pure agate
#

try it out

solemn pumice
#

Yes will do

solemn pumice
#

the jump is now fine, now however it wont' turn left/right if I press those. But I guess I just need to also retun the rightAxis and use that as well

#

However, it is rotating the correct axis based on where I look, but I just also want to be able to rotate by walking right or left

pure agate
solemn pumice
#

yeah ^^

pure agate
#

and the camera should also move with the player but not rotate?

#

unless the input makes it rotate I guess

solemn pumice
#

yeah sounds correct

pure agate
#

so right now what is your behavior

solemn pumice
#

Now its rotating forward relative to the camera, so if I look to the left and press W player will rotate to where the camera is looking. however I want it the same way as the video above

#

So if I look forward, and press A, player should go towards and rotate towards left.

solemn pumice
#

its rotating only forward based on where the camera is facing

#

So if I rotate the camera to look left without moving, then only the camera rotates. However if I press W I start walking in that direction and rotate towards that direction

pure agate
#

look forward and press a what happens

solemn pumice
#

aaah, actually pressing any of the WASD keys will rotate the player forward right now

pure agate
#

cursed

solemn pumice
#

yeah.... :()

pure agate
#

The problem as I understand it is getting a direction relative to the camera?

solemn pumice
#

Yeah I think so? relative to the camera, and the players upaxis, but I think once the first is solved it also solved the latter..?

pure agate
#

I'm confused why it worked in the video but not after the change you made

solemn pumice
#

ehm so the message was too big so had to create a message file for it

pure agate
#

use pastemyst

#

[]cb

foggy monolithBOT
#

Use codeblocks to send code in a message!

To make a codeblock, surround your code with ```
To use C# syntax highlighting add cs after the three back ticks.

For example:
```cs
Console.WriteLine("Hello World");
```

Produces:

Console.WriteLine("Hello World");

To send lengthy code, paste it into https://paste.myst.rs/ and send the link of the paste into chat.

solemn pumice
pure agate
#

It's not in The code your sent

solemn pumice
# pure agate I'm confused why it worked in the video but not after the change you made

I can go more in detail exactly what I changed: ```
//replaced what gets returned
public Vector3 GetForwardAxis()
{
//return velocity.normalized
return zAxis;
}

//Then in the script that rotates the player:
//the else if statement here is redundant if it works properly.. this is to prevent a //default rotation of facing the ground
else if (inputs.magnitude > velocityThreshHold && !playerMovement.DesiredJump)
{
Vector3 forwardDirection = playerMovement.GetForwardAxis();
Vector3 upAxis = playerMovement.UpAxis;

        Quaternion rotation = Quaternion.LookRotation(forwardDirection, upAxis);
        //rotation.Normalize();
        transform.rotation = rotation;
    }
solemn pumice
#

They were previously defined in the AdjustVelocity function, which I just commented out for now

pure agate
#

How are they defined

solemn pumice
#
Vector3 xAxis, zAxis;```
#

The rest is in the AdjustVelocity function, it's the only place they are being used/ set

pure agate
#

so they're undefined?? Or just zero

solemn pumice
#

yeah, but in the AdjustVelocity they are set : ```cs

    xAxis = rightAxis;
    zAxis = forwardAxis;
pure agate
#

No the other ones lol

#

Right forward

solemn pumice
#

oh :()... sorry xP

#

void Update()
    {
        playerInput.x = Input.GetAxis("Horizontal");
        playerInput.y = Input.GetAxis("Vertical");
        playerInput = Vector2.ClampMagnitude(playerInput, 1f); 

        if (playerInputSpace) 
        {
            rightAxis = ProjectDirectionOnPlane(playerInputSpace.right, upAxis);
            forwardAxis = ProjectDirectionOnPlane(playerInputSpace.forward, upAxis);
        }
        else
        {
            rightAxis = ProjectDirectionOnPlane(Vector3.right, upAxis);
            forwardAxis = ProjectDirectionOnPlane(Vector3.forward, upAxis);
        }

        desiredJump |= Input.GetButtonDown("Jump");
        desiredDash |= Input.GetKeyDown(KeyCode.F);

        
    }
#

and the playerInputSace is a type Transform, where I put the camera as a reference

#

So they're the camera

#

the elseis a bit reduntant because it will always be the camera, but I guess catlikescoding-guy wanted to have a default

pure agate
#

So how does the player currently move

#

Show that code

#

Evidently the other axis isn't being accounted for right?

solemn pumice
#

which axis? the rightAxis?

#

so, I feel like most of the code has been shown in bits so I just pasted everything in here now, warning: its messy, I do plan on cleaning it up in the future :p

pure agate
#

Oof so many bugs

solemn pumice
solemn pumice
pure agate
#

No not related to problem at hand

solemn pumice
#

ok greatkekdog

pure agate
#

Can you debug draw those vectors

#

Forward and right

solemn pumice
#

sure! I have a meeting now so will right after that! hopefully it won't take long

solemn pumice
#

@pure agate This video is the result of the following ```cs
private void OnDrawGizmos()
{
Debug.DrawLine(transform.position, forwardAxis);
Debug.DrawLine(transform.position, rightAxis);
}

#

I'm assuming that I did it correct...

pure agate
#

the heck

#

those axes are supposed to be perpendicular

solemn pumice
#

:/

#

and I'm guessing that's an issue :(

#

highly educated guess.

pure agate
#

yeah

solemn pumice
#

maybe there's something with my GizmosDrag code? or does that look fine to you?

solemn pumice
pure agate
#

maybe

pure agate
#

the vectors are like sticking to the ground that's so strange

#

debug log the up axis too

solemn pumice
pure agate
#

debug draw 😄

#

your projection code looks correct, i don't see why the axes are so wonky

#

debug draw the inputspace axes

solemn pumice
pure agate
#

the forward and right axes should be totally flat right. if they are relative to the plane you're on

solemn pumice
#

what if the pivot of my Player is in the air?

#

The red line is the upAxis using this code: ```

    Debug.DrawLine(transform.position, upAxis, Color.red);
#

but it's just drawing a line from the player to the vector3 coordinates isn't it?🤔

pure agate
#

OH

#

its Draw(start, end)

#

so your end needs to be transform.position + upAxis

solemn pumice
#

but what goes into start?

pure agate
#

same as you had before

solemn pumice
#

ok yeah: looks better now x)

pure agate
#

niice

#

show all of them? vid pls or gif

#

or just ss

solemn pumice
#

ok, I'll ad the input as well

#

will send a video soon

pure agate
#

so that blue one looks perfect for doing the rotation

#

right?

solemn pumice
solemn pumice
# pure agate right?

ok so it works fine on flat ground, however on a planet it fcks up again... :/

pure agate
#

now you have those vectors to help you debug

solemn pumice
#

yeah true, but it seems odd to me, I recorded some more to show how the axis behave on the planet

pure agate
#

hahah he gave up at the end

solemn pumice
#

yup xD

pure agate
#

so the white and red axes are good

#

that blue one is a bit funky

solemn pumice
#

yeah :/

pure agate
#

show blue-related code

solemn pumice
#
//in the gizmos:
Vector3 input = new Vector3(playerInput.x, 0f, playerInput.y);
Debug.DrawLine(transform.position, transform.position + input, Color.blue);

pure agate
#

oh

#

well obviously its a bit messed up lol you're moving the player relative to the camera but not relative to what its standing on

#

wait actually how are you moving the player

solemn pumice
# pure agate well obviously its a bit messed up lol you're moving the player relative to the ...

I thught this part did that ```cs
void AdjustVelocity() //changed
{
float acceleration;
//Vector3 xAxis, zAxis;

    walkOrRunSpeed = (Input.GetKey(KeyCode.LeftShift)) ? maxRunSpeed : maxWalkSpeed;
    acceleration = OnGround ? maxAcceleration : maxAirAcceleration;

    xAxis = rightAxis;
    zAxis = forwardAxis;
    
    xAxis = ProjectDirectionOnPlane(xAxis, contactNormal);
    zAxis = ProjectDirectionOnPlane(zAxis, contactNormal);

    //Debug.Log("xAxis: " + xAxis + "zAxis: " + zAxis);

    Vector3 relativeVelocity = velocity - connectionVelocity;
    float currentX = Vector3.Dot(relativeVelocity, xAxis);
    float currentZ = Vector3.Dot(relativeVelocity, zAxis);

    //float acceleration = OnGround ? maxAcceleration : maxAirAcceleration;
    float maxSpeedChange = acceleration * Time.deltaTime;

    float newX = Mathf.MoveTowards(currentX, playerInput.x * walkOrRunSpeed, maxSpeedChange);
    float newZ = Mathf.MoveTowards(currentZ, playerInput.y * walkOrRunSpeed, maxSpeedChange);

    velocity += xAxis * (newX - currentX) + zAxis * (newZ - currentZ);
}```
#

the code block above has with moving the player to do

pure agate
#

debug draw the xAxis and zAxis right where you have that debug log

solemn pumice
#

do you mean opposite? log it where its drawn on the planet?

pure agate
#

you should draw it because i can't see numbers in 3d lol

solemn pumice
#

ohh sry, yeah

pure agate
#

actually, debug draw this value xAxis * (newX - currentX) + zAxis * (newZ - currentZ). that represents your total movement

#

wait where is the rotation of the player being set again?

solemn pumice
solemn pumice
#

the second script is on a mesh which is a child of the actual gameobject that moves

pure agate
#

so that's working fine

solemn pumice
#

I used this code: ```cs

    Debug.DrawLine(transform.position, transform.position + velocity, Color.green);
pure agate
#

eh good enough

solemn pumice
#

yup but if I use that directly it's bascially the same as I had before making this post. The weird thing while jumping happens. Also if I stop moving Player faces the ground..

pure agate
#

aha yes

#

so the forwardAxis controls your player rotation
it is set here

forwardAxis = ProjectDirectionOnPlane(playerInputSpace.forward, upAxis);
solemn pumice
#

checks out^^

pure agate
#

and read here

            Vector3 forwardDirection = playerMovement.GetForwardAxis();
            Vector3 upAxis = playerMovement.UpAxis;

            Quaternion rotation = Quaternion.LookRotation(forwardDirection, upAxis);
            //rotation.Normalize();
            rotation.x = 0f;
            transform.rotation = rotation;
#

so if you don't move, you have no forward component so your player faceplants

solemn pumice
#

yes

pure agate
#

now actually setting the player rotation based off the velocity could work lol

#

i don't recommend it but if you want a quick fix and a big headache later

solemn pumice
#

well, how will it become a headache later :(

#

But that's basically how I did it before? by using the "velocity"

pure agate
pure agate
solemn pumice
solemn pumice
pure agate
#

If you want to solve the tilting when jumping problem just project the velocity vector onto the movement plane

#

Do you have a question 😂

solemn pumice
#

so, the question is:

#

What is projecting and what does it do

#

why you do it is also a great question

pure agate
#

hmmmmmmm

#

What is your knowledge of vectors? I'm asking because if you don't know enough I can't properly explain this

#

You might also just want to look at other resources like YouTube to understand projection as a mathematical concept and then I can bridge it to game Dev

#

Or I can give you a super simple but incomplete answer so you can move forward

solemn pumice
#

like basic + and *

#

I'd say I know basic Vector

pure agate
#

Are you familiar with components of vectors

solemn pumice
#

no I'm not :/ though english is not my mother language, and I'm not sure if my language might use other words for stuff

#

but let's just assume I don't

solemn pumice
solemn pumice
#

ah, the scalar values, heard of them yeah

#

I recall it faintly from math

pure agate
#

okay so let me take a stab at this

#

at the heart of projection is the question: how much of this vector goes along this direction (or plane)
so when I say project vector A onto vector B or plane P, i mean how much of vector A goes in the direction of vector B or plane P

#

you can think of the projected vector like a shadow

solemn pumice
#

is the result that blue line?

pure agate
solemn pumice
#

so the Vector3.ProjectOnPlane does that?

#

and the second parameter would be the upAxis?

pure agate
#

so a plane can be defined in two ways

#

two vectors can define a plane

#

or a plane can be defined by its normal

pure agate
solemn pumice
pure agate
#

yes try that out

solemn pumice
#

and also the fact that without the commented out line, the player will face-plant ```cs
else //if (inputs.magnitude > velocityThreshHold && !playerMovement.DesiredJump)
{
Vector3 forwardDirection = playerMovement.GetVelocityNormalized();
Vector3 upAxis = playerMovement.UpAxis;

        Quaternion rotation = Quaternion.LookRotation(forwardDirection, upAxis);
        rotation.Normalize();
        transform.rotation = rotation;
    }
pure agate
#

it makes sense that the player face plants

solemn pumice
pure agate
#

Well think about the intention

#

You want the rotation to match the velocity .. kind of

#

just not when the velocity is zero

#

if you were to explain it in English, you want the rotation to match the last non zero velocity the player had

solemn pumice
#

So just as long as the velocity is greater than 0 do the rotation?

pure agate
#

That is one way to do it

solemn pumice
#

I'll try it out, but I got a feeling that the player will still tilt a bit

pure agate
#

@solemn pumice why

solemn pumice
# pure agate <@265155253513486337> why
if (playerMovement.GetVelocity().magnitude > 0)
        {
            Vector3 rotateDirection = playerMovement.GetProjectedVector();
            Vector3 upAxis = playerMovement.UpAxis;

            Quaternion rotation = Quaternion.LookRotation(rotateDirection, upAxis);
            rotation.Normalize();
            transform.rotation = rotation;
        }
``` The result is that he faceplants :/ but I might have done it incorrectly
#

So I think the better way is to make sure that in the function where I return the ProjectedVector, I write a logic to not return it if player is not moving, but then I have to return something else, so I thought maybe I have to return the last "velocity step" (or what you¨d call it).

#

But I can't figure a way to do that

pure agate
#

That is a good idea, but would be a badly named function

#

Yeah actually meh

#

You just store the last non zero velocity

pure agate
#

This is actually what you want

solemn pumice
#

what's a good approach for that? the only way I can think of is this: ```cs
if(velocity.magnitude > 0)
Vector3 lastStep = velocity;

pure agate
#

This avoids the final projection to cancel y velocity

pure agate
#

Maybe have a tolerance on the magnitude

#

Like 0.1 or something

solemn pumice
#

hm yeah I'll try that

pure agate
#

It won't be noticeable but might make it run smoothly

#

Why do you normalize the rotation

solemn pumice
#

that's a good question, I commented it out then now back in, it's not supposed to be there

solemn pumice
# pure agate It won't be noticeable but might make it run smoothly

Tried now but I must be doing something wrong ```cs
//this code is being set inside the AdjustVelocity()
if(velocity.magnitude > 1f)
lastVelocityStep = xAxis * (newX - currentX) + zAxis * (newZ - currentZ);

public Vector3 GetProjectedVector()
{
Vector3 projectedVector = Vector3.ProjectOnPlane(velocity, upAxis);
lastVelocityStep = Vector3.ProjectOnPlane(lastVelocityStep, upAxis);
if (velocity.magnitude > 0)
return projectedVector;
else
return lastVelocityStep;
}

#

wait I forgot the threshhold

#

see it now

pure agate
#

Okay you're mixing two things. One is the actual player velocity, and the other is the input vector

#

They're similar but not exactly the same and I suggest you stick to using one of them

solemn pumice
#

yeah... where is this happening btw? in the rotation script?

pure agate
#

You would know more than me

#

Question: why do you have so many player related scripts

solemn pumice
#

Like, why I have one for rotating and one for movement?

#

Figured it would be cleaner to seperate movement with the script that handles the player mesh /animations/rotations.. I might be wrong though

pure agate
#

It seems like you're passing values back and forth between the two

solemn pumice
#

For now I've only been passing values from the movement to the PlayerAnimations for the rotation

#

Btw it seems to work, except from when jumping while standing still.

pure agate
#

That makes sense do you know why

solemn pumice
#

not really :p my first thoughts is that it might have something to do with the lastVelocityStep

#

Oh wait

#

it is because I only assign the movement and not the jump as well.... let me try one thing lol

pure agate
solemn pumice
#

ok it didn't work kekdog I did this first ```cs
if(velocity.magnitude > 1f)
lastVelocityStep = xAxis * (newX - currentX) + zAxis * (newZ - currentZ);

Then I changed it up with this cs
if(velocity.magnitude > 1f)
lastVelocityStep = velocity;

solemn pumice
#

idk if that's correct

pure agate
#

what doesn't account for the upaxis

solemn pumice
#

the lastVelocityStep

pure agate
#

oh

#

so yeah, changing the lastVelocityStep to equal velocity includes the upaxis, but there's another line of code that removes the upaxis part later

solemn pumice
#

does it have to do with the jump?

#

or in UpdateState... ```cs
velocity = body.velocity;

#

I'm not sure =)

pure agate
#

lastVelocityStep variable specifically

solemn pumice
#
lastVelocityStep = Vector3.ProjectOnPlane(lastVelocityStep, upAxis);
pure agate
#

yes

solemn pumice
#

interesting.. but if I don't do that line, won't it be weird when jumping?

#

one way to find out I guess

pure agate
solemn pumice
#

hm yeah

pure agate
#

think about the problem more broadly rather than focusing on some code that might be interfering with your current approach

#

what is the problem we currently have?

solemn pumice
#

If I jump while standing still, the rotation is off/weird

pure agate
#

okay good

#

so why is that happening

solemn pumice
solemn pumice
#

So when player jump while standing still, the direction is weird because it's supposed to get a direction based on the rightAxis and forwardAxis. So when jumping up those axis's are 0, and the only direction left on the velocity is, or should be the upAxis

#

idk what I'm doing xD the above message don't make sense lol

pure agate
#

yeah sure that sounds right

solemn pumice
#

so then it has something to do with the upAxis not being included

#

Do I have to make another "state" for when the player is jumping, and give a new rotation based on that? ....

solemn pumice
#

So I did a debug.drawLine on the lastVelocityStep, and it goes away when I jump while standing still. So I'm thinking that I need to somehow also save the upAxis on that, but it's what I thought velocity did. However you already pointed out where it gets ruled out... so how do I include it back..🤔

pure agate
#

why do you want to include upAxis?

#

why do we get rid of the upAxis part of the velocity vector in the first place?

solemn pumice
#

ah because of the tilt..?

pure agate
#

clarify what you mean by tilt

solemn pumice
#

the player tilting on the x-axis... however while writing that I realize it's not it right.. because we prevent that with the threshhold

solemn pumice
#

Never been closer though, but stilll not there

pure agate
# solemn pumice the player tilting on the x-axis... however while writing that I realize it's no...

to test what you say

public Vector3 GetProjectedVector()
    {
       Vector3 projectedVector = Vector3.ProjectOnPlane(velocity, upAxis);
        lastVelocityStep = Vector3.ProjectOnPlane(lastVelocityStep, upAxis);
        if (velocity.magnitude > 0)
            return projectedVector;
        else
            return lastVelocityStep;
    }

Remove the projections:

public Vector3 GetProjectedVector()
    {
       Vector3 projectedVector = velocity;
        //lastVelocityStep = Vector3.ProjectOnPlane(lastVelocityStep, upAxis);
        if (velocity.magnitude > 0)
            return projectedVector;
        else
            return lastVelocityStep;
    }
#

You state that the threshold prevents tilting. So removing the projections and keeping the threshold should still prevent tilting

solemn pumice
#

oh... no that dont' sound right

#

Ah yeah it's the ProjectOnPlane that prevents it because we needed to make sure to get a Vector that didn't "tilt" the way the velocity does by jumping

#

the threshhold is to prevent faceplanting

pure agate
#

correct

solemn pumice
#

So there's something odd while in air and not pressing any keys... I just don't get how to fix that properly.

#

If I'm correct, it has something to do with the velocity being 0 on the right and left axis, which somehow gives the player a weird rotation while in air🤔

pure agate
#

that sounds right

solemn pumice
#

I still don't know what to do about it though

pure agate
#

let's summarize what we're doing. we want the player to rotate in the direction of the last non zero horizontal velocity vector

#

we first used a projection to find the horizontal (flat on the plane) velocity vector instead of the entire vector. we did this to solve tilting.

#

next we used a threshold to only update the player's last velocity when it is greater than zero. we did this to solve faceplanting when the player wasn't moving

#

there is however a bug in the code

#

i want you to debug which vector is being returned by the GetProjectedVector function

solemn pumice
#
public Vector3 GetProjectedVector()
    {
       Vector3 projectedVector = Vector3.ProjectOnPlane(velocity, upAxis);
        lastVelocityStep = Vector3.ProjectOnPlane(lastVelocityStep, upAxis);
        if (velocity.magnitude > 0.5f)
        {
            Debug.Log("return projected vector");
            return projectedVector;
        }
        else
        {
            Debug.Log("Return the lastvelocitystep");
            return lastVelocityStep;
        }
    }
```So that basically? just to see when each gets returned?
solemn pumice
#

sooo the projectedVector is the problem?🤔

pure agate
#

woah woah

#

is the projectedVector the problem, or some other code the problem

solemn pumice
#

*velocity?

pure agate
#

in what cases should the rotation of the player be updated

solemn pumice
#

when the velocity is greater than 0.5 (if I understand the question correctly)

pure agate
#

should (what is supposed to happen) not is (what actually happens)

#

like tell me in english when the rotation should be updated

solemn pumice
#

The rotation should be updated whenever the player moves

#

oh, and it should only update when it moves? so when I jump, I need to exclude that

#

make sure player don't update the rotation when I'm jumping?

pure agate
#

that sounds right

solemn pumice
#

this will be a guess, but to remove that from the velocity, does this work ?```cs

velocity -= upAxis;

#

If this was on a flat world. I'd do something like ```cs

velocity.y = 0f
if (velocity.magnitude > 0.5f)
{
Debug.Log("return projected vector");
return projectedVector;
}

pure agate
solemn pumice
#

I want to make sure that when I jump, the velocity thresh-hold don't change so that while in air I return the "lastVelocityStep"

solemn pumice
pure agate
solemn pumice
pure agate
#

yeah, does that make sense?

solemn pumice
#

sort of.. Just thought I already accomplishing that with this: ```cs
Vector3 projectedVector = Vector3.ProjectOnPlane(velocity, upAxis);

solemn pumice
pure agate
#

so you should be able to solve it now

#

but after i will show you a better way

solemn pumice
#

ok I'll give it a try

solemn pumice
# pure agate but after i will show you a better way

omfg. It actually works🥹 I defined the projectedVector outside so I could set it in the FixedUpdate ```cs
projectedVector = Vector3.ProjectOnPlane(velocity, upAxis);
if (projectedVector.magnitude > 0.5f)
lastVelocityStep = velocity;

Then I adjusted the code in here: cs
public Vector3 GetProjectedVector()
{

    lastVelocityStep = Vector3.ProjectOnPlane(lastVelocityStep, upAxis);
    if (projectedVector.magnitude > 0.5f)
    {
        Debug.Log("return projected vector");
        return projectedVector;
    }
    else
    {
        Debug.Log("Return the lastvelocitystep");
        return lastVelocityStep;
    }
}
pure agate
#

glad you got it working

#

!!