2

My code below only works for horizontal movement. Shouldn't the vertical movement be working too? I'm just starting out with basic 2D Unity programming:

public class Player : MonoBehaviour {

    //These fields will be exposed to Unity so the dev can set the parameters there
    [SerializeField] private float speed = 1f;
    [SerializeField] private float upY;
    [SerializeField] private float downY;
    [SerializeField] private float leftX;
    [SerializeField] private float rightX;

    private Transform _transformY;
    private Transform _transformX;
    private Vector2 _currentPosY;
    private Vector2 _currentPosX;

    // Use this for initialization
    void Start () {
        _transformY = gameObject.GetComponent<Transform> ();
        _currentPosY = _transformY.position;        

        _transformX = gameObject.GetComponent<Transform> ();
        _currentPosX = _transformX.position;
    }

    // Update is called once per frame
    void Update () {
        _currentPosY = _transformY.position;
        _currentPosX = _transformX.position;

        float userInputV = Input.GetAxis ("Vertical");
        float userInputH = Input.GetAxis ("Horizontal");

        if (userInputV < 0) 
            _currentPosY -= new Vector2 (0, speed);     

        if (userInputV > 0)
            _currentPosY += new Vector2 (0, speed);

        if (userInputH < 0)
            _currentPosX -= new Vector2 (speed, 0);

        if (userInputH > 0)
            _currentPosX += new Vector2 (speed, 0);

        CheckBoundary ();

        _transformY.position = _currentPosY;
        _transformX.position = _currentPosX;
    }

    private void CheckBoundary(){
        if (_currentPosY.y < upY)
            _currentPosY.y = upY;

        if (_currentPosY.y > downY)
            _currentPosY.y = downY;

        if (_currentPosX.x < leftX)
            _currentPosX.x = leftX;

        if (_currentPosX.x > rightX)
            _currentPosX.x = rightX;
    }
}

If I remove/comment out the _currentPosX and it's related codes then my Vertical movement works. But if I remove/comment out the _currentPosY and it's related codes then my Horizontal movement works.

But how come I'm having trouble getting them to work at the same time? I think I'm just missing something but I can't figure it out since I'm just a beginner at this.

Thanks to whoever can give advise.

EDIT: for further clarification...

I'm coding a simple 2d game that will have the player move in 4-directions using the WASD keys.

W = move up
A = move left
S = move down
D = move right

My main problem is that I can get two of the keys working only in one axis: either A and D is working for Horizontal while W and S are not working at all for Vertical movement or vice-versa.

Programmer
  • 121,791
  • 22
  • 236
  • 328
5120bee
  • 689
  • 1
  • 14
  • 36

3 Answers3

12

You don't need those if statements. Just use += to append the input to the current transform position.

Move without Rigidbody:

public float speed = 100;
public Transform obj;

public void Update()
{
    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");

    Vector3 tempVect = new Vector3(h, v, 0);
    tempVect = tempVect.normalized * speed * Time.deltaTime;

    obj.transform.position += tempVect;
}

Move Object with Rigidbody2D:

public float speed = 100;
public Rigidbody2D rb;

public void Update()
{
    float h = Input.GetAxis("Horizontal");
    float v = Input.GetAxis("Vertical");

    Vector3 tempVect = new Vector3(h, v, 0);
    tempVect = tempVect.normalized * speed * Time.deltaTime;
    rb.MovePosition(rb.transform.position + tempVect);
}

I suggest using the second code and moving the Rigidbody if you want to be able to detect collison later on.

Note:

You must assign the object to move to the obj slot in the Editor. If using the second code, assign the object with the Rigidbody2D to the rb slot in the Editor.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • what does Time.deltaTime do and can I still use my CheckBoundary(); function to prevent the player from going off the camera screen view boundaries? – 5120bee Oct 15 '17 at 23:39
  • It makes sure that the move speed is the-same on every device/computer. Some devices are faster than others. Without that, it would be unfair for players to play against those with fast computers as their character would move faster. As for your second question, yes. If you can't do that then create a new question about restricting player movement to some boundaries. – Programmer Oct 15 '17 at 23:43
  • 2
    Shouldn't you handle physics calculations in the FixedUpdate instead of the Update function? – Geordi Rugenbrink Jun 22 '19 at 19:46
2

THIS CODE WORK 100% (you must try it.)

public float moveSpeed = 5;


void Start()
{
   
}


 void Update()
{

    if (Input.GetKey(KeyCode.D))
    {
        transform.position += Vector3.right * moveSpeed * Time.deltaTime;
        
    }
    else if (Input.GetKey(KeyCode.A))
    {
        transform.position += Vector3.right * -moveSpeed * Time.deltaTime;
        
    }

    else if (Input.GetKey(KeyCode.W))
    {
        transform.position += Vector3.up * moveSpeed * Time.deltaTime;

    }
    else if (Input.GetKey(KeyCode.S))
    {
        transform.position += Vector3.up * -moveSpeed * Time.deltaTime;

    }
}
Makalaos
  • 21
  • 1
0

Try changing the value 0 in the Vector2 functions to current x/ y position...I ran into a similar problem with my project

if (userInputV < 0) 
        _currentPosY -= new Vector2 (/*current position*/, speed); 
Nathan
  • 1
  • 1