Monster shadow

VIDEO

Create a grid in Unity - Perfect for tactics or turn-based games! Part 2

Description:
Add functionality to the grid we made last video. Randomize tiles, spawning units, game flow and taking turns. This is a long video... I originally aimed for it to be nice and quick, but ended up being an unadulterated glimpse into the mind of a game dev. So enjoy! Perfect for any tactics or turn-based game. Take a shot for every time I mess up BaseUnit! Part 1: https://youtu.be/kkAjpQAM-jE Project Files: https://bit.ly/2TXh4Na Scripts: https://bit.ly/3hWmK1Y
ADD A COMMENT

Tarodev
Did you enjoy the video? *Let me know* so I can continue making helpful content!
Tarodev
@Oscar Lundin The unity tilemap system is great... for some things. For example if you want to generate a simple map with no complex logic, it's fine. If you need interaction between tiles or to perform special logic, you'll need to generate your own grid. Example: If you wanted a pressure plate tile which opens a door tile... you cannot do this easily using unity tilemaps. Also, depending on the game, it may be better to have randomly generated (procedural) maps, or it might be better to make your own level editor to make hand crafted. A basic rule of thumb is: procedural is good for rapid development, hand crafted is better for user experience.
Oscar Lundin
Yes, I wanna see how this could be used with either designed maps or if instead of a separate grid, could this be based on the unity grid so it's easy to paint tiles? could collision boxes be translated to in walkable somehow?
oliver cromwell
hell yea
Htet Wai Yan Aung
Thank you for the great video
Doly Rakotomahenina
I don't usually comment, but your channel is going to huge!! Thanks for teaching us!
kiririn 39m
Very mixed feelings about this video. It introduces so many bad practices and code smells
Tarodev
Elaborate
Mohammad Ashour
Have you considered making a turn based game with data oriented and functional programming, perhaps using a reactive library like UniRX or unidux?
NameImpending
I'm having trouble with moving the hero. It moves and destroys pieces fine but wont seem to move unless it's attacking a piece.
Tarodev
Alternatively pop into discord and I'll help you out
Tarodev
It'd be something in the move conditionals. Sounds like the attack flow works, but look carefully over what's happening when it doesn't find an attack. If you need help debugging it, I released a video recently which will be very handy in finding this problem. Check it out 😊
C N
Great stuff. Perhaps Game Grid pt3 where you add A*Star Pathfinding?
C N
@Tarodev :-)
Tarodev
Could do! I was thinking of doing another part where I add a bunch of utility. A* could be included.
Dan Darger
Dev tutorial videos don't get nearly as much love as they deserve. You are a great tutor and I really appreciate your content. Wanted you to know you're making a difference. Thank you!
Dicko
Would you mind zooming in a bit more on your visual studio next time? sometimes its hard to read
Dicko
@Tarodev Thank you!
Tarodev
For sure. If you see my newer videos I've been ensuring I do this 😊
Jpeg
Best way to ask for subs I’ve ever seen
Tarodev
Gotta be creative to get people clicking that button ;)
Ranil
This kind of video is exactly what I've been hunting for, just being able to digest someone else's thought process as they solve the problems their flow has in real time with very minimal fluff. Please do more of these kinds of videos in the future. My only criticism is that you do some things that are objectively correct for scalabity, like using scriptable objects for your units, but don't describe why it's the correct move when for exactly what you do with it its not really necessary. But other than that this was amazing.
Tarodev
@Ranil it's obvious you're not a new developer, that's for sure. As you go you'll find a lot of overlap between Web dev and game dev. Good luck on your new journey 🐙
Ranil
@Tarodev thanks so much for the in depth responses! These insights are amazing to read as someone who has just in the last week and a half started trying out game development (I've been a web developer for years so I'm not completely blind in every aspect). I really look forward to your future content!
Tarodev
@Ranil It'd be so small as to be insignificant I'd say. I tend to think of scriptable objects as little json files which are convenient to use in-editor. As long as you can keep your files organised and it all works for you, I say keep going. I would keep separation between your real scriptables and just the save data ones though. The more I think about it the more I dislike the idea though. Go back to my pokemon example.. Now when you delete a save slot you also have to find all the scriptables attached to that file and delete those too. Other than the ability to manually edit the files in the editor, I don't really see an advantage over a standard save system.
Ranil
@Tarodev I'm trying it out for a game jam and I can definitely see some flaws with it, especially when creating something on the small scale I am trying to use it for. It also made the first day of the jam feel like a slog because I didn't create any content, just systems. However, with the systems all in place, it feels like I can scale all of the systems very easily, adding new enemies, new levels, new weapon types, etc. It also helps me keep things organized since I can easily create new scenes and implement only the pieces I need and not being concerned with DontDestroyOnLoad singletons. Other than the insane amount of files in the editor, does this approach have some kind of downside in regards to file size or memory in the final build?
Tarodev
@Ranil I also watched that talk and of course this will come down to personal preference, but I hated that strategy. Using scriptable for dynamic data is a horrible idea. Imagine if you will a pokemon game where you have n number of pokemon with also the ability to have n number of save files... That's a lot of scriptables. You're much better off creating a standard save system which saves your object to disc. As I said, it's personal preference so just do what you think works best for your game 😊
Nic Haas
I'm not sure if I missed something but the hero unit is able to be placed onto the mountain tiles. What would the logic look like to prevent the player from putting the hero unit on a mountain tile?
Tarodev
When you are grabbing the free tiles, make sure you're checking the tiles walkable boolean is set to true. Also, make sure you set your mountain prefab to non walkable.
Kory
Any idea why I'm getting double spawns of each type (end of spawning units section)? Great video so far.
Tarodev
Is your grid also spawning twice? Could be duplicate grid managers. Or maybe your game manager state is being called twice for some reason. Let me know if you fix it 😊
Oya Guni
7:18 Nice played there. Thanks for the content, really useful!
MrEastgalaxy
Super good tutorial, think Scriptable Objects would be ok to implement in this system
s a
great ty!
Serkan Coskun
Great video, I actually liked the tempo you had on this one. A guaranteed subscription for me. I would recommend a separate Singleton script you can inherit from😄. I have a question though. How would you implement a move pattern and highlight the possible tiles to occupy? My approaches where not that beautiful. Thanks
Tarodev
This can depend on how complex you'd like to go. 2 steps: #1. Gathering the tiles. This can be done via pathfinding like A*, or if it's just octagonal movement by simply counting on every direction according to move distance and returning the tiles. #2. Highlighting. Use the same technique I did for the mouse over highlight, but use a separate sprite to toggle as to not conflict.
Nonx
Could you do a tutorial on how to visualize a pathfinding? plsss
Mia Bentzen
The primary reason i wouldn't have been subscribed (if i wasn't) is because of all the annoying youtuber things that keep interrupting the video (like complaining about your subscribed ratio, and the animation that keeps poping up telling me to subscribe). It adds nothing to the video, but it does take away from it, as every time the video gets interrupted by distracting nonsense i funnily enough get distracted by it, and forget what you were doing, making it harder to follow along. These things are designed for gaming youtubers who's target audience is children, your target audience is not children, adults can click on the button if they want to, stop reminding them every 5 minutes. This is especially frustrating because besides that your tutorials are actually good, which means i want to be subscribed, but these distractions really make want to not be honestly. Sorry if this comment came of mean, but i'm just really tired of every channel on youtube doing these things constantly, and i don't want to deal with it when trying to learn.
gibran zidane
I also agree with you but I subscribed anyway
Tarodev
@Mia Bentzen I'll keep it in mind for next time!
Mia Bentzen
@Tarodev I personally don't see the necessity, but i guess it can't be helped. Could you perhaps shrink the animation and remove the noise or make it more quiet? i think that would help quite a bit with how distracting it is.
Tarodev
I see what you're saying, but to be fair I do it less than any other channel I've seen. Also, even if somebody does like the channel, they may forget to subscribe which is why it's important to mention it. To cement this fact, I gain about 4x as many subs on videos where I mention it. I also hate it. I'm not sitting there laughing maniacally as I drag a subscribe notice on my video, believe me. It's a necessary evil if I ever want to make this my day job/reach and help more people. Thanks for your sub and know in the future I hate it as much as you 😘
Yulzh o
Your tutorial is really helpful. Is it possible to store information in each tile independently and generate a canvas replacing the default grass tile with different visual features according to those info? e.g. I want to make an intractable tile that can be attacked and has it's own status shown as UI image/text. Sorry for having a specific question and really appreciate your efforts. Thank you!!!
Tarodev
@Yulzh o not 1 for 1. But the same idea can be applied for sure. Save them to a scriptable object.
Yulzh o
@Tarodev Thanks for your help and I did it! One more thing to ask. I am now working on saving the grid map and I found your video about saving unity Tilemaps. I am wondering if the script (or the logic) in that tutorial applies to the grid system you introduced here. Thx!
Tarodev
Yup! That's the beauty of having the individual tile scripts. You can create a 'building' tile, just like I created a mountain tile. This building tile has a health variables which lowers when attacked. When it takes damage you can add a more damaged visual until it eventually crumbles!
SEE ALL COMMENTS


Transcript:

this is part two of the grid game series if you didn't watch part one go watch
that now and then come back here to continue
hey bros so last time i left you with this checkerboard grid
this time i'm gonna run through a whole bunch of stuff like
giving a bit of variance to the map spawning some units moving them around
attacking and a few other tips and tricks along the way
so unless i want this video to be three hours long which i don't
i'm just going to absolutely smash through it okay so if you
if you need any help with it just get into my discord and i'll help you out
with it first let's organize our tiles so right
now we just made this base tile but what if we want a whole bunch of
different logic for example i might want a mountain or a stream or
some lava and then i might only want this checkerboard pattern on my grass
so let's start organizing that let's create a new folder called
tiles and let's put our base tile in there
then let's make two unique tiles let's call this a grass tile
and then let's also make a mountain tile and open up the grass tile and this will
actually derive from our base tile okay so make sure you
use this one and not the unity tile maps one or you'll be in a world of hurt
and then also the mountain tile let's derive from the base tile
cool and then let's organize our prefabs here so let's make a
prefab folder prefabs and then in here let's make a
tiles folder and put that in there so that's now our base tile and on our
base tile let's remove the actual tile script
okay so we're never going to use this directly we're going to make
variants of it so let's right click create prefab variant
and let's call this a grass tile and then on this we'll add our grass
tile script like that and then fill in our
references and then just to make sure that
everything is working on our grid manager
let's put in our new grass tile in there and then
press play cool so it still works uh let's make another variant for our
mountain tile mountain tile and the only thing we need to do
here is maybe just make the tile like color like that
cool beans sorry in our grid managerial instead of just spawning this tile
prefab let's rename this to grass tile and then
let's also make a mountain tile like that
and here instead of spawning it all the time let's just randomly
select to spawn a mountain sometimes so in this section here this is where you
would actually create be creating your biomes
uh or your map variants so i'm just going to be randomly selecting a tile
but you might have like tile weights so for
example if you spawn maybe a stone tile you might have a weight to it
so that maybe on the next hole uh there might be a certain amount of
chance that that will also be a stone tile
um or like really complex biome logic but for now let's just do a random tile
so random tile equals and let's use the random class from unity engine range
and we'll do min 0 max 6 and if that number is equal to 3 let's
set this to the mountain tile otherwise let's set it to the grass tile
and then instead of spawning that tile prefab all the time
let's actually make it the random tile cool so now that should actually be
enough to just spawn those two as it is so let's go to our grid manager
and put in our grass tile and before we put the mountain tile on it actually
needs the mountain tile script so let's do that
and aha so we don't want to put the checkerboard on the
mountain tile do we so let's actually make this
a checkerboard logic specifically on the grass tile
so the two colors let's remove that and put it on the
grass tile let's actually remove those as we don't need them
next this init function i still want to call this a nip function on every single
tile but i don't want it to do the same thing
on every tile for example so let's actually make this
an abstract class and then this method can be a virtual
method so basically now this logic will run on all the tiles
but each individual tile has the chance to override this function and then do
specific logic for them okay so and i'll show you what i mean
uh but also we're sending in the offset here into
all the tiles and we really only need the offset in the grass tile
so instead of accepting an offset let's accept a
into x and an into y just their coordinate
okay and then on the grid manager here we'll we'll just send in the x and
the y and so on the tile and now this here is the
checkerboard pattern logic so let's remove that
and here let's override the init function
and then put that there and i know i'm going through this really rapid fire
so if you can't keep up just download the project and come in and ask me
questions it's fine so this needs the offset logic doesn't
it so let's go to our grid manager and here
let's grab this and put this here and while we're here
let's just refactor this a subscriber thorough bowman on youtube
said that i can do this in a far simpler way and he is absolutely right we can do
x plus y modulo two equals one
and that will do the exact same thing and then
we need the renderer on our grass tile but it would be a mistake removing this
and putting it on the grass tile because we could have a whole load of derived
derived tiles that need this renderer right so instead of
removing it let's just change it from private to protected
and if you don't know what protect it is it's effectively private
but your derived tiles can also access it okay so it's a good way to
allow your derived tiles to access it without polluting the namespace
cool beans so on our grass tile we are doing our checkerboard pattern and on
our mountain tile we are not overwriting it at all okay
and when you don't overwrite it at all that means just the initial logic on the
base tile will run so let's try that out let's go
back and on our grass tile on our grass tile we've got that there
and on our mountain tile we just need to put in
our variables that then in our grid manager we can now put
our mountain tile and let's give that a crack there we go
got a little bit of variance in our map now
and as you can see only the checkerboard is on the grass
and next you're probably wondering what this is and let me show you
it is in fact my subscriber ratio and as you can see that's not too good
rose subscribe all i ask is that you are deeply integrating me into your
personal lives that's all i want all right i want to make you happy and i
want to make you a better game dev so subscribe so you never miss a video
and now that that's done i can delete that
cool let's move on okay so now in our grid manager
we're just generating this grid as soon as we get out the gate all right there's
there's not really much organization going on here
so i'm going to add a game manager to my project and if you don't know what a
game manager is i'm going to link a video will be up that side of the screen
somewhere go watch it it is a fundamental part of
game design and knowing it will organize your game
scripts significantly so go watch that come back
and i will have this game manager uh up and running
okay so i've got my game manager up uh we've got our game state a num here
which can be generate grid spawn heroes spawn enemies
heroes turn enemies turn and then we've got a change state function
which will then put in logic here depending on the state
so the first one is generate grid so in our grid manager
let's make this a public static let's make this a singleton
like that and in our awake function assign that and you should know what
that is if you just watch the game manager
video and now we don't really want to do this
uh impromptu like that we will call this from the game manager so on
our game manager generate grid and we'll do grid manager
instance generate grid like that and as you can see in my start function
i'm getting the ball rolling by calling the first state generate grid
in our generate grid function when it's all well and done
we will say game manager instance update game state and i'll
change change state and the next state will be
spawn players spawn heroes cool so it's going to come in generate
the grid and then change the state to spawn heroes
and now we're in spawn heroes the best thing to do would now to be
create a unit manager so let's do that and we're getting a lot of managers here
so let's create a managers folder and call this a
units manager [Music]
and then i'll move my other manager scripts in
just to make it nice and organized all right let's make the unit manager
delete that as i won't use it and i swear the amount of times
that i make singletons i should really just have like a hotkey that scaffolds
it out because i spent half my life making uh
singletons all right so unit manager so now we
actually need some units to spawn don't we and
whenever i'm handling units i always create a scriptable object to hold
information about the unit okay so let's create a new folder here
this one will be called units and in here we'll have
two subfolders heroes and enemies and then in the base folder here let's
create a scriptable unit and let's open that up and this
will be a type scriptable object and then we'll have a create asset menu
and the file name will be uh new units and the menu name
will be scriptable units so this is just a way to right click in our
hierarchy in our project pane and create this new unit
and now what does this unit need what information does it need to hold and
just remember this is not the actual unit
but just like an encasing linking all this information together
so first let's create an e num called fraction and you can either be a
hero which will be zero or an enemy which is
one and then on here this will be faction
and then we need a prefab to the actual hero unit that we're going to spawn
so let's do that in our units uh let's create a
base unit and then let's create in heroes let's
create a base uh sorry in enemies
let's create a base enemy and then in heroes we'll create a
base hero and then let's create the actual heroes so i'm going to call
this hero1 and then i'm going to create an enemy
here called enemy one okay so there's going to be a
hierarchy here so if we go into our base hero this is
going to derive from unit base sorry base
unit and then if we go into my hero 1 that is going to derive from hero bass
bass hero so bass hero and then if we go into our enemies hero
enemy 1 that's going to derive from base enemy
and then as you guessed it base enemy is going to derive
from base unit does that make sense so we've got this
hierarchy here so at the bottom we've got unit base so we
know that every unit on the field is going to
need some shared logic for example setting
themselves to the tile or taking damage all right and then we
know that the base hero is going to need logic
like selecting the hero and then actually doing the moves like
moving the character or presenting their uh attack pattern or
whatever and then the bass here the bass enemy is
also going to need their own logic that's not shared with the other ones
that might be like the ai and the logic right there might be
ai for moving and attacking so this is a good little hierarchy to keep
everything really organized so now that we've got our scripts
let's create a new folder here in prefabs called
units and then in here as you guessed it there's gonna be
heroes and then enemies okay so so now we've got our scriptable
unit which is like our container and then we've actually got our scripts
for the actual prefab so let's create our first scriptable
unit in assets create a new folder called
resources [Music]
now this is a special unity folder and i'll show you why
in a second then create a new folder in there called
units and as you guessed it i'm going to create
more folders for heroes and enemies just to keep things really organized so
in heroes let's create our first create scriptable unit
all right so that's that asset menu that we made right here
let's call this hero 1 now here we've got our faction and let's
actually duplicate that here for enemy one okay so that's not enough
info what we actually need is the uh the unit
prefab now this will be a public unit base
and i keep it on that the wrong way unit base unit
uh unit prefab okay so here we're saying that it just needs
a type base unit but ultimately we're actually
going to be assigning uh specific heroes and units to it
uh and enemies to it okay so let's actually create this
unit so i'm going to create a script uh sprites folder
and i'm just going to import my tarot dev mascots
which i use in pretty much every video so let's actually make
our first hero so i'm going to use my snorlax
and it doesn't really need much right now i'm just going to have a sprite
renderer and then i'm going to actually have my
hero 1 script on there and then i let's create a prefab of that
so my snorlax and then harley quinn can be my first enemy
and i'll make that an enemy one and make her a prefab in enemies
so now in our scriptable objects we can go to our hero 1 and attach our
snorlax and our enemy one attach up quinn and
make sure on your enemy you change the faction to enemy
now i'll show you why the resources folder is important
so let's create a private list of scriptable oh my gosh
of scriptable units and we'll call this units now in our awake function let's
set this to units equals and we'll call resources
load all and we'll use the generic function here and we'll say it's of type
scriptable units and then to look in the units i think
that's what i called the folder units uh folder and we'll just say two
list okay so this will go into our resources
folder and look for the units folder and then
look through all the subfolders for any type of
scriptable unit and it will put it into this list here
so now we can continue the flow in our game manager
this is our next step spawn heroes so in us in our unit manager let's have a
function here called public void spawn heroes
okay now in your game you probably had a menu or something to select the heroes
that you actually want to spawn and then once you actually get into the game
you'll read the data from your save and then actually spawn those specific
heroes but for me um in this tutorial i'm just
going to say there's going to be one a hero count of
one and i'm gonna loop through the amount of
heroes that i need okay so i've only got one here so i'm
just gonna do one and i'm just gonna randomly spawn it okay so
i need to grab a random hero from this list so let's create a
private and this is going to be a generic function
get random unit and this is going to take in a faction
okay so is it going to be a hero or is it going to be a
enemy okay and this is a generic function so let's say that it
is going to be of type t where t is
base unit okay so now here i'm going to do a little bit of
lambda magic i'm going to return from our units list
where the unit faction equals the faction that we're sending in
then i'm going to order the list by random so
i'm going to use unity's random class again
and then i'm just going to return the first one and we don't actually want to
return the whole scriptable unit we just want
to return the prefab okay and because this is expecting a
return type of t we can cast it to t
so this may look a little bit daunting but i'll show you how it is called
but first i'll just go over it one time we're
going through our list we're saying we want all of them
all of the units according to the faction that we're telling it uh that we
want and then we're randomly shuffling them
around and then we're selecting the first one from this rough
ruffled stack and just returning the actual prefab okay
so here we can say var random prefab equals get random unit and it's going to
be of type hero base man base hero
and the faction is going to be hero okay so now that we've got this random one
we've only got a snorlax in there so it's going to be snorlax
uh we can spawn this now say spawned hero etools instantiate
random prefab we don't really care where it's going right now
now we need a tile to spawn it on don't we
so i'm also going to do this really rudimentary but basically i'm going to
split the tiles in half heroes are going to spawn the left
enemies are going to spawn on the right so all i need to do is get a tile
that uh x that the tile x if we go to our grid manager our
tile x is less than width divided by two
okay so let's do this let's go public tile
get hero spawn tile or something and in here we're going to
return now if you remember our tiles is a
dictionary and the key is a vector 2 the position and the value itself is the
tile so we're going to return tiles where
the t dot key dot x is less than our map width divided by
two and then let's also order these so so
that we always get a random one whoops and then return the first and we
actually only want the value okay so get hero spawn and we're going
to grab something on the left but we don't want to spawn
on a mountain do we and we don't want to spawn
on another tile that has an occupied unit
so let's create some let's add a little bit of logic here so
we're going to need two variables first one
is the boolean which will be is walkable now we're going to set this
in the inspector so for example the grass is always going to be walkable
and the mountain is always not going to be walkable
and then we're going to create two publics here so first one
is going to be of type unit base oh my golly gosh base unit
and this is going to be called occupied unit and then we'll have another
boolean here which is like the final walkable check all right so this is
going to be called walkable and i'm going to use an arrow function
here and this is just going to return it's going to say that it is in fact
walkable if is walkable is true okay and
occupied unit equals null okay because we don't want to go on another tile
that's already occupied do we so now we can just call walkable and it will check
all of our things and say yes this tile is walkable at this moment
so back on our grid manager so here not
only do we need to check that this is on the left side of the map
we also need to check that the t that the actual tile is walkable
perfect so while we're here let's also just do the get
enemy spawn and this one will be more than x and walkable okay
so basically the same thing now on our unit manager
we can so now we've grabbed our random unit we've spawned it
now we need to grab a random spawn tile so then we go grid whoops grid manager
instance get hero spawn tile once we've got that tile we need to
actually set our unit to it so we could do this
we could say spawned hero dot transform.position
equals random spawntile dot transform.position
that will place him there and then on our uh random spawn tile
we could set the occupied unit is indeed the spawned hero
and then also it would be good to actually have on the hero
what tile they're on so on our base hero on our base unit sorry public
uh tile occupied tile let's remove that as we don't need
that so then in uh unit manager
we can say our spawned hero dot occupied tile
equals the random random spawn pile cool but this actually sucks like
um we're gonna have to do this for the spawn hero
do it for the uh spawn enemies every time one of the moves we have to do this
too so it would be nice if we could just
like put this logic in one place and just make a function call and we can
let's do that on tile so on tile public void set
unit and this will take a unit base oh my god base unit
[Music] and we can grab this logic here
and plonk this right in here so the unit is now going to be this
and this is the actual tile so we don't need to even reference the random spawn
tile we can just do that and that will be set to
this as we're talking about this tile and also when the unit moves
we also want to de-allocate his current tile or else all the tiles
are going to start getting occupied units even if they're not there
so what we'll say is if units oh if unit dot occupied tile
does not equal null we'll say the unit occupied tile dot occupied unit equals
null okay so we're actually going to this
unit's occupied tile and then setting its occupied unit to null
so we have to do this if check because the very first time we spawn the unit
this will in fact be null okay and we don't want to get a null reference
exception so now that we've got this we can just
say instead of having all that logic we can
say unit manager ins no we do it we can say random spawn tile
set unit and then we can send in the spawn hero
cool bananas so let's call this from our game manager so
unit manager instance spawn heroes and am i actually continuing this flow
in grid manager yes i am cool so let's actually try that
let's go back into the game
group manager and i need to create a game manager here i've only made the
script haven't met haven't actually assigned it
game manager i also need to make a unit manager
and assign the unit manager scripts okay now let's try that uh
secrets contains no elements what are you talking about sir
so i can't find a tile which satisfies that ah because we have not set our
grass tiles to be walkable yet so all of our tiles grass and mountains
are not walkable so grass tiles is walkable true
and then our mountain child will obviously be false
let's try that there we go so it's spawning our stuff
it's not spawning our unit or is it it is where is it okay so uh
our tiles are on uh sorting so all order layer zero but our
units are also on zero so it was being covered so put that on one
and there we go let's quickly do that for the
enemies as well so in our unit manager let's just copy that and do
spawn enemies and then this can be just enemy count
and yet again uh this will obviously
depending on the level that you're going to you'll go to your level details and
you'll see what units need to be spawned and then
you'll spawn them and it probably won't be random either you'll probably be like
putting them in specific places or not but so this will be the random
unit that we're getting is not base hero it is base enemy
base enemy and the faction will be enemy and that will be spawned enemy
get hero spawn tile we'd want to get enemy spawn tile
so we've got a little bit of repeat code here so you could probably uh
make it a little bit more efficient like we've got this nice generic function
here that we're using in both times uh you could probably make this a
generic function as well but anyway so now that we're spawning
heroes we need to send it to the next game manager stage
change state and that will be now spawn enemies
so in spawn and while we're here let's just uh
we know that after we spawn the enemies we'll be wanting to go to our
hero turn so in game manager uh we
the next state will be spawn enemies cool
so let's try that that should work straight out of the gate
go and there we go spawning at random excellent so now we're heading to
the player's turn anyway so it's coming down here
and we're setting this game state to hero's turn
so now let's add some click logic some selection logic i'm just going to close
out all those because it's getting very busy
so let's do our click logic in our tile that makes sense to me let's make a void
on mouse down on our tile
and i'm sorry if you can hear some uh bassy music in the background
i have got some seriously uh crappy neighbours
had to choose my words wisely though this is a family friendly channel
so now on mouse down we only care about on mouse down
when the game state is the player's turn the heroes turn
so let's just check um if game manager instance
uh game state does not equal the player's turn uh hero
heroes down let's just return we don't want to do it
so there are actually a few branches that we need to check here
let's do if occupied unit is not null so if there is a unit on this tile
let's do some stuff so the first what we should do is actually
check if it is a hero that we're clicking on or an enemy
and it would actually be nice if in our actual hero class we have
access to the faction so let's just add
faction and before i forget i'm just gonna make sure that uh
i'm setting them to the right faction so snorlax will be a hero
quinn will be an enemy like that okay so if occupied unit
faction equals hero what do we want to do
well we want to select the hero don't we we want to select it
so that we can make a move with it um so in our unit manager let's do this
let's make a public hero base as we every time hero
base hero uh selected hero so i'm making it a hero as we don't ever
want to select an enemy uh we only ever want to make
actionable on a on a hero and then we'll create a
function down here called public void set selected hero
and that will take in a hero and then selected hero equals hero
and the reason i'm not directly manipulating that i'm actually sending
it in here is because it would be nice if on our canvas we can display like
what heroes selected and maybe the moves that they have available
okay so let's call that now in tile say grid no unit manager
instance uh set selected hero and then send in the occupied unit
and we know that it will be our type hero so let's just cast it
base hero um yeah usually i put bass on the end of
words not at the start so this is it's like throwing me off every
single time anyway so uh if they're a hero and we know that
any logic in here means that there is in fact an occupied
unit so it's either going to be a hero or it's going to be an enemy so if it's
a hero let's select it else we need to check
if we already have a selected unit so if unit manager instance selected hero does
not equal null okay so we've actually got a hero
selected here and if there is a selected hero uh
we know that the new unit that's being clicked is not a hero
so then the only scenario here is that we are clicking on an enemy
all right so in your game obviously you're going to
show uh when they when they select the hero it's going to show like a
uh their walk distance and also their attack their attacked uh squares that
they can attack on and you'll have all this logic there but
for me i'm just gonna say if you've if you've selected a hero and then you
select and then you click on an enemy you're just gonna kill it
regardless of where it is okay and obviously on your units you would
also have a health system and you'd have a function
that takes damage and does all the animations and stuff
but for me i'm just gonna delete the enemy as soon as i click it
okay it'll still give you the idea of of what
to do so i'm going to grab the enemy like this
and i know this is an enemy so i can cast it to the
base enemy and this will be occupied unit
so so now in your game you should be doing something like enemy dot
take damage or whatever or uh or maybe you should be doing something like uh
this selected hero dot attack and then sending in the unit the enemy
unit to go on attack or whatever okay but for now i'm just
going to say destroy enemy game object and i also want to
deselect our selected units so unit manager
instance uh set selected selected hero and i'm
just going to send in null now so i believe that's all we need in
the if if we click on a tile and the unit
and the tile is occupied so now we'll do an if an else statement
here we can say if unit manager instance selected hero does not equal
null all right so we have got a select we've we've already got a
selected unit and we have now clicked a tile that doesn't have a unit on it
okay so what we want to do here is move our hero to this tile so
we can use uh we're already on our tile so we can just use our set unit can't we
we can say set unit and we can send in our selected hero
like that so we're going to move our hero to this new tile
and then we want to deselect our selected hero
after that and i think that is it for that now
to actually show that we're selecting a hero
let's create a canvas your canvas and i'm going to set my canvas
scala to scale with screen size so it's all nice and uniform regardless
of the size of the screen and i'm going to create a image and this
will be called uh selected
let's put this on the bottom left and i'll make it a little bit
transparent and something like this like that maybe and i'll add some text
under it and this will be
i'll just put this as a placeholder selected hero
like that and then uh now we need a menu manager so let's
create a new object menu manager and create you know
managers here menu manager
[Music] and yet again i have found myself
needing to create a new singleton so public static menu manager
instance [Music]
perfect so now let's have a function called public void
show selected hero and oh my god and this will take in a
hero bass whoops a bass hero
[Music] all right so we need an object here so
let's make a serialized field private game
objects selected hero object
now i would probably create its own special class for this but
for now i'm just going to do this i'm going to say
selected object hero get component in children and this will be
a text component under the unity engine ui
library and i will say text is equal to now it would be nice if we actually had
a name for this hero so let's go in here uh no let's go into the actual unit base
and create a new variable here called public string
units name so then in menu manager we can say
all right what the hero is and the unit name
and then we can toggle it on to set active equals true and we can also
use this very same function to toggle it off so we can say
if hero equals null we can take this line and instead
disable it and then just return another function as we don't want to run that
so show selected hero cool so now in our unit manager so
that's handy that we made this function instead of just directly setting it
now we can say menu manager instance show selected hero and just
sense send in the hero like that cool bananas
and you know what while we're doing this menu manager
let's actually kind of do the exact same thing but hover effects
so let's let's uh duplicate this and this will now be a
tile info and let's send it over this side instead
and i'm just going to kind of like roughly put it there
and the base information will be tile info
and then also if the tile has a unit on it
let's also make another one and scale this one a bit
kind of like sub information this one here will be
uh tile units and this one will be uh units
okay so then in here let's create a tile info object or
let's just call it tile object and then
tile unit object and then another function public void
show tile info and this will send in a
tile and we can say uh let's just copy this so it's going to
be kind of the same tile object and this will be
the tile and it would be nice to have a tile name too
wouldn't it say let's create on the base tile public
string tile name and go here tile name
and then we're also going to say if this tile has an occupied unit let's
copy this and this will be the tile unit this time
it will be tile occupied unit dot unit name
and and then we're going to do the exact same thing as up here
so we can also toggle it by saying if tile equals null
then we'll take the tile object and null it and also take the tile unit
object and null that too now in our tile
see how we're hovering over it here so on mouse enter we can say
menu manager dot instance uh show tile info and just send in this
and then we can do the same when we exit but we'll toggle it off by saying
null okay and then in the same way in our unit manager this can also be
null so this this will be toggling it off as well
holy moly my throat needs some water so anyway back in unity
in our menu manager let's add the menu manager
and let's assign these things so selected hero
tile info and then tile unit info and just for a little bit of extra
organization i'm just going to do this managers uh resurrect that
take all of our managers so menu manager unit game grid
and then put that at the top perfect so let's press play
yep so we don't have names for our grass tiles so i'm going to call this
grasslands and mountain and then this will be quinn
and this will be snorlax cool bananas let's go
so there we go so we've got uh and also let's just
to make it a little bit neater disable those to start
so grasslands mountain and then it shows snorlax on top
and quinn and because we're in player turn we can click this
and our snorlax will be selected and then we should be able to click
and because we're not actually uh after our unit moves we're not actually
like uh moving the turn on we're still in player
tone i can i should just be able to click and then destroy quinn so let's
just try that again click move click move click move
destroy quinn perfect so now you would uh actually progress it onto
the enemy's turn and then you would perform some you know logic for the
enemies to try and kill the player or what have you
alright so i think that's about all i'm going to show you in this video
i'm sure this video is going to be super long as it is if you learned something
or you enjoyed it make sure you subscribe and uh like
let me know in the comments if there's anything else you would like to learn
and i will most probably make a video out of it if it's a good idea
also i'm going to be releasing a series of these type of things like how to make
the base of different specific games so if there's
another game type that you would like to know how to make
let me know and i'll make a video on it but until then
uh happy dev journeys and i will see you in the next video
ciao