How I Dynamically Created Buttons In Unity

I think I basically combined these two things:
* this video tutorial
* this "Action" delegate stuff
the tutorial was good and did most of it. But every single button it creates has the same functionality.
I needed to create buttons with wildly different functionality. I wasn't sure it was possible, but with that Action delegate stuff, it works. If I needed to pass parameters into the function, or return values, I'd have to do it different I guess (the documentation and some Stack Overflow messages said stuff about that).
If I have time I'll try to spell it all out here some more.
Oh yes, also need to say how I got the buttons arranged in a grid.
== Important bits from the Video Tutorial ==
at top do "using UnityEngine.UI;"
in class (main body, at top), need access to the button prefab:
    public GameObject myButtonPrefabName;
also access to the "container" (canvas) for that button:
    public Transform myButtonContainerName;
Since these are public, you can plug in your canvas and prefab button objects into them in the Unity Inspector.
@4:20
To create a button, use the instantiate prefab code:
    GameObject myNewGameObject = Instantiate(myButtonPrefabName) as GameObject;
@~4:50 to set that object as a child of the "container" object:
    myNewGameObject.transform.SetParent(myButtonContainerName);
now, part for making the functionality:
    myNewGameObject.GetComponent<Button>().onClick.AddListener(() => nameOfMyFunction(myParameter));
== Action Delegate Stuff ==
At the top of the script, add:
using System;
First, (using the video tutorial stuff) I created a method that makes whatever button I want:
 public void makeButton(string name, Action function)
     {
         
 
         GameObject myNewGameObject = Instantiate(myPrefabButton1) as GameObject;
         myNewGameObject.GetComponentInChildren<Text>().text = name;
         myNewGameObject.transform.SetParent(myGridCanvas.transform);
         //I pass in an "Action", C# delegate thing, but notice here I have to add brackets after it:
         myNewGameObject.GetComponent<Button>().onClick.AddListener(() => function());
 
         //add the button to a list, so I can elswhere delete it:
         currentGridButtons.Add(myNewGameObject);
     }
Oh right, that last bit is important. Otherwise every time I open the menu, it adds more and more duplicate buttons. When I close the menu, I use Destroy on each item in that list, and then use .Clear() or whatever n the list (otherwise it has more and more of these dead-ish items on the list every time).
Then, where I want to create some buttons, I just go:
 Action myDelegate = this.buttonFunction1;
         makeButton("button 1 text", myDelegate);
 
         myDelegate = this.buttonFunction2;
         makeButton("button 2 text", myDelegate);
 
         myDelegate = this.buttonFunction3;
         makeButton("button 3 text", myDelegate);
Nice and concise!
notice the "Action" key word is only in front of it the first time. The rest of the time, I'm just overwriting the variable I guess.
those functions (Unity calls them "methods") are defined elsewhere, just like all normal methods are defined.
Wow, I just tested, can make it even MORE conceise:
 makeButton("button 1 text", this.buttonFunction1);
 
         makeButton("button 2 text", this.buttonFunction2);
 
         makeButton("button 3 text", this.buttonFunction3);
That's more how I thought it should be. Glad it works!