user57682: I will be controlling a robot with more than 10 motors which means I'll need 2 buttons each to control moving forward and backward. My controller is an Arduino mega. Is 1 pin = 1 button the best solution here? Or should I use another IC for this?

user31105: you can use a so called shift register. One very common one is a 74HC165 shift register (https://playground.arduino.cc/Code/ShiftRegSN74HC165N/).
With one of such IC you can connect 8 buttons, however you can daisy chain max 4 to get 4 * 8 = 32 button inputs, only using 4 digital pins of the Arduino. In your case you would need 3 ICs to get 24 (thus 20) button inputs.

user31668: The example project below can control 16 switches. If you have a membrane keypad with 5 x 4 or 5 x 5 then you can meet your requirement.

I will shortly add an example of using shift registers to have multiple inputs (the main use case of shift registers is the same)
Link

Below is the example using shift registers. You need three shift registers as @Michael mentioned in his answer. Here is one example where you can control 32 switches maximum. You are only using 3 data pins and two power pins. This is the main application of the shift register. You don't have to do any selection, whenever you read the serial input data, you will automatically get the status of all the 32 switches in one Go.

Here is the code
// File : Cascade165.ino
//
// Version 1, 5 August 2021, by Koepel
//     Initial version.
// Version 2, 5 August 2021, by Koepel
//     Layout of the wiring made better.
// Version 3, 13 August 2021, by Koepel
//     Changed 'SCK' to 'clockPin'.
//
// Cascade of four 74HC165 shift-in registers.
// Only three pins are used on the Arduino board, to read 32 switches.
//
// Using the 74HC165 is safe, because a pulse to the Latch pin 
// ('PL' on the 74HC165) will make a new start every time. 
// In case of an error or a wrong clock pulse by noise, 
// it synchronizes the data when inputs are read the next time.
//
// Based on:
//   (1)
//     Demo sketch to read from a 74HC165 input shift register
//     by Nick Gammon, https://www.gammon.com.au/forum/?id=11979
//   (2)
//     74HC165 Shift register input example
//     by Uri Shaked, https://wokwi.com/arduino/projects/306031380875182657
//
//

const byte latchPin = 9;        // to latch the inputs into the registers
const byte clockPin = 13;       // I choose the SCK pin
const byte dataPin = 12;        // I choose the MISO pin
uint32_t oldOptionSwitch = 0;   // previous state of all the inputs

const int pulseWidth = 10;      // pulse width in microseconds

void setup ()
{
  Serial.begin( 115200);
  Serial.println( "Turn on and off the switches");
  Serial.println( "Top row is switch 0 (right) to switch 7 (left)");
  Serial.println( "Second row is 8 to 15, and so on");

  pinMode( clockPin, OUTPUT);   // clock signal, idle LOW
  pinMode( latchPin, OUTPUT);   // latch (copy input into registers), idle HIGH
  digitalWrite( latchPin, HIGH);
}

void loop ()
{
  // Give a pulse to the parallel load latch of all 74HC165
  digitalWrite( latchPin, LOW);    
  delayMicroseconds( pulseWidth);
  digitalWrite( latchPin, HIGH);

  // Reading one 74HC165 at a time and combining them into a 32 bit variable
  // The last 74HC165 is at the bottom, but the switches start numbering
  // at the top. So the first byte has to be shifted into the highest place.
  uint32_t optionSwitch = 0;
  for( int i=24; i>=0; i-=8)
  {
    optionSwitch |= ((uint32_t) ReadOne165()) << i;
  }

  for( int i = 0; i<32; i++)
  {
    if( bitRead( optionSwitch, i) != bitRead( oldOptionSwitch,i))
    {
      Serial.print( "Switch ");
      if( i < 10)
        Serial.print( " ");
      Serial.print( i);
      Serial.print( " is now ");
      Serial.println( bitRead( optionSwitch, i) == 0 ? "down ↓" : "up   ↑");
    }
  }
  
  oldOptionSwitch = optionSwitch;
  delay( 25);      // slow down the sketch to avoid switch bounce
}

// The ReadOne165() function reads only 8 bits,
// because of the similar functions shiftIn() and SPI.transfer() 
// which both use 8 bits.
//
// The shiftIn() can not be used here, because the clock is set idle low
// and the shiftIn() makes the clock high to read a bit.
// The 74HC165 require to read the bit first and then give a clock pulse.
//
byte ReadOne165()
{
  byte ret = 0x00;

  // The first one that is read is the highest bit (input D7 of the 74HC165).
  for( int i=7; i>=0; i--)
  {
    if( digitalRead( dataPin) == HIGH)
      bitSet( ret, i);

    digitalWrite( clockPin, HIGH);
    delayMicroseconds( pulseWidth);
    digitalWrite( clockPin, LOW);
  }

  return( ret);
}

Link to the shift register project: https://wokwi.com/arduino/projects/306024460940476993

user4143: For 20 buttons you can use a Keypad Matrix arrangement (plenty of examples online) where you would use only 9 pins (5 columns of 4 rows is 5+4 pins). It's slightly more involved that simple 1:1 buttons to pins, but thankfully there is a Keypad.h library that takes the hard work out of it for you.
If you want to be able to press multiple buttons at once you need to include diodes in your matrix to prevent "ghosting".
Nick Gammon has a great writeup on it here.

57682: <p>I will be controlling a robot with more than 10 motors which means I'll need 2 buttons each to control moving forward and backward. My controller is an Arduino mega. Is 1 pin = 1 button the best solution here? Or should I use another IC for this?</p>
 31105: <p>you can use a so called shift register. One very common one is a 74HC165 shift register (<a href="https://playground.arduino.cc/Code/ShiftRegSN74HC165N/" rel="nofollow noreferrer">https://playground.arduino.cc/Code/ShiftRegSN74HC165N/</a>).</p>
<p>With one of such IC you can connect 8 buttons, however you can daisy chain max 4 to get 4 * 8 = 32 button inputs, only using 4 digital pins of the Arduino. In your case you would need 3 ICs to get 24 (thus 20) button inputs.</p>
 31668: <p>The example project below can control 16 switches. If you have a membrane keypad with 5 x 4 or 5 x 5 then you can meet your requirement.</p>
<p><a href="https://i.stack.imgur.com/sC97W.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/sC97W.png" alt="enter image description here" /></a></p>
<p>I will shortly add an example of using shift registers to have multiple inputs (the main use case of shift registers is the same)</p>
<p><a href="https://wokwi.com/arduino/projects/294980637632233994" rel="nofollow noreferrer">Link</a></p>
<hr />
<p>Below is the example using <strong>shift registers.</strong> You need three shift registers as @Michael mentioned in his answer. Here is one example where you can control 32 switches maximum. You are only using 3 data pins and two power pins. This is the main application of the shift register. You don't have to do any selection, whenever you read the serial input data, you will automatically get the status of all the 32 switches in one Go.</p>
<p><a href="https://i.stack.imgur.com/hMwoh.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/hMwoh.gif" alt="enter image description here" /></a></p>
<p>Here is the <strong>code</strong></p>
<pre><code>// File : Cascade165.ino
//
// Version 1, 5 August 2021, by Koepel
//     Initial version.
// Version 2, 5 August 2021, by Koepel
//     Layout of the wiring made better.
// Version 3, 13 August 2021, by Koepel
//     Changed 'SCK' to 'clockPin'.
//
// Cascade of four 74HC165 shift-in registers.
// Only three pins are used on the Arduino board, to read 32 switches.
//
// Using the 74HC165 is safe, because a pulse to the Latch pin 
// ('PL' on the 74HC165) will make a new start every time. 
// In case of an error or a wrong clock pulse by noise, 
// it synchronizes the data when inputs are read the next time.
//
// Based on:
//   (1)
//     Demo sketch to read from a 74HC165 input shift register
//     by Nick Gammon, https://www.gammon.com.au/forum/?id=11979
//   (2)
//     74HC165 Shift register input example
//     by Uri Shaked, https://wokwi.com/arduino/projects/306031380875182657
//
//

const byte latchPin = 9;        // to latch the inputs into the registers
const byte clockPin = 13;       // I choose the SCK pin
const byte dataPin = 12;        // I choose the MISO pin
uint32_t oldOptionSwitch = 0;   // previous state of all the inputs

const int pulseWidth = 10;      // pulse width in microseconds

void setup ()
{
  Serial.begin( 115200);
  Serial.println( &quot;Turn on and off the switches&quot;);
  Serial.println( &quot;Top row is switch 0 (right) to switch 7 (left)&quot;);
  Serial.println( &quot;Second row is 8 to 15, and so on&quot;);

  pinMode( clockPin, OUTPUT);   // clock signal, idle LOW
  pinMode( latchPin, OUTPUT);   // latch (copy input into registers), idle HIGH
  digitalWrite( latchPin, HIGH);
}

void loop ()
{
  // Give a pulse to the parallel load latch of all 74HC165
  digitalWrite( latchPin, LOW);    
  delayMicroseconds( pulseWidth);
  digitalWrite( latchPin, HIGH);

  // Reading one 74HC165 at a time and combining them into a 32 bit variable
  // The last 74HC165 is at the bottom, but the switches start numbering
  // at the top. So the first byte has to be shifted into the highest place.
  uint32_t optionSwitch = 0;
  for( int i=24; i&gt;=0; i-=8)
  {
    optionSwitch |= ((uint32_t) ReadOne165()) &lt;&lt; i;
  }

  for( int i = 0; i&lt;32; i++)
  {
    if( bitRead( optionSwitch, i) != bitRead( oldOptionSwitch,i))
    {
      Serial.print( &quot;Switch &quot;);
      if( i &lt; 10)
        Serial.print( &quot; &quot;);
      Serial.print( i);
      Serial.print( &quot; is now &quot;);
      Serial.println( bitRead( optionSwitch, i) == 0 ? &quot;down ↓&quot; : &quot;up   ↑&quot;);
    }
  }
  
  oldOptionSwitch = optionSwitch;
  delay( 25);      // slow down the sketch to avoid switch bounce
}

// The ReadOne165() function reads only 8 bits,
// because of the similar functions shiftIn() and SPI.transfer() 
// which both use 8 bits.
//
// The shiftIn() can not be used here, because the clock is set idle low
// and the shiftIn() makes the clock high to read a bit.
// The 74HC165 require to read the bit first and then give a clock pulse.
//
byte ReadOne165()
{
  byte ret = 0x00;

  // The first one that is read is the highest bit (input D7 of the 74HC165).
  for( int i=7; i&gt;=0; i--)
  {
    if( digitalRead( dataPin) == HIGH)
      bitSet( ret, i);

    digitalWrite( clockPin, HIGH);
    delayMicroseconds( pulseWidth);
    digitalWrite( clockPin, LOW);
  }

  return( ret);
}
</code></pre>
<p>Link to the shift register project: <a href="https://wokwi.com/arduino/projects/306024460940476993" rel="nofollow noreferrer">https://wokwi.com/arduino/projects/306024460940476993</a></p>
 4143: <p>For 20 buttons you can use a Keypad Matrix arrangement (plenty of examples online) where you would use only 9 pins (5 columns of 4 rows is 5+4 pins). It's slightly more involved that simple 1:1 buttons to pins, but thankfully there is a Keypad.h library that takes the hard work out of it for you.</p>
<p>If you want to be able to press multiple buttons at once you need to include diodes in your matrix to prevent &quot;ghosting&quot;.</p>
<p>Nick Gammon has a great writeup on it <a href="https://www.gammon.com.au/forum/?id=14175" rel="noreferrer">here</a>.</p>
