- Home /
Unity 5.2 is causing my game to not function properly.
So i was doing the Udemy course (complete unity dev) and tried the breakout game and tweaked and added new features but after updating to unity 5.2, my code no longer works.(The ball hits the bricks but the bricks do not break. I have looked through the code but can't figure out what is wrong) I do not get any error messages however.
using UnityEngine;
using System.Collections;
public class Brick : MonoBehaviour {
public AudioClip crack;
public Sprite[] hitSprites;
public static int breakableCount = 0;
public GameObject smoke;
private int timesHit;
private LevelManager levelManager;
private bool isBreakable;
// Use this for initialization
void Start () {
isBreakable = (this.tag == "Breakable");
// Keep track of breakable bricks
if (isBreakable) {
breakableCount++;
print (breakableCount);
}
timesHit = 0;
levelManager = GameObject.FindObjectOfType<LevelManager>();
}
// Update is called once per frame
void Update () {
}
void onCollisionEnter2D (Collision2D col) {
AudioSource.PlayClipAtPoint (crack, transform.position, 0.8f);
if (isBreakable) {
HandleHits();
}
}
void HandleHits () {
timesHit++;
int maxHits = hitSprites.Length + 1;
if (timesHit >= maxHits) {
breakableCount--;
print (breakableCount);
levelManager.BrickDestoyed();
PuffSmoke();
Destroy(gameObject);
} else {
LoadSprites();
}
}
void PuffSmoke () {
GameObject smokePuff = Instantiate (smoke, transform.position, Quaternion.identity) as GameObject;
smokePuff.GetComponent<ParticleSystem>().startColor = gameObject.GetComponent<SpriteRenderer>().color;
}
void LoadSprites () {
int spriteIndex = timesHit - 1;
if (hitSprites[spriteIndex] != null) {
this.GetComponent<SpriteRenderer>().sprite = hitSprites[spriteIndex];
} else {
Debug.LogError ("Brick sprite missing");
}
}
// TODO Remove this method once we can actually win!
void SimulateWin () {
levelManager.LoadNextLevel();
}
}
Answer by tanoshimi · Nov 28, 2015 at 08:48 AM
I am forever disappointed by the number of so-called "complete" programming courses, books, tutorials etc. that fail to teach students any knowledge or skills about debugging. Programming involves constantly making mistakes, and you need to learn what to do when they happen - to identify them, fix them, and move on. Just expecting students to perfectly copy example code word-for-word is not teaching them to program. Sigh.
Rant Over. Now - this is what that course should have taught you.
The simplest tool you have access to when your code isn't working as expected is Debug.Log. You can use it to output the value of a variable to the console, but you can also use it to print a text string reporting the current state of the program, for example. That's how we'll mostly use it to understand when a section of code is not being executed as expected.
The problem you have observed is that the blocks aren't breaking. That part of the game code is handled by the HandleHits() method, so try putting a Debug.Log line right at the start of that method as follows:
void HandleHits () { // The following line will print to the console when this method is called Debug.Log("HandleHits() method called!"); timesHit++; .... the rest of the code
Debugging code is a continuous process - you make a change, and then re-test each time. So try playing your game again. If HandleHits was being called, we'd expect to see the message "HandleHits() method called!" appear in the console while you're playing. I suspect, however, you won't see this message.
If I'm correct and you don't see the message, we've learned something - HandleHits() is not being called. So now, the next step is to backtrack through your code logic to find what should have called it. In a long project, you can use the Find references command to find all the places that call a function, but as your code is quite short and only in one class, you can simply use Ctrl+F and search for "HandleHits", or look through your code, and you'll see one place where HandleHits() is called - at line 36:
void onCollisionEnter2D (Collision2D col) { AudioSource.PlayClipAtPoint (crack, transform.position, 0.8f); if (isBreakable) { HandleHits(); } }
In this function, the HandleHits() method is only called if
isBreakable
is true. So, let's add another Debug.Log to see whether that's the case:void onCollisionEnter2D (Collision2D col) { AudioSource.PlayClipAtPoint (crack, transform.position, 0.8f); Debug.Log("isBreakable is " + isBreakable.ToString()); if (isBreakable) { HandleHits(); } }
Remember, after every change we test again. We are expecting to see a line in the console that says either "isBreakable is true", or "isBreakable is false" when we play the game. However, I suspect that, once again, you'll see nothing.
So, you continue to backtrack further - what happens immediately before HandleHits() is meant to be called? Well, on line 34, there was meant to be a "crack" audioclip played. Did that happen? Play the game again and listen carefully.
I'm betting you couldn't hear the audio either. So we now know that not only is HandleHits() not being called, but in fact none of the code in onCollisionEnter2D is being called either.
So now what?
onCollisionEnter2D
is an inbuilt function - you don't manually call it from your code - Unity is meant to call it automatically when a collision happens, right? So we can't backtrack through our code like before to find references to it. At this point, the other thing your course should have taught you is the importance of reading the manual. Look carefully at the documentation for that method and you'll see that it should be calledOnCollisionEnter2D
, notonCollisionEnter2D
... Unity isn't calling your method because (like almost all programming languages) C# is case sensitive.If I'm right, I suspect the "Upgrade to Unity 5.2" was completely irrelevant. The code you have currently written will never have worked in any version of Unity, so at some point you have changed the "O" to an "o". It's an easy mistake to make, but care and attention to detail matter, a lot.
The final thing your course should have taught you is version control - which means that when discover something is broken that used to work, you can go back to the last version in which it was working and find out what changed that might have broken it.
I may be wrong, of course, but that at least is how I suggest you approach the problem. And I would suggest you add the following to your list of things to learn after your course:
Use Debug.Log
Step back through your code
Read the manual
Be careful! Check and double-check spelling.
Learn about version control