Unity FPSSample

I did one of these for the 3D Game Kit, so figured I’d do one for this too. I’m going to take a look at the sample and write about anything of note. Stuff we can steal for our own projects, horrible hacks, solutions I didn’t know existed.

Repo

The first thing to note is that the repo is on github and is 18gb. A lot of people will tell you that git(hub) isn’t feasible for larger repos like this. Before LFS they’d be right.

It took me 25 minutes to download the whole thing on my 350mb connection, that puts the download speed at about 100mbps.

So although they obviously haven’t been using GitHub to develop this it shows that this isn’t something that cripples Git or the GitHub Desktop client.

Import

Something that has always been a huge burden for us on Rust is the import time. This project is no different, with a 40 minute import time.

The huge majority of the time seems to be spent importing textures. When you’re looking at the filenames being imported you have a lot of time to think. Why does it need to do this? Why can’t it do it the first time the asset is accessed? Hasn’t it already saved all the important stuff in the meta file, like max size, actual size? Couldn’t it store an average colour to show and then async load them in the background when they’re actually required?

Couldn’t you do the same with shaders? With audio files? With models and animations?

I get that we’re meant to use the cache server to try to sidestep this, and that might ease things slightly if everyone accessing the repo is in the same office and on the same network.

Packages

The packages are using the staging packages repo by default. This probably isn’t a surprise because the project requires the Unity 2018.3 beta anyway.

They seem to have taken some of the packages and dumped them into the packages folder instead of using them from the repository.

I can only imagine this is because they’ve had to make some changes to them. Hopefully that’s because they were improving/developing the packages along-side this project – so are more up to date/bleeding edge than what is on the package manager.

The alternative is that they had to hack them around to make them do what they wanted.

Audio

They wrap their audioclips in a ScriptableObject with some more configurable stuff. Seems like everyone making a Unity game still has to write their own system for this.

The way they play sounds is nice

The Play function itself is interesting

It uses a recycled list of AudioSource’s. It returns a handle in case you need to terminate the sound early. This is pretty nice and it’s really a shame that this like this isn’t built into Unity. I’m guessing they’ll do something like this eventually as a package.

Viewmodel

The viewmodel has aim sway. The arms and weapon are separate meshes and separate animators – although seem to be sharing the same animation controller. So there doesn’t seem to be any re-targeting happening here.

The shaders used on the materials on the first person weapons/arms use a special shader setting. I don’t know whether this is built into the HDRP shader or if it’s something they crowbarred in for this.

We had something like this in Rust legacy, but it was a clusterfuck. The only reason it really existed was to stop weapons sticking through the wall. This seems to also alter the FOV of the weapon (in Rust we scale it on the Z axis to change the FOV). It also seems to prevent the first person stuff from casting shadows into the world. The weapon doesn’t seem to have any self shadowing.

This shader flag doesn’t seem to affect depth, I was able to get it to clip through the world by resizing the weapon, so I can only really imagine that it exists to change the FOV.

I’d class all of this shader stuff a hack. The more elegant solution, if you were writing it in C++ in your own engine, would probably be to clear the depth and render the camera last.

Viewmodel Animation

The animation controller for the viewmodels is way more thorough than we have for Rust. In Rust we apply movements things like jumping and running using code. But we have like 20 viewmodels – so it’s hard to justify adding stuff like this on everything.

The animation system has a load of ECS modules and uses Playable Graph, so probably seems more complicated than it is.

I really struggle with this stuff. Doesn’t seem to be a way to zoom around, so can’t read any of the nodes. So I dunno, it’s obvious a lot of work has gone into it, maybe I’m just too dumb to see why all this exists instead of inside the animation controller.

Maybe it’s like the SoundDef stuff for animations? A way to programatically choose the right clip? But wrapped in the ECS system to guarantee that no-one will ever use it.

Console

There’s a console built in on the F1 key.

Convars are exposed via an attribute

Nothing special used to collect them though. Just reflection at startup.

Console commands are added via a function at startup.

Again a console is something that a lot of people seem to make themselves, would be nice if Unity supported them by default. Especially if they did it properly and integrated it with the multiplayer stuff to get replicated and client vars.

The console system is such a huge part of the source engine. You have convar settings replicated from the server, and you have client vars replicated from the client that the server can read. GMod is pretty much built on replicated vars.

Multiplayer Builds

One of the things that depresses us about Rust is we have an #ifdef SERVER system. So when we build a server we define SERVER and undefine CLIENT. When we build client we define CLIENT and undefine SERVER. That doesn’t sound like a big deal but it’s the same code, with #ifdefs everywhere. When you commit code you need to make sure it works in client mode and sever mode.

This seems to operate in a one for all type scenario. Your build can be a client or a server.

It has a terminal/console system – which works in Windows and Linux. This is something a lot of people seek out when making dedicated servers (I wrote a little blog about it once) – so this would probably be a good thing to steal.

In Rust we attempt to cull all of the stuff the dedicated server won’t need, like sounds and textures. I don’t see any of that happening here. We found that running in batchmode and shipping some assets lead to some significant memory leaks, so might want to keep an eye on that.

Being able to start a headless server and join it with one button is a pretty cool feature. I know it’s pretty standard but you can definitely see influences from UE here.

It would be great if this stuff wasn’t hidden away in these editor windows and you could add new buttons to the top play, pause, next frame buttons.

Networking

There’s a ton of networking stuff. It’s hard to tell whether the network stuff here is the standard medium level network stuff that Unity are going to release, or if it’s just a bunch of custom stuff just for this. I’d guess it’s probably both, chopped together, as an RD experiment.

They have a class for getting a server list. It’s accessing a URL, but the URL currently replies with some json with no servers.

It’s nice to know server-lists are a consideration though – they’re commonly ignored in favour of matchmaking etc.

Entities are generally serialized using two functions.

I do like this method. It is obviously error prone being order dependant, but I can see how it’s more agile than adding attributes to member variables. I tend to think that the ideal system would use a combination – but it’s really easy to get bogged down in this stuff instead of just getting shit done.

The network system appears to be tick based, has prediction/rollback etc. I haven’t tried it online but it would be pretty interesting to see what it’s capable of.

EditorHistoryWindow

Kind of useful thing to rip out and customise. Shows a list of the objects you selected so you can quickly switch back to them.

If you tick the box is makes it a favourite so it won’t be removed when you select more objects. Works on both scene and disk objects.

Summary

I didn’t have time to really look into how everything worked, so this is from a quick scan.

The ECS stuff I could live without. That might be my ignorance of it speaking, but to me it feels like I’d like to see the performance of 16 player models with it vs without it before I add 30 new classes to seemingly just animate the model.

While I’m always going to find stuff to bitch about, this is the closest I’ve seen Unity get to creating a proper PC game.