hey, i think I found a bug? if i put an x in all 4 corners and o in all 4 edges (or vice versa, the final x makes the game a draw? Iām gonna do the last bit of the tutorial tomorrow, (the pick a player part) but just wondering about that.
Looking at my final project, it works as expected:
Now, Iām having a hard time (without redoing the project) checking to see if thereās an issue at your stepā¦ but first:
Iād check the code in EndTurn to make sure that all the test are correct. Thoā that should trigger 4 separate lines of code and 4 possible wins (1 row, 1 column, 2 diagonals). Youād have to have 4 lines wrong to make that not a win.
The other thing to check is to make sure that the center grid space is correctly assigned and in the correct orderā¦
Can you win with a diagonal, row or column that goes thru the center before the last turn?
Can you have a win with any last place turn? EG: From this setup, starting with X, placing the last X should create another 9th turn win.
I would have added them, but your code has lost its formatting.
It looks like you have the move count test first, not last. As code is executed top top bottom in a function, it reaches the move count test before the win test, so if itās turn 9, you will always get a draw.
And well, Iām still confused as to WHY Iām doing a lot of these things, I find it a little hard to understand WHY I use things like void, but I know void update is everytime the game refreshes or something similar, in a previous project I used fixed update which was like a regular pulse. But yeahā¦ what is void?
The āvoidā is saying āthis function returns nothing at all.ā For a āvoidā you can use āreturn;ā or not have a return at all. For other types of returns, you set up the proper return value.
The Update() function is called every single frame, every time Unity draws the screen. There is some official documentation here. The FixedUpdate() is probably what you mention using before and is explained here.
void is a return type for a function. In C#, all functions must have a return type. In many cases, functions simply āDo Somethingā but are not necessarily processing data and returning a result. These are void.
void SetBoardInteractable (bool toggle)
{
for (int i = 0; i < buttonList.Length; i++)
{
buttonList .GetComponentInParent<Button>().interactable = toggle;
}
}
In the above example, the function toggles all of the buttons in buttonList, but returns no value, so the return type is void.
int AddTwo (int a, int b)
{
return a + b;
}
In the above example, the function processes data and returns a value, so the return type must be int.
TYPE is the type of thing this is, in that āIs this a GameObject? Is this a Camera? Is this a float?ā The type is the name of the class. If you write your own class, eg: public class GameController, the type is GameController. Donāt forget that ultimately, even thoā Components are ābuilt-inā, these Components - like Cameras and Rigidbodies - are defined somewhere and they are usually classes, just like the classes you write in your scripts. They are identified by type.
Now, C# can get a little pedantic with type.
int myNewInt = AddTwo (4, 5);
int AddTwo (int a, int b)
{
int calculatedValue = a + b;
return calculatedValue;
}
We define int 3 times! 5 is you count the parameters! Shouldnāt the compiler know this should be a fussing int??
Orā¦
GameObject clone = Instantiate (prefab) as GameObject;
Well, yes the compiler can figure it out but in many cases C# is pedantic by design so you are required to be absolutely clear about what you are writing. Other languages like JavaScript (or even UnityScript) are more forgiving and can try to figure out what type things are by implication.
There are some situations now, in C#, where you can let the compiler figure out type.
var clone = Instantiate (prefab) as GameObject;
The var her means āThis is a variable of the type being returned by the right hand side of the statementā - in this case GameObject.
In general, itās safest to make sure you write these out by hand so there is no confusion.
[edit]
As a side note, functions that do not return a value still do return when the function is done. Control of the game is returned to wherever it came from. If you think of the flow of logic in a game - the logic is flowing in a big loop reading all of the code on all of the relevant and active scripts and then Unity renders a frame and then the loop goes all over again.
public Text displayText;
void Update ()
{
// Some code goes here - checking for input and doing things.
SetDisplay (Time.time);
// More code goes here - checking for input and doing things.
}
void SetDisplay (float time)
{
displayText.text = time.ToString();
}
If you have a function like Update() and in Update, you call a function like SetDisplay. They are both functions that return void. Unityās main game loop (which we donāt have control of) calls Update. The control of the game is now in Update doing things. During the execution of Update, the function SetDisplay is called. The control of the game - or the code being executed - is now in SetDisplay. Unity has executed āsome codeā in Update, but has not yet called āmore codeā. The control moved to SetDisplay first. Unity executes all the code in SetDisplay and then SetDisplay returns void - but it does return. It just returns empty, nothing, void - and control of the game returns back to where it came from - in this case back to Update right after the line calling SetDisplay. Unity now executes āmore codeā in Update. When Update is done, the function Update then returns void and control of the game is handed back to the main Unity game loop, which will go on and look for any more Update functions on any other Components and then continue on with all the other things it does.
So - the flow of logic is handed off to different functions and then handed back to where it left off all in a linear fashion, like a mouse threading through a maze.
Unity will call all of these events on all relevant and enabled scripts on active GameObjects and then move on the next set of events, in a big loop, until the gameās application is closed.
As a lst side note, in advanced coding, you can have what is called āmultiple threadsā all executing code simultaneously. This goes beyond the definition above āall code is executed in one long linear sequenceā but you have to choose to do that and itās an advanced topic. Know that it exists, but ignore it for now.
In tutorial#8 (Ending in a draw),
if(moveCount >= 9)
should be
else if(moveCount >= 9)
Because if a player wins in the 9th move, without that else it will display āItās a Draw!ā.
At what stage of the tutorial are you? āElse Ifā is the final state. If you follow the tutorial and do the save and test steps, this should work as expected. If youāre testing in the middle of a step, then you might have problems. Be aware that code executes from top to bottom and the order of the code is important. If you have that line above the win checks, youāll have problems.
If you feel there is a different error, then please point out the exact step you are in when it fails, as our tests of this tutorial donāt find this issue.
Hey there Iām at the end of part 5 but I keep getting an error telling me on the gamecontroller script.
The type arguments for method āComponent.GetComponentInParent()ā cannot be inferred from the usage. Try specifying the type arguments explicitly.
I also get an error on the grid space script that says āGameControllerā does not contain a definition for āGetplayerSideā and no extension method āGetplayerSideā accepting a first argument of type āGameControllerā could be found (are you missing a using directive or an assembly reference?)
Iāve attached pictures of both scripts. Iām thinking Iāve just missed something small.