- Home /
Input.GetAxis doesn't seem to move me in the direction I am facing
I am trying to make a first-person-controlled, zero-gravity environment where you pretty much move in the direction you are facing, current velocity willing. (I'm using rigidbody movement) The scripts I am about to display work almost exactly how I want, except that the forward movement when looking up or down from the world X-Z plane doesn't move to where I am looking. For example, if I hit the start button and don't move the mouse to keep looking forward and hold W, I will move exactly forward. But if I move my mouse upward and and looking more vertically, when I hold W down, I move at less of an upward angle than where I am looking. How can I fix that?
For mouse look I am using this script:
// Performs a mouse look.
var horizontalSpeed : float = 2.0;
var verticalSpeed : float = 2.0;
function FixedUpdate () {
// Get the mouse delta. This is not in the range -1...1
var h : float = horizontalSpeed * Input.GetAxis ("Mouse X");
var v : float = verticalSpeed * Input.GetAxis ("Mouse Y");
transform.Rotate (-v, h, 0);
}
For the character controller I am using this script:
// These variables are for adjusting in the inspector how the object behaves
var maxSpeed = 7.000;
var force = 8.000;
var jumpSpeed = 5.000;
// These variables are there for use by the script and don't need to be edited
private var state = 0;
private var grounded = false;
private var jumpLimit = 0;
// Don't let the Physics Engine rotate this physics object so it doesn't fall over when running
function Awake ()
{
rigidbody.freezeRotation = true;
}
// This part detects whether or not the object is grounded and stores it in a variable
function OnCollisionEnter ()
{
state ++;
if(state > 0)
{
grounded = true;
}
}
function OnCollisionExit ()
{
state --;
if(state < 1)
{
grounded = false;
state = 0;
}
}
// This is called every physics frame
function FixedUpdate ()
{
// Get the input and set variables for it
jump = Input.GetButtonDown ("Jump");
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
// Set the movement input to be the force to apply to the player every frame
horizontal *= force;
vertical *= force;
// If the object is grounded and isn't moving at the max speed or higher apply force to move it
if(rigidbody.velocity.magnitude < maxSpeed)
{
rigidbody.AddForce (transform.rotation * Vector3.forward * vertical);
rigidbody.AddForce (transform.rotation * Vector3.right * horizontal);
}
// This part is for jumping. I only let jump force be applied every 10 physics frames so
// the player can't somehow get a huge velocity due to multiple jumps in a very short time
if(jumpLimit < 10) jumpLimit ++;
if(jump && grounded == true && jumpLimit >= 10)
{
rigidbody.velocity.y += jumpSpeed;
jumpLimit = 0;
}
}
Answer by SilverTabby · Jun 28, 2011 at 03:35 AM
Here's your problem:
if(rigidbody.velocity.magnitude < maxSpeed7)
{
rigidbody.AddForce (transform.rotation * Vector3.forward * vertical);
rigidbody.AddForce (transform.rotation * Vector3.right * horizontal);
}
Instead of using Vector3.forward, use
var localForward : Vector3 = transform.TransformDirection(Vector3.forward);
rigidbody.AddForce(localForward * vertical);
Vector3.forward returns (1, 0, 0). Always. So if you are feeding that into a function, forward is always along the X (red) axis, no matter what the rotation is.
TransformDirection() takes a vector and returns the local space version of it. For example, passing in Vector3.forward (1, 0, 0) to a transform that is looking straight up will return (0, 1, 0).
Here's the documentation on the subject:
http://unity3d.com/support/documentation/ScriptReference/Transform.TransformDirection.html
transform.forward is equivalent to transform.TransformDirection(Vector3.forward). Less typing and one less variable to keep track of.
That didn't work for me, SilverTabby. It has the same behavior as before. The documentation you linked seems to say the opposite of what you suggested, and transform local space to world space.
This is confusing to me since strafing (Vector3.right) seems to be working as intented.
(I edited out the typo in the code in the OP, btw, where it said < maxSpeed7)
rigidbody.AddForce((camera.main.ViewportPointToRay(Vector3(0.5,0.5,0))).direction * force);
That seems to make me move in the direction of the camera, where I am looking. I think I'll have to add manual button press checks so the player can move forward and backward, though. Thoughts on that?
Answer by Phoera · Jul 29, 2015 at 02:55 PM
https://www.3dbuzz.com/training/view/3rd-person-character-system/simple-character-system
Video #7 has a solid explanation of what you need. The whole course can also be useful