Built on Unity’s tutorials, Tanks!!! goes further, turning them into a live, fully featured, Multiplayer game. Get the game now, on iOS, Android, MacOS, or Windows. Then, get the source, available from the Asset Store!
Tanks!!! Reference Project is a Unity Multiplayer project that is available for free on the Asset Store. If you’ve gone through the Multiplayer tutorials on our site, it should look familiar. It’s based on the existing Tanks! tutorials, but amped up into a fully featured game. This project includes code, assets, reference material… everything you need to build the full game.
We made this project because we’ve seen and gotten a lot of direct feedback regarding how one implements Multiplayer in a production environment. So, it demonstrates how to solve some common Multiplayer challenges like compensating for latency and cheating.
Because this is architected as a production-ready game, it may be harder to digest than the existing Tanks! tutorials. So to ease people in, this project comes with a complete reference guide. You can also watch 3 part video walkthrough on Youtube right now.
So, try out the game and then download it from the Asset Store. Then, let us know what you think on this thread. I’m especially curious if this game really does help people understand Unity Multiplayer better and if we at Unity should create more “reference projects” like this one. PM me if you have detailed feedback.
If you run into any technical issues or questions, reply to this thread. Alec (AlecLarsen1989) was lead getting this project shipped and will also answer questions directly.
Can you send through more details? For example, did you deploy your own instance of the game to your Android device? The Live versions (on Google Play/App Store) are not compatible with the version from the asset store.
If you did deploy your own version to your Android device then are you using Unity 5.5.1? If you are, could you possibly send through the adb logcat dump from your Android device, as this would allow us to pinpoint the problem. If you need any further assistance, feel free to reach out
This one uses the Multiplayer services (Relay, Matchmaker). It’s also architected as a production game, which is important for multiplayer where you have network-specific considerations to workaround e.g. cheating, compensating for latency.
I’ve noticed, that all models have two versions of the same mesh, one is used as the default visible mesh, and the other has smoothed normals and is used to draw the outline and cast shadows. Is there any specific reason for this setup? I thought about writing custom smooth normal data into a separate uv channel on model import and then let my shader use that channel to get custom normals only for the outline part, so I wouldn’t have to import double the amount of meshes. Does this lead to multiple shader passes or somehow break batching or why would I want to manually import separate models?
for example:
‘TankHealth’ does not contain a definition for ''TANK_SUICIDE_INDEX"
I went poking around TankHealth.ca
I am seeing a bunch of place holder functions.
For example:
public void TakeDamage(float amount)
{
// Adjust the tank’s current health, update the UI based on the new health and check whether or not the tank is dead.
}
Is this expected?
I did a reimport and got the same results.
I have watched the 3 videos and read the TanksReference.pdf
Is there somewhere that goes into what should be coded for these functions?
I believe my issue was I imported over the old Tanks tutorial files and some old files got left behind.
I do not see _Complete-Game.unity, _Complete-Game.meta, _Completed-Assets.meta like the original Tanks did.
The reason it’s a different mesh is a fairly simple optimisation. While I don’t anticipate any hiccups with your proposed approach, it would defeat the true main purposes of smoothing out the normals in the first place:
The mesh with smooth normals and no UVs means that Unity can represent that mesh without needing to split verts at UV islands or hard normal edges, so the same geometry ends up with fewer verts sent to the GPU. This means we could render the shadows and outlines with fewer overall verts, though with a slight extra memory cost.
It also opened up the possibility to literally eliminate verts that would not contribute to the shape of the shadow or outline (although in practice we found we didn’t really need to do this all that much, if it all). You can generally get away with using a significantly lower-resolution mesh for a shadow without any visible artifacts. It’s also useful to do this so that you can make thin things that cause shimmery shadows thicker in the shadow mesh, to help eliminate those graphical artifacts.
The other, more pragmatic reason for smoothing the normals is for the outline portion of the effect (although there is no reason the outline mesh and shadow meshes need to be the same, it just made sense to do it in this case). It’s a fairly naive outline approach that simply pushes verts outwards along their normals, and if there’s a vert cut for hard shading, the faces will split apart and there will be gaps in the outline. While your approach will still work for this, there is a (probably minuscule) chance that the split verts, even though they have the same normal, may cause seams to appear in your outline. Chances are that won’t happen on desktop platforms, but mobile GPUs tend to use less accurate approximations and position representations in their hardware, and it’s possible, though perhaps not likely, that it could happen there. That’s almost certainly not a big concern though.
So in summary, the primary reason to not do it your way really is just because it’d result in a higher total vert count in the scene. If that’s not a concern of yours, then there’s no especially compelling reason not to do it that way.
This is brilliantly, mind-blowingly, amazing! Not only it’s cross platform but also CROSS PLAY? I’m going to test playing against my brother on the PC while I’m on my Android phone, I have to see it to believe this!
Hi,
I have some questions about this template. If I go to the prefabs folder and go to the tanks folder, I drag one of the tanks to a scene but it seems that its not complete, it doesn’t have movement. Shouldn’t a prefab be the final thing?.
Another question, why do people make a level, put the art work and enemies on scene and them make the player appear by code?. Whats the point?. It only makes people confused. Why not put everything on scene and make things easier to change, to custom.
Thanks.
Prefabs are used as template objects that store common functionality. So in our case, we have three different types of tanks. These tanks share common functionality, e.g. shooting and driving. So this common functionality was placed on a prefab (CompleteTank) so that if we need to change/add to it then we do it in one place. The different tanks have different visuals so these were all stored in separate prefabs, which are then parented to the CompleteTank prefab in code.
This brings us to the 2nd question. For this game, the player needs to be instantiated in code because it is a network game - there is no way of knowing how many players are going to be playing the game when building the scene. The second reason for instantiating the players in code is the fact that there are three different tanks (and different decorations and colors). There is no way of knowing what tank the player will use when building the scene.
Hi again,
Sorry to trouble you again. After reading “complete tank prefab” I went to check the template and for my disappointment I couldn’t find it. I came back to this post and then I read “complete tank prefab in code”
Could I ask a big favor to Unity?. Could you put on this template or the other tanks template, a prefab of the complete tank with this sort of firing system?. I really like it and I would like to mod it and try to learn how you do it.
If you can’t put the prefab on the template, could you export as a package and make available a link in this forum?.
Thank you again for your support and paciente.
It’s not a simple process of combining two prefabs because the code does set up some dependencies (because of networking and game management) but let me see if I can direct you. The best way to get an understanding of how the game is setup is to run it in editor and inspect the various game elements. Firstly, open the scene called “SplashScreen” and let’s hit run. Then start a Training level (let’s pick level 1). In the scene hierarchy view there is an instance of CompleteTank, as seen in the image below.
If you click on the instance of the CompleteTank and check the inspector, you will notice multiple components - scroll down until you see TankShooting, as per the screen-grab above. You will also notice the TankMovement script. These scripts have handle the control of the tank. If you scroll down further, you will see TankKeyboardInput and TankTouchInput. These scripts pass user input to the TankShooting and TankMovement scripts. The reason for this is that this game is cross platform and this is the best way to ensure code re-use.
So I’ve listed some of the code that is essential to the tank control (TankShooting, TankMovement, TankKeyboardInput and TankTouchInput) so feel free to look through/modify those files. Test your changes it in the Training missions. You can also make use of your IDE (MonoDevelop or Visual Studio) and set break points in the abovementioned files and use the Debugger to see how the scripts work.
I think this project has been a great guide for me to get into creating a complete multiplayer game! At the moment I’m working on an on-rails shooter. I have been having issues when it comes to parenting the player to a network transform. It would be great if someone could give me advice on the topic. Thanks!