- Home /
Movement keeps doubling when using militple input
i am still quite new to programming. what i am trying to do is move a character around based on camera and movement input i have that working but have been unable to prevent the speed from doubling when both forwards/backwards and either left or right keys are pressed. this is my code. float horMovement = Input.GetAxisRaw ("Horizontal"); float vertMovement = Input.GetAxisRaw ("Vertical");
if (horMovement != 0 && vertMovement !=0)
{
speed= 30f;
}
else
{
speed = 15f;
}
transform.Translate(camera.transform.right*horMovement* Time.deltaTime*speed);
transform.Translate(camera.transform.forward*vertMovement*Time.deltaTime*speed);
Vector3 forwardOnlyXandZ= new Vector3 (camera.transform.forward.x*Input.GetAxis("Vertical")
,0,camera.transform.forward.z*Input.GetAxis("Vertical"));
Vector3 rightOnlyXandZ= new Vector3
(camera.transform.right.x*Input.GetAxis("Horizontal"),0,
camera.transform.right.z*Input.GetAxis("Horizontal"));
// player rotation
Vector3 moveDirection = forwardOnlyXandZ + rightOnlyXandZ;
if (moveDirection != Vector3.zero)
{
Quaternion newRotation = Quaternion.LookRotation(moveDirection);
playerGraphic.transform.rotation =
Quaternion.Slerp(playerGraphic.transform.rotation,newRotation,Time.deltaTime*8);
}
Answer by hbalint1 · May 03, 2015 at 10:14 PM
from another forum:
"you should gather your direction vector first, normalize it, and then set it to your movement speed."
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
move = move.normalized * Time.deltaTime * //walkspeed, runspeed, etc.
rigidbody.AddRelativeForce(move);
and my explanation (some maths):
when moving only on one axis the speed vector is one. But when you want to move on both axis at once the speed vector is the sum of the horizontal and vertical vectors. c^2 = a^2 + b^2, where a=b=1. so c = sqrt(2) what is about 1.414f. So when you move on both axes your speed is 1.414 times faster, than it should be. So an other trick is when both axes are pushed just divide your speed with sqrt(2) (maybe Mathf.Sqrt(2);) and it should give the same speed as pushing just one axis.
sorry. this is the whole class. Put in on a cube an you can test it yourself:
using UnityEngine;
using System.Collections;
public class $$anonymous$$ove : $$anonymous$$onoBehaviour {
public float walkSpeed = 3.0f;
void Update () {
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
if($$anonymous$$athf.Abs(Input.GetAxis("Horizontal")) > 0 && $$anonymous$$athf.Abs(Input.GetAxis("Vertical")) > 0)
transform.Translate(move * walkSpeed * (1/$$anonymous$$athf.Sqrt(2)));
else
transform.Translate(move * walkSpeed);
}
}
you can put this into your code.
I would recommend allowing lower speeds, just in case a controller (i.e. XBox360 Controller) is used.
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0f, Input.GetAxis("Vertical"));
if(move.sqr$$anonymous$$agnitude > 1)
{
move = move.normalized;
}
transform.Translate(move * walkSpeed * Time.deltaTime);
This should improve support in this movement scheme.
Your answer
Follow this Question
Related Questions
not allowing to walk on certain surfaces 2 Answers
rigidbodyfpscontroller stuttering when not selected on hierarchy 1 Answer
Drag object on XZ with perspective 0 Answers
Better Player Movement Code 0 Answers
Moving a player with Rigidbody 2 Answers