- Home /
Having to select an object multiple times to continue
Hello everyone. I seem to be having some raycasting issues. With the code I have written I want the user to click on a certain number of objects. After that I want a question to show up that asks them to click on another object. If I have them right click the object the second time through, after the question is posed, it works. But I would rather have them left click. The problem is that if I have it set to have them left click then after they click on the objects the first time, depending on what they click last, the correct or incorrect response shows up without them clicking on the object a second time. My code follows:
void testQuestionThree() { Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition); string finalClick = hit.collider.gameObject.name;
if(popUpDisplayed == false)
{
if ( Input.GetMouseButtonDown(0) )
{
if (Physics.Raycast (ray, out hit, 100.0f))
{
if(hit.collider.gameObject.name == "learningCylinder2")
{
object1Clicked = true;
}
if(hit.collider.gameObject.name == "learningCube2")
{
object2Clicked = true;
}
// below we add a test, to see if we clicked either object,
// but importantly this only matters if we've clicked both already.
// this determines what we clicked after the request
if(object1Clicked && object2Clicked)
{
allObjectsClicked = true;
object1Clicked = false; //resetting variables to false
object2Clicked = false;
}
if((object1Clicked || object2Clicked) && allObjectsClicked)
{
isClicked = true;
finalClick = hit.collider.gameObject.name;
allObjectsClicked = false; //resetting variables to false.
object1Clicked = false;
object2Clicked = false;
}
}//end physics
}//end input.get
if(allObjectsClicked)
{
if(isClicked == false)
{
GUI.Box (new Rect (350,10,350,120), "Please click the learning cube.");
}//end isClicked false
}
if(isClicked)
{
if(finalClick == "learningCube2")
{
GUI.Box(new Rect (350, 10, 350, 120), "That was correct. You may now continue.");
}
else
{
GUI.Box(new Rect (350, 10, 350, 120), "Sorry, the correct answer was the cube. Click to advance.");
}
navButtonEnabled = true;
}//end if isClicked
}//end popUpDisplayed
}
This is being called in onGUI(). As stated. If I have them right click after the box comes up saying "Please click on learning cube" then it works. But if I them left click then it runs through the whole thing, top to bottom, without the user having to click a second time.
Answer by Alec-Slayden · Apr 29, 2011 at 01:54 PM
EDIT in response to evolved question / problem:
Looks like my previous answer didn't help prevent multiple OnGUI() calls from running the whole section of script, sorry about that. Here's a solution that will definitely work:
Your testQuestionThree function should look like this:
void testQuestionThree(){
if(popUpDisplayed == false)
{
if(allObjectsClicked)
{
if(isClicked == false)
{
GUI.Box (new Rect (350,10,350,120), "Please click the learning cube.");
}//end isClicked false
}
if(isClicked)
{
if(finalClick == "learningCube2")
{
GUI.Box(new Rect (350, 10, 350, 120), "That was correct. You may now continue.");
}
else
{
GUI.Box(new Rect (350, 10, 350, 120), "Sorry, the correct answer was the cube. Click to advance.");
}
navButtonEnabled = true;
}//end if isClicked
}//end popUpDisplayed
}
The upper part has been moved to update in this form:
void Update () {
if ( Input.GetMouseButtonDown(0) && !popUpDisplayed)
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit, 100.0f))
{
if(hit.collider.gameObject.name == "learningCylinder2")
{
object1Clicked = true;
}
if(hit.collider.gameObject.name == "learningCube2")
{
object2Clicked = true;
}
// below we add a test, to see if we clicked either object,
// but importantly this only matters if we've clicked both already.
// this determines what we clicked after the request
if(object1Clicked && object2Clicked)
{
allObjectsClicked = true;
object1Clicked = false; //resetting variables to false
object2Clicked = false;
}
if((object1Clicked || object2Clicked) && allObjectsClicked)
{
isClicked = true;
finalClick = hit.collider.gameObject.name;
allObjectsClicked = false; //resetting variables to false.
object1Clicked = false;
object2Clicked = false;
}
}//end physics
}//end input.get
}
This ensures that the check for mousedown is only done once per frame, and fixes the issues that were presented by multiple OnGUI Calls. The script itself isn't changed so much as cut into two parts and moved. It's important to keep the OR (||) operand.
finalClick as a variable will need to be declared ahead of time, setting = "" is fine.
Now, I assume you're going to want more test questions in your interactive. Leaving this as is will only work for test question three. If all of your questions involve two objects, then you can use a variable to store the name to test against the clicked object, and not much needs to be changed. If each question has its own dynamic, you might want to turn the stuff we moved to update into a second function, and just have two functions per question; one for the GUI display, and one for the mechanics.
Using Get$$anonymous$$ouseButton() and Get$$anonymous$$ouseButtonDown() has the same effect. Also, I don't know if I put the right things in Update() or not, but the effect has also been the same.
No it is not. You want to track how often the mouse got clicked. If you use Get$$anonymous$$ouseButton you would get the number of frames it was held down for, if you use Get$$anonymous$$ouseButtonDown you get the number of times it was clicked.
Sorry, I didn't mean it had the same effect by definition. I meant it had the same result in my code. No matter which one of those I used it worked out the same.
It is still running through the code too quickly. It still doesn't show the GUI box that says "Please click learning cube." If I click on the cube then the cylinder to begin, it says "Sorry, the right answer was the cube." If I click on the cylinder then the cube it says "Correct..." But it still isn't interrupted long enough to display the instructions for the user. I am using Get$$anonymous$$ouseButtonDown and I moved the code you wrote into update, ins$$anonymous$$d of in onGUI.