Pokemon Unity Tutorial – BattleManager [Pt.8]

August 23, 2019

Unity Pokemon Tutorial

BattleManager

Youtube – Lets Make… Pokemon in Unity! – Episode 8 BattleManager Code

By: BrainStorm Games

This tutorial focuses on the scripting the actual functionality of all the UI in the battle scenes. This includes giving all of the different text selections their various functionalities when the player selects them during a battle.

The intial setup for the BattleManager script was a huge pain in this tutorial. It started with creating a bunch of public GameObjects and Text objects to provide input fields in the inspector. There were almost 20 different elements created at once here. Then, we had to plug in all of the corresponding UI Text and Panel objects from the last tutorial into these fields. Many of these objects were never renamed at all (or named poorly as the script name does not match the object name in any manner). This will be workable since this is not the main reason I am doing these tutorials.

After setting all of these, they set up a switch case which uses a newly created BattleMenu enum to determine which of these UI elements should be set active/inactive at any given time. This is all done in a ChangeMenu method that takes in a BattleMenu paratmeter. This method is called in the GameManager.

Then they setup a monster nested switch case in the Update method to give the illusion of the “cursor” moving around the different menu options. Every button press goes into this huge switch case that first determines which menu you are in, and then depending on that menu, determines which text elements it needs to change (since it only wants to change those on the currently visible menu). It then resets every text element to its initial string, while changing the current string by just adding “> ” in front to look like a cursor is selecting it. The code for the menu selection is as follows:

private void Update()
{
if (Input.GetKeyDown(KeyCode.DownArrow))
{
Debug.Log(“Down pressed and currentSelection is: ” + currentSelection);
if(currentSelection < 4)
{
currentSelection++;
}
}
if (Input.GetKeyDown(KeyCode.UpArrow))
{
Debug.Log(“Up pressed and currentSelection is: ” + currentSelection);
if (currentSelection > 0)
{
currentSelection–;
}
}
if(currentSelection == 0)
{
currentSelection = 1;
}

switch (currentMenu)
{
case BattleMenu.Fight:
switch (currentSelection)
{
case 1:
moveO.text = “> ” + moveOT;
moveT.text = moveTT;
moveTH.text = moveTHT;
moveF.text = moveFT;
break;
case 2:
moveO.text = moveOT;
moveT.text = “> ” + moveTT;
moveTH.text = moveTHT;
moveF.text = moveFT;
break;
case 3:
moveO.text = moveOT;
moveT.text = moveTT;
moveTH.text = “> ” + moveTHT;
moveF.text = moveFT;
break;
case 4:
moveO.text = moveOT;
moveT.text = moveTT;
moveTH.text = moveTHT;
moveF.text = “> ” + moveFT;
break;
}

break;

case BattleMenu.Selection:
switch (currentSelection)
{
case 1:
fight.text = “> ” + fightT;
pokemon.text = pokemonT;
bag.text = bagT;
run.text = runT;
break;
case 2:
fight.text = fightT;
pokemon.text = “> ” + pokemonT;
bag.text = bagT;
run.text = runT;
break;
case 3:
fight.text = fightT;
pokemon.text = pokemonT;
bag.text = “> ” + bagT;
run.text = runT;
break;
case 4:
fight.text = fightT;
pokemon.text = pokemonT;
bag.text = bagT;
run.text = “> ” + runT;
break;
}

break;
}


}

There has to be a much better way to do a menu system like this. I’d imagine you would just want everything to be set into an array of some kind where the inputs just move through the array elements. Then you would just tie some visual representation to whatever UI element is currently selected. This just seems very frail, hard to read, and hard to edit.

Pokemon Unity Tutorial – Battle GUI [Pt.7]

August 21, 2019

Unity Pokemon Tutorial

Battle GUI

Youtube – Lets Make… Pokemon in Unity! – Episode 7 Battling GUI

By: BrainStorm Games

This tutorial focuses on setting up the GUI within a battle encounter. This includes creating the panels necessary for holding all of the information about the battle and the player’s input options.

The UI panel holding the moves was given a Grid Layout Group component. This helps when you want to layout children UI elements in a grid pattern. This component holds information such as padding (spacing added around borders of current UI elements) and cell size (how much space to give each individual grid component).

Working with UI elements in Unity is always weird and unpredictable for me, and this time was no different. When making the health bar UI canvases, I created the background (health container) and foreground (current health) health elements for the player’s pokemon first without any issue. However, when I duplicated both and tried to move them into position for the opposing pokemon, they acted very strangely. I was resizing them with their values in the insepctor and all of a sudden the foreground bar became extremely thin, like a line. Something must have “broke” when duplicating these scaling canvas UI elements and moving them as children into a different UI element that caused them to act strangely after editing them to any degree. I ended up solving this by deleting out the background element, fixing up the foreground element and just duplicating that and changing the color for the new background element for the opposing pokemon.

Unity can do UI layering in the hierarchy. The element that is lower will be shown above the other elements, which is how the foreground UI element for health was shown above the background container. This works good enough for the tutorial, but I would like to look into having more proper control for UI layering.

Pokemon Unity Tutorial – More Pokemon [Pt.6]

August 19, 2019

Unity Pokemon Tutorial

Encounter List Creation

Youtube – Lets Make… Pokemon in Unity! – Episode 6 More Pokemon!

By: BrainStorm Games

This tutorial is about actually creating BasePokemon GameObjects and using them as a prefabs. The general prefab structure is pretty simple. The object is a SpriteRenderer (with the pokemon’s sprite) and has a BasePokemon script attached that just has all the base stats filled in in the editor, along with typing in the name and also hading a sprite reference here.

We created 5 different types of this prefab for different pokemon objects and used those to populate the GameManager BasePokemon list. It turns out this list won’t be holding every pokemon that exists in the game, this will just the list of possible encounters in the current area.

The method for encountering pokemon included creating an EmptyPoke prefab as well, which acts as a placeholder that becomes one of the referenced Pokemon objects from the current GameManager list. The battle instantiates this EmptyPoke object, and then uses the reference from the randomly selected Pokemon object from the list to basically add a BasePokemon component to this EmptyPoke object and copy all the relevant data over to it.

Finally, they added some transform objects to locate your pokemon and the opposing battle pokemon in the battle scene. These objects are just referenced as where to instantiate Pokemon objects (and as a result, their sprites).

Testing and Debugging

Problem 1: Generating Empty Lists that Were Being Accessed

I was getting an error that GetRandomPokemonFromList from attempting to access an array element out of the bounds of the current list being given to it. It turns out this is because I only put VeryCommon and Common rarity pokemon as options to be found, so when any other rarity (Rare, Semirare, VeryRare) were being rolled for the encounter, it was defaulting to trying to access the first element of an empty list.

Solution

I was able to solve this by adding a check for an empty list and having the method return null in that case, then the rest of the methods using this data would check if it was null first before performing their actions, so they would only proceed if they had an object to work with first.

Problem 2: Missing Encounters

I added my own EndBattle method to the GameManager script just to make testing multiple encounters easier and found an issue where it did not seem like every pokemon in the list was coming up as an encounter. I know RNGs can be a bit repetitive, so I tested for a while but it was clearly missing some encounters.

Solution

It turns out the Random.Range int they were using with bounds of 0 and list.count – 1 did not need the (- 1) since the high bound is an exclusive bound. With the (- 1), one pokemon from each rarity tier was being left out as an option. Removing the (- 1) fixed my issue, and all pokemon were appearing (eventually).

Pokemon Unity Tutorial – More Pokemon Integration [Pt.5]

August 19, 2019

Unity Pokemon Tutorial

Class Data Management

Youtube – Lets Make… Pokemon in Unity! – Episode 5 – More Pokemon Integration

By: BrainStorm Games

This tutorial focused on creating the Player class and increasing the functionality of the BasePokemon class.

The Player class contained a list of OwnedPokemon, which was a newly created class within the Player script.

The BasePokemon class added some new features to work with evolution. The PokemonEvolution class was created, which held a BasePokemon that is the next evolution and an int for the level at which the evolution should occur. A PokemonEvolution variable was created within the BasePokemon class which would hold a reference to what pokemon a single one could evolve into.

There was also a lot done with the GameManager script. A PokemonMoves class was created that would provide the foundation for all the different types of attacks in the game, as well as a new MoveType enum, which categorized the moves (as physical, special, or status). There was also a Stat class that was created that just held a float for a minimum value and a float for the maximum value. The GameManager class itself also got a list of BasePokemon called allPokemon, and a list of PokemonMoves called allMoves. I am assuming these will just be used to hold some style of reference to every unique type of pokemon and move in the game.

The GameManager class also contained the methods for determining which Pokemon is randomly encountered in battles. A List method, GetPokemonByRarity, was created which basically takes an input of a Rarity enum and then looks through the current list of allPokemon and creates a new list with only those that have the same rarity value as designated by the input Rarity. Then another method, a BasePokemon method called GetRandomPokemonFromList, simply takes a BasePokemon list input (the list created by GetPokemonByRarity) and then randomly chooses one of the BasePokemon from that list and returns it. This combinations works to determine the specific pokemon encountered when calling a random encounter.

Again, things seem to be run a bit inefficiently (for example, populating this rarity list every time a battle is encountered) but I’ll be interested to see where it leads. This tutorial was a lot of setup that will make more sense once the system gets put in motion.

Pokemon Unity Tutorial – Player Movement [Pt.4]

August 15, 2019

Unity Pokemon Tutorial

Random Encounters

Youtube – Lets Make… Pokemon in Unity! – Episode 4 Encountering Pokemon in Long Grass

By: BrainStorm Games

This tutorial sets up the random encounter mechanic. This starts with the script LongGrass, that deals with 2D colliders to allow for a probability check when the player collides with certain tiles to see if they encounter a random battle and what is encountered.

The setup places a 2D box collider on each LongGrass tile that is a trigger. The player character has a 2D box collider (not as trigger) and a RigidBody 2D component. They just set the gravity scale of the RigidBody 2D to zero and that was it. These seems like an improper time to use a RigidBody 2D component as we’re just using it to detect a trigger collision.

I also tried modifying some values in the RigidBody 2D so it fit the situation better, but none of them interacted with the LongGrass colliders properly. I tried making the Body Type “Kinematic” instead of “Dynamic”, as well as checking off “Simulated”, but neither of these collided with the LongGrass triggers at all. In testing this, I placed a Debug.Log in the OnTriggerEnter2D encounter method just to make sure it was detecting the collisions, and I noticed a bug where moving left or right in the LongGrass was actually calling for an encounter chance twice for some reason. This also did not apply when moving up or down, just for left and right motion.

The way they switch from the overworld game to the battle scene also seems improper. They aren’t seperate scenes, they are just two different cameras placed in different locations in the scene space. The transition from the overworld to an encounter just turns off the overworld camera and turns on the battle camera. This seems sloppy and cluttered as you then have everything running in a single scene at all times.

Another note I did not like was that the LongGrass gets the GameManager component by tag. They created a “GameManager” tag for the GameManager and that is what they use to reference it and grab its script from other scripts. I am becoming less of a fan of tags as I work with various Unity projects as they are annoying to keep track of and finicky in code since they require typing an exact string value in. This can be lessened by creating a string variable to hold the tag name in your script so at least you only need to type it out properly once for that script, but it still seems to be a pain to work with and error prone, not to mention difficult to modify.

Tutorial – Creating a Realistic Boat in Unity

August 14, 2019

Realistic Boat Physics

Unity

Harbrador – Make a realistic boat in Unity with C#

By: eriknordeus

As someone interested in using real world physics and applying it with Unity’s physics engine, this tutorial just looked very interesting and promising. It appears they do a lot of work determining buoyancy as well as air and water resistance using the actual mesh of an object. They also split the code up in a nice way, separating a lot of the math into its own class to keep scripts organized and easier to use/read, so I wanted to look into that organizational setup. Overall, this is just a cool project that has a lot of factors I want to learn more about (physics in unity, organizing scripts, applying real world concepts to Unity/games).

HFFWS Object Instantiation and Setting Their Node Values

August 13, 2019

Human Fall Flat Workshop

Instantiating Objects with Nodes

Youtube – Moving Platform Tutorial in Unity for Human Fall Flat

By: Gotcha McFee

I just wanted to reference this tutorial again as this is how I got the moving platform in the first place for HFFWS. This also shows why I am interested in the specific components and their values when instantiating the object. This object also has a lot of node graph involvement, which is a big part of HFFWS in general, so it shows why being able to control their values in script is so necessary.

Creating Object Spawner

I wanted to create a script that could take some of these HFFWS prefabs and start spawning them with various values for their variables to see if I could produce varied objects in real time in the game.

This script needs to be able to:

  • Take a prefab reference
  • Access certain components (or children’s components)
  • Access the parameters of the components(s)
  • Randomly set them (within a given threshold)
  • Create instances of the prefab with these given values

The components for MovingPlatformVertical that we need access to are:

    Parent

  • Mesh Renderer
  • Mesh Filter
  • Mesh Collider
  • Signal Math Mul (Script): In 2
    Children (Axis)

  • Transform (Rotation)
  • Linear Joint
    • Max Value
    • Max Speed
    • Max Acceleration

It turns out SignalMathMul and LinearJoint are both part of the HFFWS .dll file. You can gain access to these classes in script however with the namespace “HumanAPI”. So at the top of your Unity C# script, you just need to add “using HumanAPI” to reference this namespace to create variable references for these classes.

The next issue I ran into however was attempting to set node values within script. SignalMathMul uses the node system, and I wanted to change the In 2 value of this component in script. By creating a variable reference for a SignalMathMul object, I saw there was simply a variable I could access within it called “in2”, which seemed like the variable I was looking for. Trying to set this as a float, I got an error telling me this was actually of type NodeInput. After creating this object, I looked at the methods and variables available and found one simply called “value”. So I tried setting the value of my number NodeInput to 0.5f, and then setting this signalMathMul.in2 to number (in an attempt to set the input 2 value of the signalMathMul component to 0.5f) but this just resulted in 0 at run time.

TESTING

I think that something with the whole Net Body setup may be causing issues, as this may not like values of these components being set at run time. This may be causing some value discrepancy for a very brief moment that when the networking system sees it it just defaults values to zero.

Initially, I was trying to instantiate a new moving platform with the given SignalMathMul values. I then tried to just alter the values of an existing in scene platform with the script. This also appeared to fail at first, as the inspector showed a value of 0 again. With further testing, this setup does appear to actually set the internal input node value. This change is not reflected in the Unity editor, but when play testing it did change the behavior of the platform. Upon further inspection in the node graph, it could also be seen here that the value was actually being set to that given in the script. I then went back to use the exact same setup but with instantiation again, and this did not work still. Again, this just set the input to zero. I checked in play mode in the updating node graph, and this confirmed it was actually set to a value of zero.

I then tried instantiating the object, and then changing its input values. This created an instance of the prefab with its default values just fine. The platform was moving properly. This however did not update the platform values with the scripted values.

SOLUTION

Since none of these approaches with setting in2.value to a number were working, I checked the methods and variables available again and saw there was also an initialValue variable for the Node Input class. I then tried setting in2.initialValue instead with my instantiated platform and this worked as intended. The value was properly set (in editor as well as in the node graph) and the platform’s moving behavior changed accordingly. The resulting script looks as follows:
public GameObject movingPlatformPrefab;
private SignalMathMul signalMathMul;
private LinearJoint linearJoint;

private void Awake()
{
GOInstantiatePlatform();
}

private void GOInstantiatePlatform()
{
GameObject newPlatform = (GameObject)Instantiate(movingPlatformPrefab);

newPlatform.GetComponent().in2.initialValue = 1.2f;
}

I left the extra component references in for later if I need them, and I was doing the instantiation in Awake through testing in case spawning it “later” was doing something weird with the networking scripts. I tested running it in Start instead and this also worked just fine.

HFFWS Moving Platform Tutorial

August 13, 2019

Human Fall Flat Workshop

Moving Platform Tutorial

Youtube – Moving Platform Tutorial in Unity for Human Fall Flat

By: Gotcha McFee

To start, they just went to the IntermediateLevel 1 scene to grab a copy of the moving platform prefab from there. They just placed this in a prefabs folder to use later.

This moving platform has a ton of script components on it, but the main one they focused on was called “Signal Math Nul”. Changing the second input value here changes how quickly the moving platform changes directions. A high value will make it go back to start very quickly, where a low number will take longer (and if it’s low enough, it will actually wait at the end point for some time before coming back).

Next, they showed that the child object, Axis, controls a lot about how the platform moves. By rotating this object, you can change the direction the platform moves. The other simple variables they show are:

  • Min Value: Normally just keep at zero
  • Max Value: Changes how far platform can move in given direction
  • Max Speed: Changes the top speed the platform can accelerate to
  • Max Acceleration: Changes how quickly the platform changes speed

These variables are pretty self-explanatory, but there are a few issues to note with them. Going back to the first problem where a platform that changes directions too quickly won’t even reach its maximum value, this needs to be checked when you change a platform’s Max Value. If you change this without giving it more time to change directions, it may not be ending up where you would plan on. Max Speed and Max Acceleration are values that need tested in game as they will contribute force and momentum to players that are on the platform. Having too high of values here can throw players off the platform and make it difficult to stay on.

Finally, they show that you can take this underlying foundation and place it on any object to make it move around. They child a new object to this entire setup and just turn off the old mesh components, but it’s actually easier to just change the base platform object’s Mesh Filter and Mesh Collider to the object you want (and then update the Mesh Renderer to fit this new mesh). This lets you use any mesh as a moving object.

Pokemon Unity Tutorial – Player Movement [Pt.2]

August 13, 2019

Unity Pokemon Tutorial

Player Movement

Youtube – Lets Make… Pokemon in Unity! – Episode 2 Basic Player Movement

By: BrainStorm Games

Player movement in the overworld of Pokemon games is tile based. To emulate this, the tutorial uses a Coroutine which can move the player a full tile at a time while locking the player out from further inputs until the player character has completed its full tile of motion. It also uses a simple setup where it reads the player’s horizontal and vertical input, but checks which is greater and reduces the other to zero to ensure the player is moving only on the two intended directions.

Since the player is a 2D sprite, they used an Enum setup to tie certain sprites to certain movement directions. This way it would look like the character is facing the direction they are moving. This setup had the 4 directions (North, South, East, West) for the Enum Direction. The player’s input would set the Direction variable, currentDir, to a corresponding direction. This would then be referenced in a switch case to determine which sprite to display for the character’s SpriteRenderer at the time.

Pokemon Unity Tutorial – Player Movement [Pt.3]

August 13, 2019

Unity Pokemon Tutorial

UI and Pokemon Class

Youtube – Lets Make… Pokemon in Unity! – Episode 3 Basic Pokemon and UI

By: BrainStorm Games

This tutorial covered the very basics of starting to get the UI setup in the game, as well as starting the overall base Pokemon class. The UI portion was just grabbing an image and setting it as the image for a Unity UI Panel. To help present the image in a certain way, they did go into the sprite editor to apply an all around 4 pixel border to the image.

The base Pokemon class started with two enums, this time for rarity and type. This class, BasePokemon, also references an outside enum that was created called BiomeList, which will set out the different types of environments a Pokemon can be found in. Other than these enums, the rest was just preparing the class by setting up a lot of the variables, like the Name, image, and all the stats (like hit points, attack, and defense).