- Home /
Unusual normalized vector effects on movement
I apologize beforehand if this is rudimentary or if I've repeated someone else' question; I haven't found any input on this particular problem yet.
A friend and I are putting together a custom character controller for our project. We are still handling basic movement but are getting strange results.
We have noticed that our code results in unresponsive movement in that the player will continue to move in a direction after the button has been released. Since we are using MovePosition rather than altering the object's RigidBody's velocity, this doesn't make sense to us.
To top it off, we have noticed that if we do not use a normalized version of the vector we are using to do movement, the movement becomes far less "floaty." We would like to keep our movement vectors normalized so we need to understand why this is happening. Any ideas?
using UnityEngine;
using System.Collections;
/*[RequireComponent (typeof (Animator))]*/
[RequireComponent (typeof (CapsuleCollider))]
[RequireComponent (typeof (Rigidbody))]
public class PlayerControllerCustom : MonoBehaviour
{
Quaternion tarRot;
Rigidbody rb;
private float moveSpeed = 4.0f;
private float inputX;
private float inputZ;
private int animInt;
void Start ()
{
tarRot = transform.rotation;
rb = GetComponent<Rigidbody>();
}
void Update() //All player Input should go here if possible
{
inputX = Input.GetAxis("Horizontal"); //Gets W/S Input for X Axis (built into Unity)
inputZ = Input.GetAxis("Vertical"); //Gets A/D Input for Z Axis (build into Unity)
}
void FixedUpdate () //All Physics calculations should go here
{
Run(); //Calls to Run Method every FixedUpdate
Crouch(); //Calls to Crouch Method every FixedUpdate
Sprint(); //Calls to Sprint Method every FixedUpdate
}
/***************************************************/
/* ************* MOVEMENT METHODS ************* */
void Run() //Run with WASD (Built in Unity input: W/S for positive / negative Z axis values, A/D for negative / positive X axis values)
{
rb.MovePosition(transform.position + (transform.TransformDirection((inputX), 0, (inputZ)).normalized * moveSpeed * Time.deltaTime));
}
void Crouch() //Crouch while Left Control is held down
{
if (Input.GetKey(KeyCode.LeftControl))
{
moveSpeed = 2.0f;
rb.MovePosition(transform.position + (transform.TransformDirection((inputX), 0, (inputZ)).normalized * moveSpeed * Time.deltaTime));
}
}
void Sprint() //Sprint while Left Shift is held down and player is standing and only moving forward (no X axis or negative Z axis movement)
{
if (Input.GetKey(KeyCode.LeftShift) && inputX == 0 && inputZ > 0 && animInt == 0)
{
moveSpeed = 8.0f;
}
else
{
moveSpeed = 4.0f;
}
}
}
Thank you very much for your help.
Your logic seems a bit funky: If the player is crouched, for example, they would get moved twice - by the $$anonymous$$ovePosition in Run() and then again by the $$anonymous$$ovePosition in Crouch().
You are most certainly correct, sir. Thank you for watching my back on that.
$$anonymous$$y partner wrote the code and last night I noticed that the logic was very odd as well and have already started discussing how we can redo that bit. However, I left it as it was for the sake of asking the question since I'm confident that wonky or not, it shouldn't be responsible for this particular bug.
Answer by _dns_ · Sep 02, 2016 at 02:13 PM
Hi, "GetAxis" returns a value that is smoothed by Unity : read the manual about inputs and the "gravity" and "sensitivity" parameters. It's nice but can introduce some sort of lag.
Using "GetAxisRaw" will return non-smoothed values. Depending on what effect you want, you may use the "raw" version or change the gravity + sensitivity parameters to your liking.
Your solution works but I'm still curious as to one detail. While I recognize that GetAxis has some extra stuff going on behind the curtain, we didn't have this problem until we tried to normalize the movement vector. As far as I can tell, normalization shouldn't affect how we're reading the input, should it? Why is it that normalizing the vector happened to cause this bug?
Normalizing will make the vector length to 1 unless it's 0 (or smaller than an Epsilon that would make it unsafe to normalize it). With the non "raw" version, the smoothing will return a small decreasing value for a few updates before returning to 0. Normalizing this value will resize the vector to 1 even if it's of a small length, making the character move. Its doing that without normalizing too but with small values so you didn't notice (I guess if you reduce the gravity value of this axis in the input settings you'll see the character slow down ins$$anonymous$$d of stopping instantly, even without normalizing).
By the way, if the normalization is to avoid going faster in diagonal than in axis aligned direction: you can get the magnitude of the vector, clamp it between 0 and 1, then normalize the vector and multiply it by the clamped magnitude. Doing so will keep the original direction but also all the ranges of values that an analog stick can give.
If you want to add a dead zone, I suggest reading this: http://www.gamasutra.com/blogs/JoshSutphin/20130416/190541/Doing_Thumbstick_Dead_Zones_Right.php
Your answer
Follow this Question
Related Questions
Strange Character Controller Behavior Caused by Simulated Gravity and Ground Check 0 Answers
Character won't jump under certain circumstances 0 Answers
How do i maintain the same speed in the air? 1 Answer
Altering movement depending on camera rotation 0 Answers
Moving forward towards the cursor with LookAtMouse? 0 Answers