0
\$\begingroup\$

I wrote a C# script to control a 2D player, but the script is not fully working. When I press the right arrow/d key to move the player is not moving in the right direction, but I have done the same exact thing for left key which works fine.The script shows no errors too.Kindly help me to solve the issue.The code is:

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField] private Rigidbody2D _rb2d;
    [SerializeField] private float _speed;
    [SerializeField] private float _jump;
    private static float _tempspeed;
    private static float _tempjump;
    private bool _isRight;
    private bool _isLeft;
    private bool _isSpace;

    private void Start()
    {
        _isLeft = false;
        _isRight = false;
        _isSpace = false;
        _speed = 5f;
        _jump = 7f;
        _tempjump = _jump;
        _tempspeed = _speed;
    }

    private void Update()
    {
        ReadInput();
    }

    private void FixedUpdate()
    {
        Move();
    }

    private void ReadInput()
    {
        if (UnityEngine.Input.GetKey("d") || UnityEngine.Input.GetKey("right"))
        {
            _isRight = true;
        }else {
            _isRight = false;
        }
        if (UnityEngine.Input.GetKey("a") || UnityEngine.Input.GetKey("left"))
        {
            _isLeft = true;
        }else {
            _isLeft = false;
        }
        if (UnityEngine.Input.GetKey("w") || UnityEngine.Input.GetKey("up"))
        {
            _isSpace = true;
        }else {
            _isSpace = false;
        }
    }

    private void Move()
    {
        Vector2 speedVectorRight=new Vector2(_tempspeed,_rb2d.velocity.y);
        Vector2 speedVectorLeft=new Vector2(-_tempspeed,_rb2d.velocity.y);
        Vector2 jumpVector=new Vector2(_rb2d.velocity.x,_tempjump);

        if (_isRight)
        {
            _rb2d.velocity = speedVectorRight;
        }else {
            speedVectorRight.x=0f;
            _rb2d.velocity = speedVectorRight;
        }
        if (_isLeft)
        {
            _rb2d.velocity = speedVectorLeft;
        }else {
            speedVectorLeft.x=0f;
            _rb2d.velocity = speedVectorLeft;
        }
        if (_isSpace)
        {
            _rb2d.velocity=jumpVector;
        }
    }

When I tried to print debug statements in different parts of if statements, they work fine. The problem in my observation is in :

if (_isRight)
        {
            _rb2d.velocity = speedVectorRight;
        }else {
            speedVectorRight.x=0f;
            _rb2d.velocity = speedVectorRight;
        }

The _rb2.velocity is not accepting speedVectorRight I guess.Thanks in advance!

\$\endgroup\$
  • 2
    \$\begingroup\$ Walk through your code one line at a time, pretending you're the CPU executing it step by step. Notice that after you've set the velocity based on the state of the _isRight vector, you then proceed to overwrite that result based on the state of the isLeft variable. \$\endgroup\$ – DMGregory Jun 2 at 19:09
  • \$\begingroup\$ @DMGregory Oh yes!!! I did not notice that.The solution you have provided is so simple.Thanks \$\endgroup\$ – dejavu Jun 3 at 5:21
0
\$\begingroup\$

You can make this code much simpler.

First, you can use the Input Manager to read your multiple sets of input buttons as a single axis. Mapping the typical arrow keys/WASD A= / D= to a "Horizontal" axis is already handled by the default setup:

Input manager showing Horizontal Axis configuration

Similarly, you can edit the default "Jump" action to read both W and as a single synonymous input.

Doing it this way also allows users to remap these controls if you show the input mapping dialog at the start of your game.

With this in hand, you can simplify your code to:

void FixedUpdate() {
    // This gives us -1 if A/← is pressed, 1 if D/→ is pressed, and 0 if both/neither.
    // It's OK to read this in FixedUpdate because it's a sustained input.
    float inputDirection = Input.GetAxisRaw("Horizontal");

    // Get the current velocity.
    var velocity = _rb2d.velocity;
    // Override the horizontal with our desired speed and direction.
    velocity.x = inputDirection * _speed;
    // Assign it back.
    _rb2d.velocity = velocity;
}

// Jumps are usually instantaneous, so it needs to be checked in Update, 
// so we don't miss or double-up a jump on frames that get 0 or 2 FixedUpdates.
void Update() {
    // GetButtonDown returns true the first frame the control is pressed,
    // then not again until the button is released and pressed a second time.
    if(Input.GetButtonDown("Jump")) {
         _rb2d.velocity += Vector2.up * _jump;
    }
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for your answer....but I am facing trouble choosing when to use Update() and FixedUpdate(), I searched in Google, but was not able to find the solution that I could understand easily.Is it possible for you to send any link of any articles that I could find helpful.Thanks \$\endgroup\$ – dejavu Jun 3 at 5:26
  • \$\begingroup\$ Use Update to respond to instantaneous inputs — like a button press or release. Use FixedUpdate for any ongoing simulation effects, like applying cumulative forces/velocity over time, dealing with held buttons or movement directions from analog sticks/WASD. \$\endgroup\$ – DMGregory Jun 3 at 10:55
  • \$\begingroup\$ Now all my doubts have been cleared.Thank you very much. \$\endgroup\$ – dejavu Jun 3 at 12:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.