Multiple choice game not working!?!

firstly, heres my code:

var target : StartSprite;
var targetScript : ChangeSprite;
var AcceptInput : boolean = true;
private static var score : int = 0;
var guiScore : GUIText;

function Update () {


if(!AcceptInput)
{
return;
}
AcceptInput = false;
Debug.Log("Clicked");
if(target.spriteRenderer.sprite == target.diamond) {

score +=1;

guiScore.text = "Score: " + score;

StartCoroutine("Click");
targetScript.enabled = true;
}
else {
StartCoroutine("Click");
targetScript.enabled = true;
Debug.Log("Wrong Answer");
}
}
if(Input.GetMouseButtonUp(0)) {
targetScript.enabled = false;
changeSprite ();
}
}


function Click () {
yield WaitForSeconds (0.5);
}


function changeSprite (): IEnumerator {

if(Input.GetMouseButtonDown(0)) {
if(!AcceptInput)
{
return;
}
AcceptInput = false;

if(targetScript.spriteRenderer.sprite == targetScript.diamond) {

score +=1;

guiScore.text = "Score: " + score;

yield WaitForSeconds (0.5);

targetScript.enabled = true;
}
else {
yield WaitForSeconds (0.5);
targetScript.enabled = true;
Debug.Log("Wrong Answer");
}
if(Input.GetMouseButtonUp(0)) {
AcceptInput = true;
targetScript.enabled = false;
changeSprite ();
}
}
}

So basically if you press the button it would check what the sprite of another object is and if it is the correct answer, then add a score then enable another script which changes the sprite of the object. For some weird reason this is just not out properly. If I press the button, it would add a score before the sprite even displayed on the screen. It’s supposed to be something like a multiple choice question, but if I press the button, it would add the score because the sprite that is the correct answer is displayed after the sprite that was currently displayed, why is it behaving like this? Does anyone have any ideas? I REALLY need help. I’ve been trying to figure this out for days! (Just to let you know I’m not being lazy so I asked the question on unity answers) Any help would be much appreciated. Thanks :smiley:

Firstly, the code you wrote up there wouldn’t compile. Your braces are all kinds of off (you’ve got an entire if statement outside of all functions, and an extra curly brace after the end of that, to boot).

You’ve got your check for Input.GetMouseButtonUp(0) within the braces that would only have been reached if Input.GetMouseButtonDown(0) would have to be true, meaning that the check to Input.GetMouseButtonUp(0) will always return false, when you check it there.

Secondly, I would strongly suggest against using coroutines like that. Update tends to run a bit irregularly, and it can be very difficult to debug a program where you’ve got two things running at different rates, like that. I would suggest checking against Time.deltaTime to time your stuff.

Thirdly, if the target script is the script that tracks the next answer, then why are you checking against its “diamond” value? You should be tracking the current answer, as the script will not enable itself unless you set its “enabled” property to “true,” which you only do if the “diamond” variable is found to be the same as the sprite that was clicked.

Really, I would suggest using a completely different code structure, as it would be much easier to debug. Sprites are not intended to be used as booleans in the way you’re using them, and it would really be much easier to read and predict if you used another type to store those values.

Not to mention, I have no clue what the “diamond” value is, other than some kind of sprite. Check where that value is set, and see if it’s being set to the proper value (the one that is connected to the answer you wanted).

EDIT

To better explain coroutines, put the following code in a js script:

#pragma strict

function Update () {
    StartCoroutine(YieldTestEnumerator());
    Debug.Log("I DIDN'T. Time = " + Time.time);
    //Debug.Break();
}

function YieldTestEnumerator()
{
    Debug.Log("I STARTED. Time = " + Time.time);
    yield WaitForSeconds(0.5);
    Debug.Log("I WAITED.  Time = " + Time.time);
    Debug.Break();
}

The thing to note here is that “I STARTED” was printed before “I DIDN’T.” This would be expected in any normal execution order language. However, notice that “I DIDN’T” is printed several times before “I WAITED” is ever printed, and you can even confirm by the time stamp that it is, indeed, being called FIRST.

Ok, but what does this mean? Well, it means that putting a coroutine and telling it to wait a certain amount of time to “delay” the function that called it doesn’t work. What “yield” essentially does is it passes back control over the system to the “update” function, and is called again, if it is supposed to.

For example, WaitForSeconds causes the function to essentially “pick up” where it “left off” before the yield, after the given number of seconds has passed (in pretty close to real-time).

What this does not do is stop the function that called it from executing for that amount of time, so your update function will continue its own execution, despite the fact that the end of the Click function (which is really “nothing,” since there is no code after the yield statement) is not completed until 0.5 seconds have passed, which is usually going to be at least a few frames (about 30, assuming a 60fps run speed) later, and thus Update (and the function that comes after the coroutine call) will actually be called about 30 times before the ending of the coroutine.

Now, keeping all this in mind, what I would suggest to you is that in your Update function, you should save the time (Time.time) when the user clicks into a float field, somewhere, and check the current time against that time to see if 0.5 seconds have passed, within the update function, and if it is: Execute the code. This is only the way I would probably do it (if it weren’t a performance-critical location in the code, at least).

However, you can certainly still use enumerators and coroutines and whatnot, though I think what you want is more along the lines of Invoke, which is essentially a delayed invocation of a given function. You would essentially invoke the method you want to be called in 0.5 seconds, and have that function contain the instructions for what to do, based on what the user clicked.

First and foremost, I would work out the kinks in your conditionals, because again, as you have it, there are a few parts of this code that will essentially never get called, and I strongly suspect that you would want them to be called, given certain criteria.