- Home /
Movement feels like it's always going slightly off to the sides
I made a simple movement component in C#, however I noticed that the moving feels kind of off. It looks like it always moves a slight bit the the left or right, even if you are just moving in a straight line.
However as far as I can tell, it should only be moving in the direction which the camera is facing, so why is this happening?
PlayerMovement.cs
using UnityEngine;
/// <summary>
/// Handles player movement.
/// </summary>
public class PlayerMovement : MonoBehaviour {
[Header("Movement Settings")]
[SerializeField]
private float baseMovementSpeed;
[SerializeField]
private float runMultiplier;
[SerializeField]
private float sneakMultiplier;
public float currentMovementSpeed;
public enum WalkStatus { Walking = 0, Running, Sneaking, Still }
private WalkStatus walkingStatus;
private float verticalInput;
private float horizontalInput;
private Rigidbody playerRigid;
void Start()
{
playerRigid = GetComponent<Rigidbody>();
}
void Update()
{
horizontalInput = Input.GetAxis("Horizontal");
verticalInput = Input.GetAxis("Vertical");
if (Input.GetKeyDown(KeyCode.LeftShift))
{
walkingStatus = WalkStatus.Running;
currentMovementSpeed = baseMovementSpeed * runMultiplier;
}
else if (Input.GetKeyDown(KeyCode.LeftAlt))
{
walkingStatus = WalkStatus.Sneaking;
currentMovementSpeed = baseMovementSpeed * sneakMultiplier;
}
else if (horizontalInput == 0 && verticalInput == 0)
{
walkingStatus = WalkStatus.Still;
currentMovementSpeed = 0.0f;
}
else
{
walkingStatus = WalkStatus.Walking;
currentMovementSpeed = baseMovementSpeed;
}
if (horizontalInput != 0)
{
if (horizontalInput < 0)
{
playerRigid.AddForce(transform.right * -currentMovementSpeed, ForceMode.VelocityChange);
//if (playerRigid.velocity.z < -currentMovementSpeed)
//{
// playerRigid.velocity = new Vector3(-currentMovementSpeed, playerRigid.velocity.y, playerRigid.velocity.z);
//}
}
else if (horizontalInput > 0)
{
playerRigid.AddForce(transform.right * currentMovementSpeed, ForceMode.VelocityChange);
//if (playerRigid.velocity.z > currentMovementSpeed)
//{
// playerRigid.velocity = new Vector3(currentMovementSpeed, playerRigid.velocity.y, playerRigid.velocity.z);
//}
}
}
else
{
playerRigid.velocity = new Vector3(0.0f, playerRigid.velocity.y, playerRigid.velocity.z);
}
if (verticalInput != 0)
{
if (verticalInput < 0)
{
playerRigid.AddForce(transform.forward * -currentMovementSpeed, ForceMode.VelocityChange);
//if (playerRigid.velocity.z < -currentMovementSpeed)
//{
// playerRigid.velocity = new Vector3(playerRigid.velocity.x, playerRigid.velocity.y, -currentMovementSpeed);
// Debug.Log("Velocity: " + playerRigid.velocity);
//}
}
else if (verticalInput > 0)
{
playerRigid.AddForce(transform.forward * currentMovementSpeed, ForceMode.VelocityChange);
//if (playerRigid.velocity.z > currentMovementSpeed)
//{
// playerRigid.velocity = new Vector3(playerRigid.velocity.x, playerRigid.velocity.y, currentMovementSpeed);
//}
}
}
else
{
playerRigid.velocity = new Vector3(playerRigid.velocity.x, playerRigid.velocity.y, 0.0f);
}
if (playerRigid.velocity.z > currentMovementSpeed)
{
playerRigid.velocity = new Vector3(playerRigid.velocity.x, playerRigid.velocity.y, currentMovementSpeed);
}
else if (playerRigid.velocity.z < -currentMovementSpeed)
{
playerRigid.velocity = new Vector3(playerRigid.velocity.x, playerRigid.velocity.y, -currentMovementSpeed);
}
if (playerRigid.velocity.x > currentMovementSpeed)
{
playerRigid.velocity = new Vector3(currentMovementSpeed, playerRigid.velocity.y, playerRigid.velocity.z);
}
else if (playerRigid.velocity.x < -currentMovementSpeed)
{
playerRigid.velocity = new Vector3(-currentMovementSpeed, playerRigid.velocity.y, playerRigid.velocity.z);
}
}
}
PlayerLook.cs
using UnityEngine;
/// <summary>
/// Handles the player looking.
/// </summary>
public class PlayerLook : MonoBehaviour {
private Camera playerViewCamera;
[Header("Look Settings")]
public bool AllowLook = true;
public Vector2 LookSensitivity;
[SerializeField]
private float maxLookXRestriction;
[SerializeField]
private float minLookXRestriction;
private GameObject playerBody;
private Vector2 mouseInput;
private void Awake()
{
playerViewCamera = transform.GetChild(0).GetComponent<Camera>();
playerBody = gameObject;
}
private void Update()
{
mouseInput.x = Input.GetAxis("Mouse X") * LookSensitivity.x;
mouseInput.y = -Input.GetAxis("Mouse Y") * LookSensitivity.y;
if (AllowLook)
{
//playerViewCamera.transform.Rotate(new Vector3(mouseInput.y, mouseInput.x), Space.Self);
playerBody.transform.Rotate(0, mouseInput.x, 0);
playerViewCamera.transform.Rotate(mouseInput.y, 0, 0);
playerViewCamera.transform.rotation = Quaternion.Euler(playerViewCamera.transform.eulerAngles.x, playerViewCamera.transform.eulerAngles.y, 0); // Reset Z value.
if (playerViewCamera.transform.rotation.x > maxLookXRestriction)
{
playerViewCamera.transform.rotation = new Quaternion(maxLookXRestriction, playerViewCamera.transform.rotation.y, playerViewCamera.transform.rotation.z, playerViewCamera.transform.rotation.w);
}
else if (playerViewCamera.transform.rotation.x < minLookXRestriction)
{
playerViewCamera.transform.rotation = new Quaternion(minLookXRestriction, playerViewCamera.transform.rotation.y, playerViewCamera.transform.rotation.z, playerViewCamera.transform.rotation.w);
}
}
}
}
Edit:
Here's a video of the problem, might be hard to see but the player isn't moving only toward or away from the blue axis, but seems to move slightly on the red one too.
https://i.gyazo.com/79d5788ca68531802afe1c9d48bfb0cd.mp4
Here's another video showing movement on the global Z axis instead of X, which is perfectly straight unlike the other video.
https://i.gyazo.com/ab7be9569fc2bfae1d543f90d430841e.mp4
Edit 2:
I tried rewriting the entire script but I'm still having the same problem. I can't seem to find what is causing this weird behaviour. Feels like I've tried everything. So weird :/
Edit 3:
The script itself doesn't seem to be adding any force sideways. When checking how much force it adds it only returns a one-axis value.
Edit 4:
I created a new project with nothing in it, copied the code and put the component on the player and still the same result as before. I really don't understand where the velocity on the Z axis is coming from. This is so confusing. I have no idea at all what is going on...
Edit 5:
I now know that the PlayerLook script has no bugs in it since I tested using the PlayerMovement script without the PlayerLook one, and the results were still the same.
Edit 6:
I now know that the "moving off the the sides" only occurs when the transform.right
or transform.forward
has a value on both X and Z axis. But I have no idea how this would cause a "walking off to the side" problem...
Edit 7:
Managed to fix it by changing the velocity directly instead of using AddForce, would still like to know why this code wasn't working though...
@nobx101
Well I tested the movement script and it works fine and moves straight. I am going to try it with your camera script.
@nobx101
Wow even your camera script is fine. $$anonymous$$aybe it is something else. When do you see these problems?
Hmm actually it seems to work for me now too. Not sure what I was doing last night lol
@nobx101
Lol it is good but you got nice scripts. $$anonymous$$eep going at it.
Very true. $$anonymous$$aybe it could be your colliders because it is odd that only one axis is effected.
Disabling all colliders in the scene doesn't seem to fix the issue either :/
I tried setting the AllowLook boolean to false, but still moved off to the sides.
Trying to thoroughly read through the script.
Answer by UDN_9a915d40-27e1-405b-b1cc-83be8be3e71d · Dec 26, 2017 at 07:07 PM
If I'm not mistaken it's probably because you use playerRigid.AddForce(transform.forward * currentMovementSpeed, ForceMode.VelocityChange);
to move the player. This will push the player forward like a ball. It's like it keeps on rolling... I don't really remember which component in the Rigidbody is controlling this. If your game is 2D it is the Linear Drag variable. Otherwise it's something like angular Drag or just "Drag". Decrease those variables and see what results you get!
This would effect all axes not just one though right? I set all of them to 0 and the result is the same :/
Your answer
Follow this Question
Related Questions
Camera Relative Movement With Rigidbody.AddForce 2 Answers
When camera switches, rigidbody.velocity doesn't work 1 Answer
Very jerky camera movement with rigidbody 1 Answer
Move RigidBody character relative to camera. 2 Answers
Change player movement 0 Answers