Steam (Part II)
Updated: Aug 22, 2019
If you're seriously looking to add Steam to your Unity game, then let me start by saying I cannot recommend in Principle's YouTube tutorials enough. They gave me 3/4 of what I needed to know, and they start you from absolute zero...as opposed to the official Steam videos that seem to be written for people who already know what they're doing. So go ahead and hit up the link above, but I'll give you the highlights here:
First, you're going to need to download Steamworks.NET, which is the most popular C# wrapper for the Steamworks SDK (you'll need that too, but not until later). There are others, but I like this one because the documentation is better, and because they favored 1:1 coverage of all the Steamworks C++ methods. What this means is that you'll be able to use the official Steamworks documentation as well, because every C++ method has an identical C# version it .NET. The code comes down as a Unity package, so just open it in your project and import everything.
The most important class you'll be interfacing with is the Steam Manager. A DontDestroyOnLoad singleton by default, you really just need to add it to a gameObject in your first scene and let it do its thing. Note that you'll need to put in your personal AppId in that script and in an external text file...don't worry, the video covers all of that. I'd also highly recommend the master Boolean which controls whether we should even attempt to ping Steam or not, as that will have an effect on whether you can run the game offline or port it to any other form of release.
That there is the absolute minimum integration you'll need. Congratulations. If you want to do anything else, though, the first step is to check the SteamManager.Initialized value that gets set in our first script. It's another guard against trying to do something without Steam being set up. I also checked the bool first, because otherwise you'll be creating a new singleton instance just to find out that one didn't already exist and wasn't needed. ...Just some design flow code, there. From that point, stuff like achievements are really easy; assuming you've already gone through the steps of setting them up online, just call SteamUserStats.SetAchievement() and pass in the string id. That'll queue up the update, so just follow it up with SteamUserStats.StoreStats() to push to the server. I do all of this in my save routine, so the local and server data are always in sync.
I also wanted leaderboards in my game, both the ability to push to them and to retrieve player rankings on them. This is more complex because the way Steam handles callbacks is kind-of convoluted. You need to first ask for the specific leaderboard you want (by id), wait for the result, ask for the entries on that leaderboard, wait for the result, and then parse through them to actually get the data you're looking for. Luckily for me, I was only ever looking for one person (either the current player or the world leader, depending on the current display settings), so the calls always came back lightning fast. It's just not very straightforward for a novice. in Principle doesn't cover leaderboards in his tutorials, but I was able to figure them out by looking at the use case example that comes in the Steamworks.NET download.
You can test that all of this stuff is working before even uploading your build to Steam. But when you're ready for that step, you're going to need the official SDK I mentioned before. You can pick back up with the video here, but the gist is that you navigate to the scripts folder and make sure that the files there correspond to the depots you set up based on my last post. Don't forget to set the upload message; I always do. After that, it's just a matter of actually making your game build(s) in Unity, and copying them over to the content folder (or else changing that path as well), and running the handy .bat script. You may get a Steam Guard error (because Steam Guard is all kinds of messed up as well), but follow the steps to resolve that and you should be good to go.
The very last step is to check all of this on the Steamworks website. If you see your new builds listed, you should be able to click and scroll through the list of files to confirm that everything's there that should be. Then you'll need to set that upload to the default branch (so that any player who downloads will get this most recent version), and hit the "Publish" tab to finally confirm everything for good.
It's kind of a lot, and I know that many people feel that either Unity, Steam, or both should do more to make the integration process easier, but if you follow the reference video, you should be fine. I've already pushed a few updates using this method as my beta testers have found more bugs, and the builds go up and down really smoothly. Good luck trying it yourself!