#3d Tower defense, can't spawn tower on tower bases

7 messages · Page 1 of 1 (latest)

slow spoke
#

I have a 3d tower defense and I need to be able to click a tower base to spawn a tower onto it. But I can't figure out how to do that at all. Unfortunately I designed the level as one mesh so I can't just pivot to spacing towards in open areas. I have set up a script that casts a ray from camera origin through mouse position on viewport, every time I left click the mouse and prints the ray cast result. Figured I needed that to interact in a 3d environment, but maybe not. Ideally I'd like to click on the base, then have a merci pop up with tower options, or even just draft n drop a tower but have it only spawn on the base. Any help would be appreciated.

lone quail
#

Hello :)

I think I don't completely understand what you've already got working and what exactly the problems are you are facing, sorry :(

You mentioned the mouse cast script is already printing positions. So that part is done?

"Unfortunately I designed the level as one mesh so I can't just pivot to spacing towards in open areas" is what I don't understand. English's not my first language - could you rephrase it or post screenshots/drawings?

About the bases you mention down below in the part about the ideal outcome: So those bases are will be there from the start, they don't change their positions and they are finite, right? They act as designated positions and they are the only locations, at which structures can be placed - do I understand that right?

I might not have time to answer right away as I'll be busy myself but I'm following this thread and maybe answering my questions makes it easier for others to join in as well :)
Anyway, it sounds like a challenge we'll have figured out in no time peepoChat

slow spoke
# lone quail Hello :) I think I don't completely understand what you've already got working ...

Yes the Ray casting for the mouse is done and prints results

I originally tried doing a grid map tile system for level layout but couldn't get it to work. So I did the layout of the level as a single mesh since I don't really need any collider info from any of the props or decor. I add the CPU that you defend and the tower bases, which yes are static and there from the star t. Yeah they're designated positions for where the tower can be placed. So far you've got it all correct.

I have a game scene with a script that right now has the mouse ray cast code. Then the level 1 scene is an instanced child scene under it. The tower bases are instanced child scenes of the level 1 scene. Sorry I can send screenshots in a bit.

lone quail
#

Ok thanks :)
If I understand correctly, you could simply check what the mouse RayCast hit by using GetCollider() and if that is a tower base, further actions can be taken.
Depending on how you want your tower options to work, this will look different.

One approach I'm coming up with right now:

  • A TowerBase class.
    One property of that class could be holding a boolean whether there's already smth built on it.
    Maybe different towers also need different bases - for example because they could differ in size. This could be done via a size enum.
    If you want to have easy control over where a base allows towers to be placed on it, you could also use a Node3D as a childnode and offer a get function for the whole node or its GlobalPosition.

  • There are endless solutions to approach the tower building code.
    One could be an InterfaceManager that is connected to a custom Signal, your Mouse script emits when a user clicks on a base. The signal's signature also passes the TowerBase that was clicked on.
    You can also go the other way round and make the InterfaceManager an autoload (which is a good idea either way) and give it a function, the Mouse script can call - smth like BaseSelected(TowerBase base).
    This TowerBase can be saved e.g. in the InterfaceManager as the TargetBase.
    Now the InterfaceManager shows buttons related to the base, one for example could be a build button.
    If that is clicked on, possible towers are displayed by further buttons. If one of those tower buttons is clicked on, the tower is placed.
    For its position you can simply use the Base's GlobalPosition + maybe an offset in the y-axis OR the GlobalPosition of the placement node I suggested earlier.

I suspect not everything I wrote will be clear right away or suit your ideas, so just ask and I'll try to explain my ideas better and adapt them to your plans :)
This is also straight out of my brain, so some stuff will not work as easily as it seems at first glance.

#

I have used a RayCast to check whether the collider in GetCollider() belongs to a certain object/class before but other times it didn't work that well - haven't figured that out yet, but your script could simply use a second raycast that is only on one physics layer, on which the towerbases are as well.
That way, if the already existing one hits some other stuff that can be interacted as well, it'll still be possible to detect and also if the raycast for the towerbase clicks finds something, your code can just decide which one's more important and disregard the other one

slow spoke
# lone quail Ok thanks :) If I understand correctly, you could simply check what the mouse R...

Wow, thank you so much. I don't understand hardly any of it, but it's very appreciated all the same. I'm very much new to game Dev and godot and I believe I may have bit off more than I can chew doing a TD game, especially with so few tutorials available for TD games. Most are for godot 3.5 and are 2d. I fully intend to complete my TD game but if I want to finish my game on time I think I'll have to pivot to something more accessible to my skill level and the time I have remaining. Gonna copy your suggestions in a Google docs though for reference later.

lone quail
#

You're welcome!
Actually I think our ideas just don't align enough just yet and my explanations probably need some refinement as well :) I do not think you're in over your head and from experience I can say you don't need all those tutorials.
It might take a little but you don't need the perfect solution right away. Actually, for a prototype it's even a good idea to just get your mechanics to work in any way that's easy for you, so you can test it as early as possible. Doesn't matter how crappy the code or how bad the performance is :)

The thing that seems the hardest to me is actually exactly what you've already got going: the mouse script :)
If you're certain, it already behaves exactly the way you want it to, that's awesome - you basically already have your whole input/control system :)

What helpse when I feel like everything is too much, is breaking my challenges down into smaller and smaller pieces until everything is easy. I'll just do the same with my explanation now as well :)

So the first thing we want, is to know whether a player has clicked on a base right?
We already have one RayCast in your mouse script that can give us the Collider it hits via GetCollider(). I don't know the gdscript name of that function but it's probably get_collider().
The problem with this is, that in the past I have been able to check what class/nodetype this collider belongs to but in my current project it didn't work. But there's a relatively easy fix for that.
We don't need an awesome solution, for now we just want one that works :D You can simply add another RayCast that points exactly to the same target point as the one you already have. Though, instead of being on the same physics/mask layer, which is probably 1, you can put the new RayCast on layer 2 or any other, so it only detects objects on this layer.