Hey! I’m trying to make a 3D FPS game, but my code for moving is giving me inverted controls, like W is back, S is forward, A is right and D is left. I tried inverting the controls on Edit > Project Settings > Input Manager > Horizontal/Vertical > Invert and it worked for a while! But now, I’m trying to make a sprinting code, and making the player being only able to sprint when you’re walking forward, but as the controls were inverted earlier, I can only sprint when I’m going backwards now. What should I do?
public class Movement : MonoBehaviour
public float speed;
public float sprintModifier;
private Rigidbody rig;
private void Start()
Camera.main.enabled = false;
rig = GetComponent<Rigidbody>();
float t_hmove = Input.GetAxisRaw("Horizontal");
float t_vmove = Input.GetAxisRaw("Vertical");
bool sprint = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
bool isSprinting = sprint && t_vmove > 0;
Vector3 t_direction = new Vector3(t_hmove, 0, t_vmove);
float t_adjustedSpeed = speed;
if (isSprinting) t_adjustedSpeed *= sprintModifier;
rig.velocity = transform.TransformDirection(t_direction) * t_adjustedSpeed * Time.deltaTime;
Your code looks fine to me, as far as WASD keys are correct. I’ve tested it and it works for me. I see that you have turned off the main camera. Perhaps you’ve made a second camera the child of the player so as to achieve your FPS. The camera should have zero rotation on the Y axis so it’s facing the same way as your player.
Two things, However. You do not need the Time.DeltaTime. RigidBody.velocity is framerate independent. Just have a think about it. If I say 30mph to you frequently or infrequently, it doesn’t matter you’re still going at 30mph. So frequency (i.e. framerate) doesn’t come into it. You only really need Time.DeltaTime when you are moving or rotating by a fixed amount.
Secondly, it seems odd that you are only sprinting when you are moving on the Z axis. It’s your game and that may be what you want but I can’t sprint horizontally unless I’m also going vertically.
The code is fine. I’ve tried it on an empty project and it worked properly with a character placeholder. However, I might know what’s happening in your case.
On your player object, is your object and all of their children facing on the same direction? If that’s not the case, that should be the reason why your controls are “inverted”. I believe that by just doing a reset of the rotation of your child objects you would be ready to go. Also, don’t forget to change the camera’s position and rotation as well.
I’m sharing two screenshots just to make myself more clear.
Additionally, a few tips that you might want to add to your controller.
- If you want to sprint both forward and backwards:
bool isSprinting = sprint && t_vmove != 0;
- Your current controller makes your character fall really slow. As SurreyMuso replied, you don’t need to multiply by Time.deltaTime when setting the velocity or applying a certain force to a rigidbody. So, when setting the velocity, this is what I would do:
rig.velocity = transform.TransformDirection(t_direction.x * t_adjustedSpeed, rig.velocity.y, t_direction.z * t_adjustedSpeed);
This will make your player fall based on physics, so it will progressively fall faster and faster. If you want to cap the max falling velocity, what you can do is:
rig.velocity = transform.TransformDirection(t_direction.x * t_adjustedSpeed, Mathf.Clamp(rig.velocity.y, maxYVel, minYVel), t_direction.z * t_adjustedSpeed);, where maxYVel would be the max velocity at which you can ascend, and minYVel would be the max velocity at which you can fall.
I hope this helps!
Are you sure that neither your
speed nor your
sprintModifier variable is set to a negative number?
Another possible issue would be if the transform your using for the TransformDirection calll (or any parent) has a negative scale. This would also flip the direction.