- Home /
Prioritize Movement in 2D
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;
}
}
}
Answer by darthtelle · May 02, 2014 at 07:17 AM
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);
}
Answer by Maerig · May 02, 2014 at 07:57 AM
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.
I also had issues with this implementation. When I would hold one direction and switch to another, it would lock in that position, and so when I would try and switch again, it would not switch. That is a pretty poor description, but it would be better to see the issue than to tell you.
I am looking for a Final Fantasy 3/6 movement style for my project. I want to be able to be holding u/d (r/l), and then while still holding u/d (r/l) and I push the r/l (u/d) button that it switches the movement of the character. $$anonymous$$aybe this is just too complicated for me to implement.
Answer by Jeff-Kesselman · May 04, 2014 at 12:52 AM
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