
A quick note about using shader as some sort of sprite list where you can specify an index and it will change the sprite used by sprite renderer.
I do know there is Sprite Library, Sprite Resolver and things like that, but when it comes to changing sprite at runtime, my first instinct is simply go for a shader as this is the approach I have been using in Substance Designer.
The shader part is straightforward, take a Texture 2D Array and an index (float), plug them in a Sample Texture 2D Array, and feed the result to Base Color. You can now change the index value to see the sprite change. I plugged red channel to Alpha because I want dark areas to be transparent (as most of the textures do).
To actually make a Texture 2D Array, it is the same as making a sprite sheet. But you need to change the type of the imported asset:


For the control part, you might think of SpriteRenderer.material, but changing this will change every instance that uses this material, which might not be what you want.
Instead, you want to get the MaterialPropertyBlock. Using it is less obvious than using materials, here's the neccessary setup:

You need to create a MaterialPropertyBlock field, and use SpriteRenderer.GetPropertyBlock(propertyBlock) to get and store the block attached to the object. You can then set the value you want (note: if you don't know yet, the name of the shader variable is the "Reference Name" of your variable, always begins with a "_").
After setting the value, use SpriteRenderer.SetPropertyBlock(propertyBlock) to apply changes.

Example: This technique is applied in Toreiroku so that each instance of a bullet type is randomized with different sprite (texture).