Hello. I am quite new to Unity and C#. I am trying to create a movement script that allows a player to move only in the cardinal directions (U, D, L, R). The code I currently have allows me to move in those four directions without moving in the diagonals. However, there are some issues.
When I hold the up or down key, and then press the left or right key the movement stays either up or down. This differs when I am holding left or right, and press and hold up or down, it prioritizes the up or down movement. Is there a way to have no priority so that when I am holding down one key, the second I push another key (regardless if I am still holding the original key or not) that priority passes to second key? Is the priority defined by he location of the if statements?
Thanks for any help!
using UnityEngine;
using System.Collections;
public class PlayerMovement : MonoBehaviour {
public Animator anim;
public float speed = 5.0f;
void Start ()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update ()
{
Movement ();
}
void Movement()
{
anim.SetFloat ("vSpeed", Input.GetAxisRaw ("Vertical"));
anim.SetFloat ("hSpeed", Input.GetAxisRaw ("Horizontal"));
if(Input.GetAxisRaw ("Vertical")>0)
{
transform.Translate(Vector2.up*speed*Time.deltaTime);
anim.SetFloat ("hSpeed",0);
return;
}
if(Input.GetAxisRaw ("Vertical")<0)
{
transform.Translate(-Vector2.up*speed*Time.deltaTime);
anim.SetFloat ("hSpeed",0);
return;
}
if(Input.GetAxisRaw ("Horizontal")>0)
{
transform.Translate(Vector2.right*speed*Time.deltaTime);
anim.SetFloat ("vSpeed",0);
return;
}
if(Input.GetAxisRaw ("Horizontal")<0)
{
transform.Translate(-Vector2.right*speed*Time.deltaTime);
anim.SetFloat ("vSpeed",0);
return;
}
}
}
I suspect your code is hitting the returns in either your up or down if statements so it’s never going to reach your left or right checks. Try removing the returns and putting the x and y in an if-else statement instead.
if(Input.GetAxisRaw ("Vertical")>0)
{
transform.Translate(Vector2.up*speed*Time.deltaTime);
anim.SetFloat ("hSpeed",0);
}
else if(Input.GetAxisRaw ("Vertical")<0)
{
transform.Translate(-Vector2.up*speed*Time.deltaTime);
anim.SetFloat ("hSpeed",0);
}
if(Input.GetAxisRaw ("Horizontal")>0)
{
transform.Translate(Vector2.right*speed*Time.deltaTime);
anim.SetFloat ("vSpeed",0);
}
else if(Input.GetAxisRaw ("Horizontal")<0)
{
transform.Translate(-Vector2.right*speed*Time.deltaTime);
anim.SetFloat ("vSpeed",0);
}
If you do want to only have the last pressed key active at a time, this would be a solution
private enum EDirection {
NONE = 0,
HORIZONTAL = 1,
VERTICAL = 2
}
private EDirection m_lastDirection = EDirection.NONE;
private bool m_isMovingVertically = false;
private bool m_isMovingHorizontally = false;
void Update () {
float vertical = Input.GetAxisRaw ("Vertical");
float horizontal = Input.GetAxisRaw ("Horizontal");
if(vertical == 0f) {
m_isMovingVertically = false;
}
if(horizontal == 0f) {
m_isMovingHorizontally = false;
}
if(vertical == 0f && horizontal == 0f) {
m_lastDirection = EDirection.NONE;
return;
}
if(!m_isMovingVertically && vertical != 0f) {
// The user has just pressed a vertical key
m_lastDirection = EDirection.VERTICAL;
anim.SetFloat("hSpeed",0);
m_isMovingVertically = true;
}
else if(!m_isMovingHorizontally && horizontal != 0f) {
// The user has just pressed an horizontal key
m_lastDirection = EDirection.HORIZONTAL;
anim.SetFloat("vSpeed",0);
m_isMovingHorizontally = true;
}
Vector3 movement = Vector3.zero;
switch(m_lastDirection) {
case EDirection.VERTICAL :
movement = (vertical * Vector2.up).normalized;
break;
case EDirection.HORIZONTAL :
movement = (horizontal * Vector2.right).normalized;
break;
default :
break;
}
transform.Translate(movement * speed * Time.deltaTime);
}
It would probably be easier with Input.GetKeyUp, though.
If you hold two keys at once on a typical PC keyboard you may get one, the other, or an entirely DIFFERENT key (this is called “ghosting”). This is at the hardware level and there isn’t a lot you can do about it.
http://www.microsoft.com/appliedsciences/antighostingexplained.mspx