Help with scripts for a Tower Defense Game

Hey guys,

I’m new to Unity so sorry if the question is trivial or plain crazy.

I’m working on a tower defense game, where you can control your tower manually. So far I’ve managed to get my turret to follow the cursor (which is acting as the cross hair), but I’m having problems with actually hitting my targets.

The problem is that the bullets I’m using are rather small and seem to miss the targets more often than not. As far as I can tell they are shooting over or under the targets.
What I want to do is write a script which modifies the bullets trajectory (in reality the y position of the bullet), according to the position of the cursor, that is, it it’s close (the cursor) to the turret itself the bullet should be aimed lower (to hit close targets), while if the cursor is far from the tower, the bullet should have a nice long trajectory before hitting the target.

As I’m starting out, I’m pretty sure a wall of script would do me no good, so if someone would take the time to nudge me in the right direction, giving some pointers I would highly appreciate it! :slight_smile:


Here are some details about the current set-up:

  • Currently I’m using a variable to store the y value of the spawned enemy, which then I give to the bullets’ y value. It’s not a very good/nice solution…

  • The bullet is a rigidbody, and I’m setting its velocity to move it,

  • What I’ve tried is to draw a ray from the camera (high above the screen) towards the cursor, and if it would hit an enemy I would get its y data to give it to the bullet, but it didn’t work. At all.

You could use raycasts as bullets instead of having a physical bullet.

Thank you for the quick reply!

I was considering that, the problem (for me, at my current level), is that my bullets are not “instantly travelling fast” (like they would be in an fps). So as far as I can understand, attaching a ray to the bullet would not solve my issue of the bullet missing the target because its lack of y movement.

On the other hand, attaching it to the tower firing the bullet, and seeing if it WILL hit the target would make it unrealistic I guess…

Two suggestions I can think of off the top of my head:

If your bullets are too small and so are missing, increase the size of the collider on them without increasing the render size. Depending on the level of detail in your game, this may be too obvious because the player will see a bullet fly only “near” the target it “hits”.

If the problem is that the bullets are going over or under the target, can you use a standard height for where the tower targets? For instance, if your enemies are all spiders whose bodies are 0.3 above the floor, when you fire off your bullet make sure it’s aimed at a spot 0.3 above the floor. Then you’d be aiming at “center of mass” for the models.

In thinking how I’d lay out the logic, this is what I came up with:

I am going to use “Defense Grid The Awakening” as an example. You can look up screen shots online if you haven’t played this game. If I were creating a tower I could aim in Unity for a game that looked like “Defense Grid The Awakening”, I would make the attacking aliens a capsule collider (a few would be sphere due to their shape) so that I don’t worry about shooting “between” the bits. Then I’d have the targeting take the length and depth from the map and set the height to a standard height. I’d make sure all of the enemy capsule colliders exist at that standard height. (You can picture the game surface as a big grid. The spot on the grid clicked determines the X and Z of the grid, the Y height is the default.)

If your game has flyers or enemies at multiple levels, this starts to get more complicated. The 2D mouse isn’t so good at picking target spots in 3D space.

Your other option there might be to make the enemies respond to being clicked with the mouse with OnMouseDown() and when you click on an enemy to shoot at it, the target coordinates are picked from the center of the enemy model using renderer.bounds.center or transform.position.

@ Socrates: Thank you very much for the detailed reply! Highly appreciated! (I’ve put quite a few hours into Defense Grid, so yeah, I know of it :))

I’m going to grab everything I can from the suggestions, the main issue now (which is kind of my own thread-jacking) is that I can’t stop the spawning enemies to collide with each other.

I’ve looked up every info I could find online (including UnityAnswers), yet not for my life I can make it happen. As far as I understand, I should be checking whether there is no collision (with another object), and if so, disable the collision via physics.IgnoreCollision. Yet, all I get is the usual “this shouldn’t refer to the same object” error…

Put all of your enemys into a custom layer named, enemys.

Than disable collision of enemy ↔ enemey layer.

@hallamasch thank you! It worked! :slight_smile:

Such an easy, graceful solution…I love it.

A new question has risen, quickly turning into a problem.

Is there a way to make an instantiated object check if the position it is going to spawn into would cause a collision with another spawning object (same instantiation), and somehow evade this?

Putting it simply, I want my X number of objects to spawn without hitting each other.

(just to clarify, the problem is not the collision itself (thanks to hallamasch I’ve solved that) but the fact that they are sometimes inside one another)

I guess you could simply cast a number of rays (representing the bounding box of the object you are spawning) down onto the target spawn point. If they don’t hit anything, it should be OK to spawn there. If they do, then you need pick a new spawn point.

You may also want to look at Physics.SphereCastAll and Physics.CapsuleCastAll. They can be used to check that there would be no collisions in an area. You can use that to check if there is enough space at the spot for your new enemy to stand without running into anyone else.

There are many scripts on the unity wiki and at iTween for this sort of thing. Great to read through them to see how others did it.

What exactly is the problem?

Is this a 2d game, but instead of the bullets travelling at a constant high they ‘rise’ and ‘fall’ hitting only a limited area?

e.g. topdown trebuchet game?

Or are you just having difficulty aiming correctly.

If it is the former, some simple yr 11 trig will do wonders.