Curious issue - having Run() method locks every other velocity modifier

I’ve a character that I’ve written a script to have a run and a dash, but when the run function is included, the dash completely stops working and I have no idea why. Commenting out the Run() bits and viola the the dash works.

Here’s a bit of my code:

    float dashVelocity = 40f;
    float deltaX;
        
    Rigidbody2D p_rb;
    Animator p_ani;
    SpriteRenderer p_sr;
    p_rb = GetComponent<Rigidbody2D>();
    p_ani = GetComponent<Animator>();
    p_sr = GetComponent<SpriteRenderer>();   
    
        void Update()
        {

            if (Input.GetButtonDown("Fire3"))
            {
                
                p_rb.velocity = transform.right * dashVelocity;
                Debug.Log("pressed");
    
            }
    
            Run();
    
          }
    
        void Run()
        {        
            deltaX = Input.GetAxis("Horizontal") * moveSpeed;
            p_rb.velocity = new Vector2(deltaX, p_rb.velocity.y);
         }
      }

(Sorry about the formatting)

Tried setting the rigidbody2D to interpolate and tried moving functions around between update and fixedUpdated but the issue persists.

There is no condition (if clause) for Run. When you pressed the button to dash. Unity detects both Run and dash. When you pressed fire3 it runs your codes in if for a moment but then runs Run function again.

Try to add a if clause also for Run. (for example if fire3 is not pressed).

Well you set your characters velocity every frame inside your Run method. Setting it again in one frame when you press a button does not have any effect at all since your Run method will overwrite the velocity again. A dash usually takes some time. Without the Run method when you set the velocity inside your if statement, the velocity will of course stay. Depending on your friction / drag settings, the object may slow down or just continues moving at the speed you set.

Directly modifying the velocity can not be done from two places. Your dash mechanic currently relies on the state of the rigidbody while your Run mechanic overwrites any physics / forces induced behaviour since you always set the velocity directly.

If you want to preserve your Run behaviour you could add the dash there as a seperate variable. Though you have to take care about your dash timing. The easiest way would be a coroutine like that:

float dashVelocity = 40f;
float dashTime = 0.3f;
float dash;
Rigidbody2D p_rb;

void Start()
{
    p_rb = GetComponent<Rigidbody2D>();
    StartCoroutine(HandleDash());
}

void Update()
{
    float deltaX = Input.GetAxis("Horizontal") * moveSpeed;
    p_rb.velocity = new Vector2(deltaX + dash, p_rb.velocity.y);
}

IEnumerator HandleDash()
{
    while(true)
    {
        if (Input.GetButtonDown("Fire3"))
        {
            dash = dashVelocity;
            yield return new WaitForSeconds(dashTime);
            dash = 0f;
            // implement cooldown if you want by uncommenting the following line
            // yield return new WaitForSeconds(dashCooldown);
        }
        yield return null;
    }
}