There is a mistake in the logic that handles Player's turn and Enemy's turn. 20:35 You need to set the ENEMYTURN flag immediately after the player has chosen an action. Right now as you can see it waits for 2 seconds, in that timeframe we still have our PLAYERTURN, meaning we can spam the attack button and start as many attack coroutines as we can. By changing to ENEMYTURN immediately, we block the attack button's function as it is only available in the player's turn.
I handled this by having an intermediate state called WAITING. This is a "blank" state that prevents the button spam, keeps me conscious about state switching as I'm programming, and also a state I can use later to let animations play out.
Just an extra tip and heads up for the fellow learners: You can still attack during enemy's turn because your Attack & heal buttons still show up and is enabled during enemy's turn so make sure you add an extra method that either disables or hides the button when its the enemy's turn and then ReEnables/Unhide the button when its your turn. Should be really easy to implement, just look up the tuts, they are easy to find.
Actually you cannot because of the state machine. The buttons are still there, but they do nothing during gamestate.enemy turn. still a good UI tip though
If you spam the attack button during your turn, it will start the coroutine several times until the first one to change the state. This will still perform several attacks in one turn.
@@se9979 No, milanote actually seems really good from what little I've done with it. Perhaps there's some paywall that i haven't come across yet, but it does actually seem really helpful for planning stuff. I definitely sound like a bot. I recommend you give it a go though.
@Lethn [Sees you're getting super defensive over a single comment] I think this proves I'm right, why would you get defensive otherwise unless you realized you _were_ being rude. Me: [Presses F to Doubt I'm the dumb one in this scenario]
After I followed this tutorial, I found Infallible Code's video "How to Code a Simple State Machine (Unity Tutorial)." It shows how to create a state machine and the tutorial is based somewhat off of the battle system shown in this video. I recommend that you guys check it out; it'll help you organize the code for each individual action (attacking and healing) better.
This was an awesome tutorial. You are one of the best Unity tutorial channels I've ever run into! However, I found a HUGE problem in the way this battle system works. There is now way to check if the player is spamming the Attack or Heal button, so when the button is spam clicked, you can attack or heal multiple times. I fixed it by creating new BattleStates called "PLAYERATTACKED" and "PLAYERHEALED" and immediately switching to that state when the PlayerAttack() or PlayerHeal() is called.
@@se9979 If you're thinking about a random encounter system like Pokemon, Add a property to tiles for if they are dangerous or not. Have a list of encounters your player can encounter in that general area, and perhaps set the ID for these encounters in individual tiles if you want to get more specific. Perform a random roll when the player steps or turns within one of these dangerous tiles, (Pokemon also makes the chance at an encounter more likely if the player is running.) Then store relevant level data before transitioning to the battle scene, and when it's over, load your player back where they were. (I'm still really new at game design, but I think this is how it's done from a logistics standpoint.)
I learned a lot from this. I am currently trying to make a rpg with 6 party members and each taking a turn. Now to sit at the code screen and stare till things come to me.
tbf the advertisement was also really clever, with him using the product being advertised throughout the whole video to show it off at the same time as teaching you gamedev skills. i'd say it was Brackeys that convinced you more so than the sponsor did :)
when adapting the contents of this tutorial I decided to change one key aspect. I find it a little silly to adapt a creature's stats to a prefab, create objects from prefabs every single encounter and every time you catch something etc. So instead, I just load the specific sprite that matches the fighter's name from Resources and keep all the fighter-specific data in its own instance of class Creature. That way it persists across all systems of the game.
I know you recently came back from the gates of death *spooky* and started to make new videos!! I loved the content, thank you for that, I'm not a programmer but I could finished the turned base combat you purposed and the most great party of it is that I was able by myself to clear all the bug I had and made it work!! I feel really happy for achieving that!! Thank you, Brackeys!! Your contents are awesome!! We're glad you are back =]
Hey Asbjørn, so much to say. Firstly a massive thank you for helping me get into game dev. Less than two years ago I knew nothing of this world, but since watching your videos and using them almost exclusively as a learning resource, I've gone from zero to...competent coder (bet you thought I was going to say hero). I was saddened to hear your announcement on ending your Brackey's videos, but as the old saying goes, don't be sad that it's over, smile because it happened and thanks to the medium, your youtube videos remain and are still a vital resource that I plunge into on a regular basis. Your professional approach to making clear and informative tutorials were (and still are) an absolute God send. I have you personally to thank for this new skillset and wish you the best of luck for the future. EndlessGratitude(); Patmaaan return;
There is a small problem in this project. You can spam the Attack and Heal buttons for 2 seconds because the battle state doesn't get changed immediately. I would suggest to add a new battle state like "PLAYERACTION" and change the state to that on line 62 at 20:12 before you call the Coroutine (or inside the Corioutine but before the 2 seconds wait).
I love your videos, and specially more nowadays. You've improved so much. I was watching for example one of your old videos a out parallax effect in 2d games and I have to say it, oh God it was so hard to watch. In those days you explained everything while you were writing the code like in live video, it was so slow and painful compared to your new videos lol still very useful all of them, but maybe you should remake a few of the more dense and long ones to this new format.
Gotta say that was the BEST AD EVER! It was nicely integrated, teaches people how to use a cool tool and IS part of the larger Game Development tutorials that MOST don't seem to show. YAY I did all this, with a TON of work but its like 10 mins of video. I mean great job, I think Milinote is great, I like its drag and drag. I know a Dark Theme would help, from my browser, but those sites REALLY are missing that, not sure if it has it.
Just signed up, COOL you can increase the font, and SO far does work NICELY with the Dark Theme browser extension I use. MY GAWD Why is Unity not charging me $1000 for my use of Dark THEME! - ITS free Unity IMAGINE that!
Hi Asbjorn, we missed you in Unite India. But happy to see you in FaceTime. Met Andreas and I conveyed my hearful thanks to Brackeys team. Wish you all the happiness in life. Thanks Guru.
about 2:00 - potential error (i had trouble here later when stuff spawned) its better to create emptz objects and insert picture underneath it why- if you need to scale the picture, it would scale the object that spawns on it as well, with empty object it does not have to scale yet you get scalable picture
4 Minutes in and its pass 3 PM ... Great guide ! having fun modifying with free art and thinking what changes could be made to the UI Would love to see more guides for rpg , Especially how to trigger the turn base combat from another menu. Thanks for the video !
This tutorial gave me nostalgia and inspired me to create a small pokemon game clone. I've also created a pokemon game tutorial series in unity to help anyone who wants to create something similar.
THANK YOU SO MUCH FOR MAKING THIS!!!!! Seriously I can't express how difficult it has been to find a comprehensive tutorial on this subject (paid for or for free). You have saved my game man. I'm seriously so grateful. OTL
I was literally looking for milanote after I saw a indie dev using it but I didn't know what it's name was. I thought it was notion but couldn't find the templates that matched this look so ruled it out. Thanks brackets! Not only for the great tutorial but also finishing my quest to find it!
Thank you for great videos every week!! This's I've been waiting for. By the way, I found a bug in the code. If I click the attack button or heal button again and again in my turn (before WaitForSeconds() ends), I can attack or heal many times in 1 turn. After my turn ends, I get attacked many times in 1 turn. A solution for this is add new BattleState named "PLAYER_CHOOSED_ACTION". When the attack button or heal button was pressed in player's turn, change the state PLAYER_TURN to PLAYER_CHOOSED_ACTION and fix the if statement such like "if (state != BattleState.PLAYER_TURN && state == BattleState.PLAYER_ACTION_CHOOSED) return;". Of course to fix this, we can change the UI as soon as the attack button or heal button was pressed. Thanks for reading and happy coding!
I had the same issue and solved it similarly: public enum ButtonState { ACTIVE, INACTIVE } Initiate it to ACTIVE in the Start function and set it to INACTIVE in the Button Functions before PlayerAttack or PlayerHeal are called. Reset it to ACTIVE when the Enemy Turn ends.
Oh shoot, I was just gonna have to research about programming turn-based combat and the report is due tomorrow then I saw this in my subscription feeds! Thank you!!!
Just worked this out, works great! Only difficulty I have is that whenever the enemy attacks, all it says is "enemy (clone)" rather than the name I assigned it. Aside from that tiny issue, everything works great!
That is because you are likely referencing the name of the object "enemy(clone)" instead of their assigned name. Perhaps you could make their name a bit more clear, that way you can make a clear reference to the unit?
I say thank you. You're a real lifesaver, i've been trying to do this since march! Been struggling with those unholy finite state machines with variable degrees of success.... If i ever finish my game i'll be sure to thank this channel
I've just tried it. It has worked perfectly fine (well, with minor bugs but nothing serious). This tutorial is easy to follow, and it is really easy to modify the code. I've been researching a bit and some people do actually use corroutines as FSM. WELL, my other projects will surely work really fine now!
@@MonochromeChromosome oh, nothing too ambitious. Just a "chicken fighting game". Chicken fights are a brazilian meme :) But i'll use the algorithm later to develop a game where you train a boxer to his way to success. Things are in a very early development stage however
That Battle shown in the checklist is the battle from pokemon ruby and sapphire where you choose your starter to save Professor Birch from the poochyena
As a solo developer, I tried Milanote and found it to be a much better, tailored experience than something of the likes of Trello. I had been using Trello up until now, and while it serves its purpose well, I will be using Milanote from now on. Thanks @Brackeys :D That awfully sounded like a paid comment, yikes lol
You can simplify GameObject playerGO = Instantiate(playerPrefab, playerBattleStation); playerUnit = playerGO.GetComponent(); to just playerUnit = Instantiate(playerPrefab, playerBattleStation).GetComponent(); That way you can instantiate the object while also setting a variable to one of its components. You also don't need the 'playerGO' variable.
HOLY FUCK, this couldn't have come at a more perfect time, I have a tactics move system that's broken and this may help me buff up the turn based manager
In C# (for example) if-statements allow you to have a single line command without the code block (so these { } define a "code block"). I was taught that NOT using the code block was bad practice so I always use them regardless of the situation. The problem with not using code blocks is that the if-statement does not use the commands after the first line if you don't use the code blocks. Consider this example. if (state != BattleState.PLAYERTURN) Debug.Log("THE RETURN COMMAND WILL NO BE RUN"); return; // so this return is not part of the if-statement ------------------------------------------------------------------------------------------------ if (state != BattleState.PLAYERTURN) { Debug.Log("The following return-command will be run after this call"); return; // this return is part of the if-statement } Man, I need to learn how to make simple things seem simple, this explanation is horrible :D But basically that is why.
Here is a quick breakdown of what would be really nice for milanote to be able to * Create references to other boards anywhere (like a hyperlink) * Create a KanBan board that can connect to all todo lists (KanBan boards are used by a lot of professionals for organizing which todo tasks are more important to least important and include a backlog) * Better tutorial and/or documentation if not already available on how to use milanote, if available make it easier to access I'll add onto this if/when I come up with better and/or more ideas. This is just my first impressions messing around with Milanote for an hour. Let me know what you think :) Otherwise this is a really good tool for organization!!!!
Thanks for sharing the IEnumerators, they should be heard!. I discovered them very late and no one really talks that much about their full potential. Now almost nothing runs in the updates function and i also cut down on using the animator because of the IEnumerators. Very powerfull and fairly cheap
do you have some videos/documentation where I could learn more about IEnumerators? I've been seeing them a lot recently whilst I'm learning and, like you mentioned, couldn't find much in the way of information on them.
@@rosh6369 Not really actually.. it just kinda clicked at some point, seeing them being used in all kinds of different ways over time. I'd say this video does a good job, maybe Brackeys can do a more in-depth topic on this ?? :) For me one of the most powerful things is that it can fire on one frame using the startcoroutine and then have its own independent update running, you can even loop it until you tell it to stop which is very useful for frame by frame animations and tweening positions.
@@rosh6369 good question. I have no idea if it contributes to memory leaks over time. I would assume it's unwise to keep an IEnumerator working for longer than a few seconds but who knows. I am sure that they fall under garbage collection after they end executing all of their code.
Hi @GeneratedKid500 and @omar Rodriguez I finded a weird solution, I downloaded the Brackeys's proyect in the destription (github.com/Brackeys/Turn-based-combat), I literally copied the .cs BattleSystem and Unit, and then in copied on my own porject, and magicly works (I followed all the steps in the tutorial until minut 12:40) Tell me if this works on your own project, and have a nice day :D
can somebody explain me 12:00 - 13:10 Well I did everything like in the video and it works, but I don't really understand what is happening and would like to: So what does the" GameObject =" actually mean? And what does the Unit component do?
Hi, a bit late for a response but anyway... I hope it will help. The idea is, when you use Instantiate, you copy a prefab and create a GameObject in the scene. That specific GameObject is returned by the Instantiate function, so you can store it in a variable. The Unit component is the script that you've just created, it handles all the stuff linked to the creature like health, damage etc ... We actually only need the Unit component here, not the GameObject, so we could simply do unitPlayer = Instantiate(player, ...).GetComponent();
Extremely helpful video. Really helped out, and while I will definitely add more to it, and change it so that it fits my vision for my game more, this is really useful for getting the basics down. However, I did notice that if you keep clicking on the player attack, it will cause the damage to just continually go down. I think I was able to solve this by changing the state in the PlayerHeal and PlayerAttack methods before waiting, since that will make it so that the attack and heal methods just return without doing anything else.
I really like the working off the checklist... I wonder if you would consider doing a few video's on how you figure the architectural design before you do the coding? This is the area where I get crippled with choice.
Use your imagination and put yourself in the shoes of a player who does not know anything about your design other than what he sees right now and has seen up until this point. Then go step by step meticulously. What does the player need to see? What has to be hidden from the player? Where will the UI be most visible but least obstructing? Etc.
@@DravicPL I appreciate the answer, but I think you are talking about design. I am talking about architecture. I can make something in five different ways where the end user can't tell the difference. Choosing which method to go with is the issue I am talking about.
For some reason, the unity doesn't recognise the Unit. It says "The type or namespace 'Unit' could not be found" Edit: found the answer. Unit is not a "variable". Is the name of the script you use in the player and enemy
15:22 when I try to put levelText.text = "Lvl " + unit.unitLevel, it shows this: Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?) please help
Either I skipped something you did or mashing your attack button can actually call multiple coroutines in a row and since the damage is calculated before the GameState tansition (due to the yield new Wait...) we can instantly damage the opponent to death with a few clicks per second. I added another GameState called WAITand set it to WAIT in the OnAttackButton() before the coroutine is called. Good solution? Did I miss something? Great video btw, you really help me get into the unity classes and UI!
Hey there, I'm trying to do the exact same thing but I'm unsure where exactly to put the WAIT gamestate? I'm fairly new to Unity and coding in general, please forgive me.
Simple question : imagine we are creating some kind of pokemon game. Is it better to create two different scenes for combat and world travel, or to manage to make both work in one scene ?
When coding the TakeDamage function REMEMBER TO CHANGE “void” INTO “bool”!! I missed this the first time watching and was losing my mind why calling one TakeDamage function as a bool was fine while a different TakeDamage function had an error for trying to call it as a bool.
There is a mistake in the logic that handles Player's turn and Enemy's turn. 20:35
You need to set the ENEMYTURN flag immediately after the player has chosen an action.
Right now as you can see it waits for 2 seconds, in that timeframe we still have our PLAYERTURN, meaning we can spam the attack button and start as many attack coroutines as we can.
By changing to ENEMYTURN immediately, we block the attack button's function as it is only available in the player's turn.
My man you got it
Thanks for pointing that out wow
I did it like this:
IEnumerator PlayerAttack()
{
bool isDead = enemyUnit.TakeDamage(playerUnit.damage);
if (isDead)
{
state = BattleState.WON;
enemyHUD.SetHP(enemyUnit.currentHP = 0);
EndBattle();
}
else
{
state = BattleState.ENEMYTURN;
enemyHUD.SetHP(enemyUnit.currentHP,);
dialogueText.text = "You deal " + playerUnit.damage + " damage...";
yield return new WaitForSeconds(2f);
StartCoroutine(EnemyTurn());
}
}
AND:
IEnumerator PlayerHeal()
{
playerUnit.Heal(5);
state = BattleState.ENEMYTURN;
playerHUD.SetHP(playerUnit.currentHP);
dialogueText.text = "You healed for 5.";
yield return new WaitForSeconds(2f);
StartCoroutine(EnemyTurn());
}
I handled this by having an intermediate state called WAITING. This is a "blank" state that prevents the button spam, keeps me conscious about state switching as I'm programming, and also a state I can use later to let animations play out.
Just an extra tip and heads up for the fellow learners:
You can still attack during enemy's turn because your Attack & heal buttons still show up and is enabled during enemy's turn so make sure you add an extra method that either disables or hides the button when its the enemy's turn and then ReEnables/Unhide the button when its your turn. Should be really easy to implement, just look up the tuts, they are easy to find.
*enemy begins attack*
*_player violently slaps them again_*
Actually you cannot because of the state machine. The buttons are still there, but they do nothing during gamestate.enemy turn. still a good UI tip though
If you spam the attack button during your turn, it will start the coroutine several times until the first one to change the state. This will still perform several attacks in one turn.
IF statements work for this, correct? Like if it's the enemy's turn, disable attack or something?
@@caidenbond1988 yeah it will
I can't believe that after years online I actually saw an Ad that is actually useful! Milanote sounds like what I've been looking for years!
you can just use trello, much easier
Probably bot
Evernote?
@@se9979 No, milanote actually seems really good from what little I've done with it. Perhaps there's some paywall that i haven't come across yet, but it does actually seem really helpful for planning stuff.
I definitely sound like a bot. I recommend you give it a go though.
Milanote is great 👌
mmmmm yes
Lots of yes
Mmmmmm mmmmilk
Milk
It is real
Ahhhh yeeeeeeeeeees
How to create pokemon the copyright free version
Ayy it's you! :D you helped me with code earlier today!
Or just ROM hack (since then you have all the Pokémon data)
I spend a week setting up the canvas before doing anything.
pocket rocks!
@@καλαμ come on help the poor guy, yeah that videos quality is a bit low but come on! I shared all what is important aye?
I literally spent a week building a turn based combat system then this comes out
He's a bastard for that isn't he?
@Lethn
Why are you being so rude.
@@Axodus Why are you being so dumb?
@@Axodus r/woosh you soo hard
@Lethn
[Sees you're getting super defensive over a single comment] I think this proves I'm right, why would you get defensive otherwise unless you realized you _were_ being rude.
Me: [Presses F to Doubt I'm the dumb one in this scenario]
This tutorial rocks. Thanks, man.
ba tum tsss... I see what you did there buddy
What are you playing?
Yotsuyu Yagiyama stand
...What?
Mr Everything 70 what
Noice joke my dude
Ice-y what you did there pal
After I followed this tutorial, I found Infallible Code's video "How to Code a Simple State Machine (Unity Tutorial)." It shows how to create a state machine and the tutorial is based somewhat off of the battle system shown in this video. I recommend that you guys check it out; it'll help you organize the code for each individual action (attacking and healing) better.
This was an awesome tutorial. You are one of the best Unity tutorial channels I've ever run into!
However, I found a HUGE problem in the way this battle system works. There is now way to check if the player is spamming the Attack or Heal button, so when the button is spam clicked, you can attack or heal multiple times.
I fixed it by creating new BattleStates called "PLAYERATTACKED" and "PLAYERHEALED" and immediately switching to that state when the PlayerAttack() or PlayerHeal() is called.
Thank you so much!
most repeated words of 2019: "so let's go ahead and get rid of our start and update functions"
for people who are about to watch this video, 100% WORTH IT!! Follow along the whole 30 mins. completely customizable and very user friendly!
When you're just starting to create an RPG game and this pops into your recommended...
I need help: do you know some way to make random encounters or some video that talks about it?
@@se9979
If you're thinking about a random encounter system like Pokemon,
Add a property to tiles for if they are dangerous or not.
Have a list of encounters your player can encounter in that general area, and perhaps set the ID for these encounters in individual tiles if you want to get more specific.
Perform a random roll when the player steps or turns within one of these dangerous tiles, (Pokemon also makes the chance at an encounter more likely if the player is running.)
Then store relevant level data before transitioning to the battle scene, and when it's over, load your player back where they were.
(I'm still really new at game design, but I think this is how it's done from a logistics standpoint.)
@@redgeoblaze3752 That sounds right.
a role playing game game?
I learned a lot from this. I am currently trying to make a rpg with 6 party members and each taking a turn. Now to sit at the code screen and stare till things come to me.
The sheer quality of this tutorial is amazing
I think it’s the first time ever that a sponsor convinces me to try the product that it sells!
tbf the advertisement was also really clever, with him using the product being advertised throughout the whole video to show it off at the same time as teaching you gamedev skills. i'd say it was Brackeys that convinced you more so than the sponsor did :)
when adapting the contents of this tutorial I decided to change one key aspect.
I find it a little silly to adapt a creature's stats to a prefab, create objects from prefabs every single encounter and every time you catch something etc.
So instead, I just load the specific sprite that matches the fighter's name from Resources and keep all the fighter-specific data in its own instance of class Creature. That way it persists across all systems of the game.
I know you recently came back from the gates of death *spooky* and started to make new videos!! I loved the content, thank you for that, I'm not a programmer but I could finished the turned base combat you purposed and the most great party of it is that I was able by myself to clear all the bug I had and made it work!! I feel really happy for achieving that!! Thank you, Brackeys!! Your contents are awesome!! We're glad you are back =]
Hey Asbjørn, so much to say. Firstly a massive thank you for helping me get into game dev. Less than two years ago I knew nothing of this world, but since watching your videos and using them almost exclusively as a learning resource, I've gone from zero to...competent coder (bet you thought I was going to say hero). I was saddened to hear your announcement on ending your Brackey's videos, but as the old saying goes, don't be sad that it's over, smile because it happened and thanks to the medium, your youtube videos remain and are still a vital resource that I plunge into on a regular basis. Your professional approach to making clear and informative tutorials were (and still are) an absolute God send. I have you personally to thank for this new skillset and wish you the best of luck for the future.
EndlessGratitude();
Patmaaan
return;
There is a small problem in this project. You can spam the Attack and Heal buttons for 2 seconds because the battle state doesn't get changed immediately. I would suggest to add a new battle state like "PLAYERACTION" and change the state to that on line 62 at 20:12 before you call the Coroutine (or inside the Corioutine but before the 2 seconds wait).
what would that look like?
I love your videos, and specially more nowadays. You've improved so much. I was watching for example one of your old videos a out parallax effect in 2d games and I have to say it, oh God it was so hard to watch. In those days you explained everything while you were writing the code like in live video, it was so slow and painful compared to your new videos lol still very useful all of them, but maybe you should remake a few of the more dense and long ones to this new format.
Perhaps the changes in Unity 2020 will be reason enough to update old video tutorials in the new style
Blender Guru did something similar when Blender 2.8 came out. So, why not the same for Brackeys?
The best youtube channel if you want to learn unity3D! Thanks!
Gotta say that was the BEST AD EVER!
It was nicely integrated, teaches people how to use a cool tool and IS part of the larger Game Development tutorials that MOST don't seem to show. YAY I did all this, with a TON of work but its like 10 mins of video.
I mean great job, I think Milinote is great, I like its drag and drag. I know a Dark Theme would help, from my browser, but those sites REALLY are missing that, not sure if it has it.
Just signed up, COOL you can increase the font, and SO far does work NICELY with the Dark Theme browser extension I use.
MY GAWD Why is Unity not charging me $1000 for my use of Dark THEME! - ITS free Unity IMAGINE that!
Dude you're a life saver. This is a great place if you're new to unity and learn. Thanks for everything.
Hi Asbjorn, we missed you in Unite India. But happy to see you in FaceTime. Met Andreas and I conveyed my hearful thanks to Brackeys team. Wish you all the happiness in life. Thanks Guru.
about 2:00 - potential error (i had trouble here later when stuff spawned)
its better to create emptz objects and insert picture underneath it
why- if you need to scale the picture, it would scale the object that spawns on it as well, with empty object it does not have to scale yet you get scalable picture
4 Minutes in and its pass 3 PM ... Great guide ! having fun modifying with free art and thinking what changes could be made to the UI Would love to see more guides for rpg , Especially how to trigger the turn base combat from another menu.
Thanks for the video !
This tutorial gave me nostalgia and inspired me to create a small pokemon game clone. I've also created a pokemon game tutorial series in unity to help anyone who wants to create something similar.
THANK YOU SO MUCH FOR MAKING THIS!!!!! Seriously I can't express how difficult it has been to find a comprehensive tutorial on this subject (paid for or for free). You have saved my game man. I'm seriously so grateful. OTL
All my questions answered in one video. Thanks!
I have no idea how he manages to speak and type this fast at the same time though...
Wow I didnt know we could call "yield return WaiforSeconds" multiple times in one IEnumerator!! So much cool ideas just popped up in my head XD
I was literally looking for milanote after I saw a indie dev using it but I didn't know what it's name was. I thought it was notion but couldn't find the templates that matched this look so ruled it out. Thanks brackets! Not only for the great tutorial but also finishing my quest to find it!
"A wild The Rock approaches..."
I love that you kept it like that. LOL
Thank you for great videos every week!! This's I've been waiting for.
By the way, I found a bug in the code. If I click the attack button or heal button again and again in my turn (before WaitForSeconds() ends), I can attack or heal many times in 1 turn. After my turn ends, I get attacked many times in 1 turn.
A solution for this is add new BattleState named "PLAYER_CHOOSED_ACTION". When the attack button or heal button was pressed in player's turn, change the state PLAYER_TURN to PLAYER_CHOOSED_ACTION and fix the if statement such like "if (state != BattleState.PLAYER_TURN && state == BattleState.PLAYER_ACTION_CHOOSED) return;".
Of course to fix this, we can change the UI as soon as the attack button or heal button was pressed.
Thanks for reading and happy coding!
I had the same issue and solved it similarly:
public enum ButtonState { ACTIVE, INACTIVE }
Initiate it to ACTIVE in the Start function and set it to INACTIVE in the Button Functions before PlayerAttack or PlayerHeal are called. Reset it to ACTIVE when the Enemy Turn ends.
@@MaxParasite Alright, I'm confused. Where exactly am i putting the inactive and active and how do i make them affect the buttons i want?
I am personally attmepting to recreate a childhood flash game in unity, it had a turn based combat system and a lot of mechanics! So thank you!
Good intro to the topic, wouldn't mind a whole series on fleshing this kind of system to show off better coding techniques & some juicy fx! \o/
Awesome video and awesome AD, perfectly integrated in the content and actually showing how it can be useful for development.
As always brackeys, you have an answer for every problem I encounter. Thanks man!
Oh shoot, I was just gonna have to research about programming turn-based combat and the report is due tomorrow then I saw this in my subscription feeds! Thank you!!!
Просто спасибо тебе за твои гайды, ты просто лучший. Столько всего пересмотрел на ютубе и твои гайды просто лучшие
Just worked this out, works great! Only difficulty I have is that whenever the enemy attacks, all it says is "enemy (clone)" rather than the name I assigned it. Aside from that tiny issue, everything works great!
That is because you are likely referencing the name of the object "enemy(clone)" instead of their assigned name. Perhaps you could make their name a bit more clear, that way you can make a clear reference to the unit?
@@RagoxHatena I just figured it out last night, but thank you for the reply!
Thank you! This is just what I needed at like the (strangely) perfect time!
I say thank you. You're a real lifesaver, i've been trying to do this since march! Been struggling with those unholy finite state machines with variable degrees of success.... If i ever finish my game i'll be sure to thank this channel
I've just tried it. It has worked perfectly fine (well, with minor bugs but nothing serious). This tutorial is easy to follow, and it is really easy to modify the code. I've been researching a bit and some people do actually use corroutines as FSM. WELL, my other projects will surely work really fine now!
@@AndersonReis42 great job:) by the way, what are you working on? Might wanna play!
@@MonochromeChromosome oh, nothing too ambitious. Just a "chicken fighting game". Chicken fights are a brazilian meme :)
But i'll use the algorithm later to develop a game where you train a boxer to his way to success. Things are in a very early development stage however
Been wanting a basics turn based combat system forever, thanks!
In the TakeDamage method you could directly return currentHP
That's cool !
"The Rock vs An actual Rock" 🤣
Nice. I'm sure a lot of students I know would love to see this stuff. Great first step.
Best unity tutorial channel ever!
That Battle shown in the checklist is the battle from pokemon ruby and sapphire where you choose your starter to save Professor Birch from the poochyena
"dwayne" johnson the "rock"....... Thanks for the tutorial. You are awesome.
It's amazing how you help people to grow in game development. I love your channel :D
I like this system. I also added my own implementation of the ATB meter from the final fantasy series.
How
As a solo developer, I tried Milanote and found it to be a much better, tailored experience than something of the likes of Trello. I had been using Trello up until now, and while it serves its purpose well, I will be using Milanote from now on. Thanks @Brackeys :D
That awfully sounded like a paid comment, yikes lol
yayy it's apparently Sunday again! good to see you post :)
That script was very structured love it
I need to make a Turn-Based Combat system for an AI tech demo for a class, so this was timed AMAZINGLY!
You can simplify
GameObject playerGO = Instantiate(playerPrefab, playerBattleStation);
playerUnit = playerGO.GetComponent();
to just
playerUnit = Instantiate(playerPrefab, playerBattleStation).GetComponent();
That way you can instantiate the object while also setting a variable to one of its components. You also don't need the 'playerGO' variable.
What if you need another component? Your version is less flexible and maintainable.
Shorting code to one liners is rarely better if at all.
HOLY FUCK, this couldn't have come at a more perfect time, I have a tactics move system that's broken and this may help me buff up the turn based manager
A video about SOLID principles in Unity would be pretty nice
Seems like something you should continue haha.
Noob question: Why does the "if" at 19:46 does not have the "{ }" after the "( )"? When should you put it and when should you not?
In C# (for example) if-statements allow you to have a single line command without the code block (so these { } define a "code block"). I was taught that NOT using the code block was bad practice so I always use them regardless of the situation. The problem with not using code blocks is that the if-statement does not use the commands after the first line if you don't use the code blocks. Consider this example.
if (state != BattleState.PLAYERTURN)
Debug.Log("THE RETURN COMMAND WILL NO BE RUN");
return; // so this return is not part of the if-statement
------------------------------------------------------------------------------------------------
if (state != BattleState.PLAYERTURN)
{
Debug.Log("The following return-command will be run after this call");
return; // this return is part of the if-statement
}
Man, I need to learn how to make simple things seem simple, this explanation is horrible :D But basically that is why.
Great video! As usual, useful content right when needed.
Here is a quick breakdown of what would be really nice for milanote to be able to
* Create references to other boards anywhere (like a hyperlink)
* Create a KanBan board that can connect to all todo lists (KanBan boards are used by a lot of professionals for organizing which todo tasks are more important to least important and include a backlog)
* Better tutorial and/or documentation if not already available on how to use milanote, if available make it easier to access
I'll add onto this if/when I come up with better and/or more ideas. This is just my first impressions messing around with Milanote for an hour. Let me know what you think :)
Otherwise this is a really good tool for organization!!!!
How would you change the BattleSystem code to have multiple enemies or multiple player-controlled characters, like in Final Fantasy?
HES BACK
This is actually what I need and its not really that difficult, thanks again!
Please make a video about camera and scaling the ui, it is so hard for me to get this right :)
btw, love your content!!!
I recommend changing the UI scale mode on the canvas to: scale with screen. It’s a lot easier to work with trust me.
is there any chance someone know how to manage multiple character in one team such as FF
Thanks for sharing the IEnumerators, they should be heard!. I discovered them very late and no one really talks that much about their full potential. Now almost nothing runs in the updates function and i also cut down on using the animator because of the IEnumerators. Very powerfull and fairly cheap
do you have some videos/documentation where I could learn more about IEnumerators? I've been seeing them a lot recently whilst I'm learning and, like you mentioned, couldn't find much in the way of information on them.
@@rosh6369 Not really actually.. it just kinda clicked at some point, seeing them being used in all kinds of different ways over time. I'd say this video does a good job, maybe Brackeys can do a more in-depth topic on this ?? :) For me one of the most powerful things is that it can fire on one frame using the startcoroutine and then have its own independent update running, you can even loop it until you tell it to stop which is very useful for frame by frame animations and tweening positions.
@@Melvin88ify Does this not contribute to memory leaks, though? they seem very powerful, I should do some digging.
@@rosh6369 good question. I have no idea if it contributes to memory leaks over time.
I would assume it's unwise to keep an IEnumerator working for longer than a few seconds but who knows.
I am sure that they fall under garbage collection after they end executing all of their code.
@@DravicPL you can keep a coroutine running as long as you like. It gets stopped on scene change/gameobject removal.
I was just looking for this... Perfect timing
12:40 - the "Unit" variable type for some reason isnt working with Unity? Is it new to the later versions in 2019?? im on 2019.2.5f1
Same problem... :(
@@Albugearu got the solution man? :( im stuck with that problem
@@omarRodriguez-es7yr Nope, I'm still trying to figure out. If I get a solution I will post it here :)
Hi @GeneratedKid500 and @omar Rodriguez I finded a weird solution, I downloaded the Brackeys's proyect in the destription (github.com/Brackeys/Turn-based-combat), I literally copied the .cs BattleSystem and Unit, and then in copied on my own porject, and magicly works (I followed all the steps in the tutorial until minut 12:40) Tell me if this works on your own project, and have a nice day :D
@@roquet11 Doesn't work. Unity gives me a CS0246 error
can somebody explain me 12:00 - 13:10
Well I did everything like in the video and it works, but I don't really understand what is happening and would like to:
So what does the" GameObject =" actually mean?
And what does the Unit component do?
Hi, a bit late for a response but anyway... I hope it will help.
The idea is, when you use Instantiate, you copy a prefab and create a GameObject in the scene. That specific GameObject is returned by the Instantiate function, so you can store it in a variable.
The Unit component is the script that you've just created, it handles all the stuff linked to the creature like health, damage etc ...
We actually only need the Unit component here, not the GameObject, so we could simply do
unitPlayer = Instantiate(player, ...).GetComponent();
You looks great today! Ou btw congrats on 900k subs!!
5:54 It was at this point that I got the joke. Dwayne vs The Rock. Well played, Brackeys. Well played.
This was a great video. Learned a lot from implementing it while following your example.
Extremely helpful video. Really helped out, and while I will definitely add more to it, and change it so that it fits my vision for my game more, this is really useful for getting the basics down.
However, I did notice that if you keep clicking on the player attack, it will cause the damage to just continually go down. I think I was able to solve this by changing the state in the PlayerHeal and PlayerAttack methods before waiting, since that will make it so that the attack and heal methods just return without doing anything else.
Nice video, helps me a lot.
I really like the working off the checklist... I wonder if you would consider doing a few video's on how you figure the architectural design before you do the coding? This is the area where I get crippled with choice.
Use your imagination and put yourself in the shoes of a player who does not know anything about your design other than what he sees right now and has seen up until this point. Then go step by step meticulously. What does the player need to see? What has to be hidden from the player? Where will the UI be most visible but least obstructing? Etc.
@@DravicPL I appreciate the answer, but I think you are talking about design. I am talking about architecture. I can make something in five different ways where the end user can't tell the difference. Choosing which method to go with is the issue I am talking about.
Brackey saving my day... Again! thank you very much!
That's funny.
Just today I've been wondering how to implement something similar. Great!
Are you going to make tutorials for Unity ECS once Entities 1.0 is released?
Honestly, i doubt that he understands ECS.
I also doubt that ECS is something that will be well recieved by the larger part of the community.
ruclips.net/video/ILfUuBLfzGI/видео.html
OMG I LOVE U
This is EXACTLY what I wanted YESS ❤
finally, i waited for this
Hey nice tutorial, would there be a chance for an extended tutorial which covers multiple combatants and different attacks/actions per combatant?
Sweet man! Thanks for making this :)
You should call this episode "Definitly not a Pokemon combat tutorial"
For some reason, the unity doesn't recognise the Unit. It says "The type or namespace 'Unit' could not be found"
Edit: found the answer. Unit is not a "variable". Is the name of the script you use in the player and enemy
I do not know why on 12:00, my characters do not spawn when hitting play,
Same for me!
@@shadikiller9431 did you ever figure it out lol
Just in time for my project!
Love your videos btw.. Great content!
Will you make an advanced tutorial about water and maybe swimming?
15:22 when I try to put levelText.text = "Lvl " + unit.unitLevel, it shows this: Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?) please help
In the Unit Class, make sure the unitLevel variable is an int instead of float.
It is an integer. The problem was with something else. Thanks for your efforts, by the way
Merry Christmas from Majou ;)
Thank you so much I have been looking for a good turn based tutorial
Thanks so much! These tutorials make my day a whole lot better!
Either I skipped something you did or mashing your attack button can actually call multiple coroutines in a row
and since the damage is calculated before the GameState tansition (due to the yield new Wait...) we can instantly
damage the opponent to death with a few clicks per second. I added another GameState called WAITand set it
to WAIT in the OnAttackButton() before the coroutine is called. Good solution? Did I miss something?
Great video btw, you really help me get into the unity classes and UI!
Hey there, I'm trying to do the exact same thing but I'm unsure where exactly to put the WAIT gamestate? I'm fairly new to Unity and coding in general, please forgive me.
Simple question : imagine we are creating some kind of pokemon game. Is it better to create two different scenes for combat and world travel, or to manage to make both work in one scene ?
Exactly what I was looking for this week. Nice work.
This is awesome! I’m just starting to learn and this was very helpful. Thank you ^_^
You make this look so easy XD
I suck at making turn based games, hopefully this will help :)
When coding the TakeDamage function REMEMBER TO CHANGE “void” INTO “bool”!! I missed this the first time watching and was losing my mind why calling one TakeDamage function as a bool was fine while a different TakeDamage function had an error for trying to call it as a bool.
"The player should be a rock. That's just inherently cool"
Lmao.
Thanks for the help i am working on an rpg for my coding class and this was a big help