Button Problem (545981)

Firstly, I asked this on unity answers and got too many answers and comments that were not so helpful, so I decided to post this on a forum where we can discuss.

This is my script:

var targetScript : ChangeSprite;
var AcceptInput : boolean = true;
private static var score : int = 0;
var guiScore : GUIText;
function Start ()
{
guiScore.text = "Score: 0";
}
function OnMouseDown () {
if(!AcceptInput)
{
return;
}
AcceptInput = false;
targetScript = GameObject.Find("Shape").GetComponent(ChangeSprite);
GameObject.Find("Shape").GetComponent(ChangeSprite).enabled = true;
Debug.Log("Clicked");

if(targetScript.spriteRenderer.sprite == targetScript.diamond) {
AcceptInput = true;
score += 1;
guiScore.text = "Score: " + score;
}
else{
Debug.Log("Wrong Answer!");
}
}
function OnMouseUp () {
AcceptInput = true;
GameObject.Find("Shape").GetComponent(ChangeSprite).enabled = false;
}

What the script does is when the button is pressed, it will activate the other script which would change the sprite of another object. And if the sprite is diamond, it would add a score and if not, Debug.Log(“Wrong Answer!”). The problem is, if I press the button, the score would add even before the sprite was even displayed on the screen. Is there any way to make the button only work when the sprite is displayed? I tried the wait for seconds method but it wasn’t really helpful. what it did was it added the score a second later but it was still the same. Does anyone have any ideas? Any help would be much appreciated. Thanks in advance!

First of all, use tabs. Your code is unreadable right now. Second, using Find is expensive and should be avoided if you use it a lot. Third, having a boolean AcceptInput is unneeded. You can only have one downpress at a time.

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


function Start ()
{
guiScore.text = "Score: 0";
}


function OnMouseDown () {
if(!AcceptInput)
{
return;
}
AcceptInput = false;


targetScript = GameObject.Find("Shape").GetComponent(ChangeSprite);


GameObject.Find("Shape").GetComponent(ChangeSprite).enabled = true;
Debug.Log("Clicked");

if(targetScript.spriteRenderer.sprite == targetScript.diamond) {
AcceptInput = true;
score += 1;
guiScore.text = "Score: " + score;
}


else{
Debug.Log("Wrong Answer!");
}

}

function OnMouseUp () {
AcceptInput = true;
GameObject.Find("Shape").GetComponent(ChangeSprite).enabled = false;
}

I used the accept input because if I don’t, it would flash through the sprites unless I release. And I don’t get why GameObject.Find is expensive, can you elaborate on it?

Please use tabs in your code. Having it all in one straight line (see how the left-hand side is straight instead of staggered like it is in monodevelop or visual studios) makes this very time-consuming to read.

Secondly, when you run Find, it takes up a good bit of processing power. Not enough to cause a difference if you’re running it infrequently, but if you run it often (or a lot in a single frame), you will probably see stuttering.

You have:

targetScript = GameObject.Find("Shape").GetComponent(ChangeSprite);

GameObject.Find("Shape").GetComponent(ChangeSprite).enabled = true;

Would this not do (assuming you cannot just assign the script you want in the inspector)?

targetScript = GameObject.Find("Shape").GetComponent(ChangeSprite);
targetScript.enabled = true;

You already found and cached the sprite you want; you should be good to go.

Finally, OnMouseDown should only be called once per click (that I am aware). If it’s rapidly cycling sprites, that is… something strange.

Because it makes the disabled script true when OnMouseDown, I have to use OnMouseUp to make it false again. If I don’t use the accept input thing, it would just rapidly flash through. The main problem is I want the button only work if the sprite is displayed. Otherwise it would display the score even before the sprite is displayed on the screen. Thanks for your time

maybe I need some kind of delay to restrict the button