- Home /
Having issues with Input.GetKey...
I want to make it so that when two keys are pressed, my character moves with certain vectors, but it doesn't seem to work except for when I want the character to move Right and Forward. I used the same code for each direction, so what gives? using System.Collections; using System.Collections.Generic; using UnityEngine;
public class Movement : MonoBehaviour {
// Keys Are Held
private bool wIsHeld = false;
private bool aIsHeld = false;
private bool sIsHeld = false;
private bool dIsHeld = false;
//Random Stuffs
private Rigidbody rb;
public float moveSpeed = 0.2f;
//Vectors
private Vector3 moveNorth = new Vector3 (0f, 0f, 1f);
private Vector3 moveNorthWest = new Vector3 (-1f, 0f, 1f);
private Vector3 moveWest = new Vector3 (-1f, 0f, 0f);
private Vector3 moveSouthWest = new Vector3 (-1f, 0f, -1f);
private Vector3 moveSouth = new Vector3 (0f, 0f, -1f);
private Vector3 moveSouthEast = new Vector3 (1f, 0f, -1f);
private Vector3 moveEast = new Vector3 (1f, 0f, 0f);
private Vector3 moveNorthEast = new Vector3 (1f, 0f, 1f);
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody> ();
}
// Update is called once per frame
void Update () {
//W Is Held
if (Input.GetKey ("w")) {
wIsHeld = true;
}
if (Input.GetKeyUp ("w")) {
wIsHeld = false;
}
//A Is Held
if (Input.GetKey ("a")) {
aIsHeld = true;
}
if (Input.GetKeyUp ("a")) {
aIsHeld = false;
}
//S Is Held
if (Input.GetKey ("s")) {
sIsHeld = true;
}
if (Input.GetKeyUp ("s")) {
sIsHeld = false;
}
//D Is Held
if (Input.GetKey ("d")) {
dIsHeld = true;
}
if (Input.GetKeyUp ("d")) {
dIsHeld = false;
}
//Movement Forward
if (wIsHeld == true) {
rb.MovePosition (transform.position + moveNorth * moveSpeed);
}
//Movement Forward + Left
if ( wIsHeld == true && aIsHeld == true || aIsHeld == true && wIsHeld == true) {
rb.MovePosition (transform.position + moveNorthWest * moveSpeed);
}
//Movement Left
if (aIsHeld == true) {
rb.MovePosition (transform.position + moveWest * moveSpeed);
}
//Movement Left + Back
if (aIsHeld == true && sIsHeld == true || sIsHeld == true && aIsHeld == true) {
rb.MovePosition (transform.position + moveSouthWest * moveSpeed);
}
//Movement Back
if (sIsHeld == true) {
rb.MovePosition (transform.position + moveSouth * moveSpeed);
}
//Move Back + Right
if (sIsHeld == true && dIsHeld == true || dIsHeld == true && sIsHeld == true) {
rb.MovePosition (transform.position + moveSouthEast * moveSpeed);
}
//Move Right
if (dIsHeld == true){
rb.MovePosition (transform.position + moveEast * moveSpeed);
}
//Move Right + Forward
if ( wIsHeld == true && dIsHeld == true || dIsHeld == true && wIsHeld == true) {
rb.MovePosition (transform.position + moveNorthEast * moveSpeed);
}
}
}
Answer by ASPePeX · Feb 13, 2017 at 09:33 AM
You are thinking way to complex imo. Here are two solutions in one, you can switch between them with the "useAxis" bool.
The useAxis solution uses the GetAxis(name) function, you can control them in the InputManager. that is also where you can reduce the drag that is introduced by the default settings (the Gravity setting). The advantage is, much shorter code, you can configure the axis in the inspector, don't go for specific keys and it is rebindable by the player.
The !useAxis, is basically what you are doing but WAY shorter. I'm just adding up the vector for every button and shove it normalized into movePosition.
using UnityEngine;
public class Movement : MonoBehaviour
{
private Rigidbody rb;
public float moveSpeed = 1f;
public bool useAxis;
void Start ()
{
rb = GetComponent<Rigidbody>();
}
void Update () {
Vector3 direction = Vector3.zero;
if (useAxis)
{
direction.x = Input.GetAxis("Horizontal");
direction.y = Input.GetAxis("Vertical");
}
else
{
if (Input.GetKey(KeyCode.W))
{
direction += Vector3.up;
}
if (Input.GetKey(KeyCode.A))
{
direction += Vector3.left;
}
if (Input.GetKey(KeyCode.S))
{
direction += Vector3.down;
}
if (Input.GetKey(KeyCode.D))
{
direction += Vector3.right;
}
}
if (direction != Vector3.zero)
{
rb.MovePosition(transform.position + direction.normalized * moveSpeed * Time.deltaTime);
}
}
}
Thank you for the suggestion, but I want to look for each button separately. Eventually I hope to make it so that a button will do different things when pressed or tapped.
Also I am not good enough at unity yet to use shortcuts like this one... I understand that the way you proposed is shorter, but I don't fully understand how to tweak it. (Also I don't $$anonymous$$d super long code)
This is a very good answer to your question. You'd be better off asking some more questions about this to understand how it works rather than looking for another answer.
In the !useAxis part (line 25++) I'm actually doing exactly what you did. I just prepare an empty vector (line 16) and add up the vectors associated with the buttons. There are no shortcuts just vector addition.
In your code if button X and Y are pressed, some bool logic says the resulting vector is (1,0,1).
In my code X is equivalent to vector (1,0,0) and Y to (0,0,1) and I just add them up to (1,0,1)
Out of habbit, I actually added two things that weren't in your code (both in line 48). One is normalizing the resulting vector. A vector of (1,0,0) has a length/magnitude of 1, but (1,0,1) has a length of square root of 2 (1.4something). There are situations where you actually want it that way, but it depends what fits your game best. The second is multiplying the movement with Time.deltaTime, which makes the movement independent of the framerate.
Answer by James2Games · Feb 14, 2017 at 04:54 AM
When it comes to complicated scripts it's best to break everything down into smaller functions so everything becomes easier to read and follow.
Personally i'm also a fan of hard coding controls but this can be updated to use the Input functions such as Input.OnButtonDown("Jump") and so on.
This script should allow the player to move in all 4 directions as well as move on an angle if they are holding down W+D for example.
If you want to check special cases where the user is moving on an angle. Then you can nest some if statements in the MovePlayer method and check for more than 1 key is pressed.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Movement : MonoBehaviour
{
public string MoveForwardButton = "w";
public string MoveBackButton = "s";
public string MoveLeftButton = "a";
public string MoveRightButton = "d";
private List<string> PressedButtons = new List<string>();
void Update()
{
CheckButton(MoveForwardButton);
CheckButton(MoveBackButton);
CheckButton(MoveLeftButton);
CheckButton(MoveRightButton);
MovePlayer();
}
private void CheckButton(string buttonKey)
{
if (Input.GetButtonDown(buttonKey))
{
PressedButtons.Add(buttonKey);
}
else if (Input.GetButtonUp(buttonKey))
{
PressedButtons.Remove(buttonKey);
}
}
private void MovePlayer()
{
Vector2 moveDirection = Vector2.zero;
if (PressedButtons.Contains(MoveForwardButton))
{
moveDirection.y += 1;
}
else if (PressedButtons.Contains(MoveBackButton))
{
moveDirection.y -= 1;
}
else if (PressedButtons.Contains(MoveLeftButton))
{
moveDirection.x -= 1;
}
if (PressedButtons.Contains(MoveRightButton))
{
moveDirection.x += 1;
}
}
}
Answer by ratnamraja · Feb 14, 2017 at 06:42 AM
Hi Trevonino,
Use Input.GetKeyDown
Instead of Input.GetKey
. Because GetKeyUp
and GetKeyDown
give result Only during the Frame.
Your answer
Follow this Question
Related Questions
Having trouble checking if the player is in a trigger. 2 Answers
problem whit input key 2 Answers
Perform event only once on keypress 1 Answer
Script error? BCE0077 0 Answers
Key not recognized 2 Answers