Tower Defense Tutorial: Part 9 AI Tanks
In this video, we will take our new found knowledge of AI Pathfinding and apply it to real, in-game Tanks! This means AI units that move along the ground, and intelligently dodge obstacles, relentlessly marching toward your base. Luckily, we will also cover upgrading your defenses- setting up projectiles and turrets for this new enemy.
What is covered in this tutorial:
- Applying AI to an in-game enemy
- Upgrading projectile, enemy, and turret scripts to all be class-based
- Creating spawns for the ground units
- Efficiently rebuilding the AI Grid and Re-Pathing all units as needed
This tutorial uses the “A” Pathfinding Project



Thank you SOOOOO MUCH! Superb tutorials that clearly show how to implement my poor JS skills in Unity so much better. Keep on rolling! Thank you once again Gabriel. Good luck from Soviet Russia.
Thanks! I’m looking forward to the next one! This serious is awesome. I can’t wait to really dig into the A* Pathfinding to push it’s limits.
Hey Gabriel,
Great tutorial as always, really enjoyed it!
Just a small note though, I’m not sure whether others have experienced it or not, but the video may have been interupted while uploading to youtube as I couldn’t download this one to my PC via the usual sites, and when watching it on youtube it also stopped several times with the only way to continue was to start it a few seconds beyond where it stops.
My towers have a collider around them that they shoot any enemies inside of. The pathfinding uses that collider when I create a new tower so that the ground enemies never go near a tower. What did I miss?
Did you make sure the collider is set to “trigger”?
Yes. They all have sphere colliders that are set to is trigger. The air enemies go inside the collider just fine. It’s just ground enemies that avoid it.
Got it. I had the layer on my towers set to obsticles. Great tutorial by the way. It was super helpful.
Ah, I bet it’s the dual-collider issue. Make sure you have one collider just for the turret, on the “Obstacle” layer. Then, you should have a separate collider as the “radar” trigger, which should be on the default layer.
Never mind, that didn’t fix it. Now the tanks drive through my turrets.
Ok, that definitely sounds like a collider and layer issue. Did you also set your Pathfinding to use the “Obstacles” layer for Obstacles?
Also, double check that you have:
1- A separate game object, with a collider, parented to the turret. This collider should not be a trigger, and should fit the turret base, and be on the “Obstacles” layer.
2- A collider attached to the top-level GameObject of the turret, where the script is, which is set to Default layer and is a trigger.
Do you have each of those items? I’d wager somewhere in that is the issue.
That fixed it. Thank you for the help and for the great tutorial.
Awesome, your welcome!
I’ve been working on this tutorial series for a week now (after work
), really enjoy it, nice and easy to follow. Thanks so much for this!
dear Gabriel,
your tutorials are always very helpful and informative, and i was wondering if you could help me with a problem I am having in a project (unrelated to this tutorial)
I have a blob shadow projector acting as the player, and I need the shadow to fade when it is over a certain area (another shadow, in this case an alpha-mapped plain), I’ve been attempting using raycasting (which is new to me), but the fade function is called when the shadow is still a few units away, here is the section of the code concerning this:
function FixedUpdate()
{
var groundHitPoint : RaycastHit;
if(Physics.Raycast(transform.position, -Vector3.up, groundHitPoint))
{
if(groundHitPoint.collider.gameObject.tag == “Ground”)
{
transform.position.y = groundHitPoint.point.y + playerHeight; //move projector up, depending on ground height, by casting a ray
}
if(groundHitPoint.collider.gameObject.tag == “Shadow”)
{
Fade(); //call function Fade(), if ray hits shadow
}
}
}
Please inform me if I am doing this wrong, or if there is a better way, (also so you know, the first part works, where the projector is moved up depending on the terrain)
Hmm, The only think I can think of right off the bat is, maybe the transform position is somehow further ahead than the visual? Have you checked the pivot location?
I have checked, it is not that, i changed the scene up (for other reasons) and now it works when over, but will sometimes trigger when not over :/, for the gameplay idea I have, it needs to be fairly accurate….
Hmm, I’m not sure then, sorry. Just so we don’t de-rail this thread, could you send a help request via the “Site Help Desk”? Link is a the bottom of the page here
yeah, will do, sorry bout that
No problem!
Awesome stuff. any chance for a c# version?
Sorry, I’m not a C# coder, but perhaps in future tutorials from other authors?
I’m doing this awesome series of tutorial and I’m writing it in C# so if anybody want, I can give my code.
Maybe if I add comments, Gabriel can add my codes to source file…
Hey mate I’m doing these great tutorials in c# too, if you could upload your source code that’d be great, since I occasionally get stuck on some silly syntax mistakes.
Thanks Gabriel for the amazing upload!
Hey Gabriel! I have really struggled to get my NGUI to work but the buttons were invisible and didn’t highlight when pressed on. But now I read on the NGUI forums that Unity 4 doesn’t work with the free version of NGUI… What to do? What version do you have?
Hi Kevin- could you link me to the post that says it won’t work with Unity 4? I wasn’t able to find that. Thanks!
Hi guys, wanted to say thanks to Gabriel for your time and knowledge, really helped with my 1st steps into the unknown.
One thing I wanted to share to help others just learning, is with the Raycast, it will not work if you don’t have Main Camera set to a Main Camera Tag.
Took me hours to figure it out!
Cheers.
Good point- sorry if I forgot to mention that in the tutorial!
Hi Gabriel, I am trying to put in a function sellStructure in the _LevelMaster so I have another option drop down with the upgrade panel.
I already have it set to add cash back to cashCount, but I am not sure of the code to destroy the structure and not LevelMaster lol.
Thanks.
This seems to work, but prob not the best way to do it?…
function SellItem()
{
cashCount+=turretCosts[structureIndex];
Instantiate(sellExplosionEffect, transform.position, Quaternion.identity);
focusedPlane.isOpen = true;
Destroy(structureToUpgrade.gameObject);
UpdateGUI();
}
Look just fine to me- nice work adding that on!
Cool.
I have a small problem that when the tank gets to AITarget and stops, projectiles go through the tank and does not do any damage. Could this be anything in particular?
Thanks.
Hi James- can you check your code to see if anything is set to occur (OnTrigger, etc) when the tank runs into the target? It sounds like the tank’s collider is somehow being destroyed, or it’s tag/layer is being changed, so that projectiles simply ignore it.
What I have on the Tank is pretty much all the same as the turrets.
I had to create a seperate health/destroy script for the tank, because I have the tanks shooting at the base and certain towers/turrets, so I needed to place a collider which I could not place in the root because Pathfinder uses Character Controller… if that makes sense..
Anyway I got it working lol.
Thanks.
Hi again, I am trying to get a health bar over the tank which I have done by making a plane a child of the tank.
Im not sure of the code to make the plane scale down with enemy health or how to connect it up?
Here is a code courtesy of ValooFX on UNity forum, but getting errors.
http://forum.unity3d.com/threads/173833-Scale-GameObject-(Health)
#pragma strict
var enemyHealth : Enemy_Health;
var maxWidth : float = 0;
function Awake()
{
//connect to
enemyHealth = GameObject.FindWithTag(“Ground Enemy”).GetComponent(Enemy_Health);
}
function Start () {
maxWidth = transform.localScale.x;
}
function SetCurrentHealth() {
var health = enemy_Health.health;
var percentage = (enemy_Health.health/enemy_Health.maxHealth)*100;
transform.localScale = Vector3((maxWidth/100)*percentage, transform.localScale.y, transform.localScale.z);
}
Hi James!
You should really use an NGUI widget for this- it will save you TONS of drawcalls. In fact, if you used a plane for each enemy’s health, you would quickly have too many drawcalls for your game to even function on a mobile device.
There are lots of good examples and scripts for exactly this use, on the NGUI forum site, and I believe in the examples as well. Give those a look, and you’ll thank yourself later!
Sorry, I don’t have time to create a tutorial on this item right now, but hopefully in the future, as there are all sorts of uses for it!
Yep I did that the 1st time, using NGUI HUD Text, showing the health as 100. Only problem was, when the enemy health went to 0, 25 would stay on the screen even when using DestroyImmediate.
I guess progress bar would be the best, but need to find out more info on how to connect to my enemy health script.
Thanks
Hey Gabriel,
When your free can you let me know what NGUI code I need to place on the enemy script (or should it be on the Projectile), and I do not know what to place in the Event Rec and Function (on the Progress Bar).
Sorry if this seems easy, I just cant find this out!
Thanks.
I’m not quite sure what you mean there? I might do a tutorial on this in the future, but haven’t worked with it directly in recent months, so I couldn’t offer exact code, sorry. Your best bet is to dig through the NGUI examples and see how they are set up- also check out the Lunar lander tutorial for a progress bar example, I go through the whole process there!
Thats cool makes 2 of us lol.
I got it in the end after a ton of reading, happy about that
Only 1 Drawcall now for each enemy that instantiates with the health bar.
Hey Gabriel, when you make your next tutorial could you maybe include how to, using A* Pathfinder how a tank can go to another Target after 1st Target is gone?
I want to make a miner that can collect items from one target to the next as they spawn in the game.
I found out about MultiTarget Path (A* Pro) but I can not figure out how to implement that as it is in c#.
http://arongranberg.com/astar/docs/_multi_target_path_example_8cs-example.php
Thanks,
James.
That would be good for an advanced tutorial, definitely. I’ll keep it in mind!
Nice work on the healthbars and drawcalls, btw!
Hi Gabriel,
Firstly I want to thank you for all the tutorials they have helped so much.
Will you be release any more training in this tower defense series? I saw you were going to add a area effect type turret, is that still in progress?
Thanks in advance.
Thanks Darryn! The series is just bumped back in priority at the moment, I really do hope to continue it as soon as possible though. Lots more to add!
Any update on when you’ll be able to continue this Mr. Gabriel? :S
A guess at least?
I’m on part 4 and takes me a couple days for each part so I’ll be here very soon. xD
My suggestion is to do a simple quick start menu, level select, and game over, end game, for the next one. I know its not in the order but It would be good to have a beginning and end setup already so while we wait we can mess with the middle and put in other content and experiment. And possibly finish, although I doubt it cause I didn’t manage much without these tutorials and helpful people in the comments with similar problems. xD
Hi Gabriel, just wanted to say thanks for your tutorials, I wouldn’t of been able to make my game with out this! I have a short promo vid up if you’d like a look!
http://www.youtube.com/watch?v=FLAixp7IT4U
Thanks!
Such a great tutorial, and kudos to James for sharing that video. That tower defense sure looks nice.
I suck at making graphics, but this is the TD I made so far:
http://dionysus.dk/devstuff/unity3d/TowerDefense/TowerDefense.html