#velocity
1 messages · Page 1 of 1 (latest)
so, your problem is that you're storing the player's velocity in local space
so, if the player is walking forwards, then the velocity vector will always be (0, 1)
this is fine if you're on the ground, but you want to prevent the player from changing direction while mid-air, right?
the gist is that, before storing the current velocity, you should convert it to world-space
which you can do with transform.TransformVector(vec);
then, before using it, convert it back into local space
transform.InverseTransformVector(vec);
imagine turning 90 degrees instantly while mid-air while moving forwards
suppose you were facing forwards
so the velocity vector (in local space) was [0,0,1]
and after converting it to world space, it was still [0,0,1]
you've rotated 90 degrees to the right, so your should now be moving to the left
your world-space velocity is still [0,0,1]; nothing changed
but, when you convert it back into local space, it becomes [-1,0,0]: your left!
I think your code was using a Vector2, so you'd need to adjust things
so that you just work with a Vector3
at least to my knowledge the vector 2 was only there to handle inputs from input manager
the velocities are all vector 3
So from what I understand after lepring the velocity with;
currentVelocity.x = Mathf.Lerp(currentVelocity.x, inputManager.Move.x * targetSpeed, blendSpeed * Time.fixedDeltaTime);
I would then convert it to world space...
then convert it back
and finally apply it?
Heres my interpretation of what you mentioned...
if (!hasAnim) return;
float targetSpeed = inputManager.Run && !(inputManager.Move.y < 0) ? runSpeed : walkSpeed;
if (inputManager.Crouch) targetSpeed = 1.5f;
if (inputManager.Move == Vector2.zero) targetSpeed = 0;
if (grounded) {
transform.TransformVector(currentVelocity);
currentVelocity.x = Mathf.Lerp(currentVelocity.x, inputManager.Move.x * targetSpeed, blendSpeed * Time.fixedDeltaTime);
currentVelocity.y = Mathf.Lerp(currentVelocity.y, inputManager.Move.y * targetSpeed, blendSpeed * Time.fixedDeltaTime);
transform.InverseTransformDirection(currentVelocity);
//Ignore these
//var xDifference = currentVelocity.x - playerRigid.velocity.x;
//var zDifference = currentVelocity.y - playerRigid.position.z;
playerRigid.AddForce(transform.TransformVector(new Vector3(currentVelocity.x, 0, currentVelocity.y)), ForceMode.VelocityChange);
}
else {
playerRigid.AddForce(transform.TransformVector(new Vector3(currentVelocity.x * airResist, 0, currentVelocity.y * airResist)), ForceMode.VelocityChange);
}
anim.SetFloat(xVelocity, currentVelocity.x);
anim.SetFloat(yVelocity, currentVelocity.y);
}```
This didn't seem to work but I have a small suspicion that I may have misunderstood you
transform.TransformVector(currentVelocity); doesn't do anything
It transforms currentVelocity from local to world space, then returns the result
You need to store that into currentVelocity
generally, functions can't mutate (i.e. change) a value-type variable
float, int, vector3
they can modify reference-type variables, like GameObject or any component type
Also, you have them swapped around.
The very first thing you should do is convert currentVelocity from world to local space with InverseTransformVector
and the very last thing you should do is convert it from local to world space with TransformVector
This way, none of your existing code has to change
Makes sense, thank you, I’ll take a good look at this tomorrow and tell you how it goes
Thanks
Ive been trying to move the transforms around to get something to click using what you've said as a guideline but I'm still unable to get them to work. I understand by the way you are approaching this, it's something you are trying to get me to learn opposed to just straight up telling me which I do appreciate, but I might need a bit of a harder push in the right direction
https://hastebin.com/share/nejuvoteka.csharp heres the code in case discord is screwing with the format
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
the paste isn't working
when on the ground, you update currentVelocity based on the player's input, subtract the player's velocity from that, transform that into world-space, and then apply that as a velocity change
i suppose that works (i'd just directly set the velocity at that point, though)
when in the air, you use the old currentVelocity value
you multiply it by "airResist", convert that to world space, and then apply that as a velocity change
is airResist a very small negative number?
0.8
i'd expect this to make you accelerate super quickly
you're applying a big velocity change every frame
also, it just clicked for me that you're using a rigidbody, not a character controller
oops
can you remind me what the original issue was? it's been a bit
basically I dont want the characters rotation to affect it's momentum while in air. At the moment if you jump and turn to look somewhere they player will begin to strafe in air
how are you rotating the player?
.MoveRotation
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
okay, so if you just do nothing while the player is airborne, then things ought to work fine
see if that's the case
for the movement method or camera method?
for whatever moves the player
when I do that the player just stops when it leaves the ground. Still has gravity but any velocities it had are just gone
find all the places you set the rigidbody's velocity or call AddForce with the VelocityChange mode
if I comment out the addForce (in air) the only other ForceMode.velocityChange(s) left are only active while the player is grounded
The only change to the rigid body while in the air would be the .MoveRotation
heres the inspector if it helps
hm, i wouldn't expect it to just stop