Clicking

Ok so I’ve been thinking about this one problem for a bit, but haven’t fully solved it yet.

Essentially i have a script that accesses a range of gameobjects that are selected. They are selected by colliding a ray into their collider. Additionally i grab values off a stored component on each game object. It primarily runs off the Update function.

Now that all works. The problem is the clicking itself. What I’m hoping to accomplish is making the first mouse click activate the selection function, have the next one close the function and activate the testing and scoring functions. The third click should start the process all over again.

So i thought initially i could accomplish this by toggling a bool value on click.

if (Input.GetMouseButton(0)) {
     Debug.Log("Click Detected");
     click = !click;
}

Problem with this approach is while the click is always detected, the bool value is not always switched.

Alternatively i tried using the OnMouseDown function within the main script, which didnt work. I also tried it as a component on each game object. The click detection was better and the boolean toggle was 100% with that approach. Problem being i really can’t figure out how to use it with the main code and make it work.

Main Code - Still working that section

//This is the main script

using UnityEngine;
using System.Collections;
using System.Threading;
using System.Collections.Generic;

public class GamePlay : MonoBehaviour {

    #region Variables
    public Vector3 targetPos;  // used in Raycasting
    public string words; //generates a word by selecting each letter
    public string colors; //holds all the colors as a CSV
    public string shapes; //holds all the shapes as a CSV
    public int score; //adds all scores up
    public bool getSelect;  //Holds value of active piece select
    public bool mouseClicked;
    public bool selected = false;  //used for initial selection only
    public bool click = false;  //used to track whether the mouse was clicked
    public bool cCheck;
    public bool sCheck;



    #endregion

    #region Equal Finder
    bool EqualFinder(string s) {
        //Strip out last comma
        string s1 = s.Remove(s.Length-1);
        //Split String
        string[] allStrings = s1.Split(',');
        //Return true or false
        bool allEqual = true;
        for (int i = 1; i < allStrings.Length; i++) {
            if (allStrings[i] != allStrings[0])
                allEqual = false;
        }
        return allEqual;
    }

    #endregion

    #region Raycasting - Detects collisions with 2D colliders, SELECT piece, and pass info to arrays
    void ScreenMouseRay() {

        Vector3 mousePosition = Input.mousePosition;
        mousePosition.z = 10f;
    
        Vector2 v = Camera.main.ScreenToWorldPoint(mousePosition);
    
        Collider2D[] col = Physics2D.OverlapPointAll(v);

        if(col.Length > 0){
            foreach(Collider2D c in col) {
                Debug.Log("Collided with: " + c.collider2D.gameObject.name);
                targetPos = c.collider2D.gameObject.transform.position;
                //Load values from Piecscore.cs
                PieceScore select = c.GetComponent<PieceScore>();
                //Get value of current selected piece
                getSelect = select.isSelected;
                mouseClicked = select.MouseClicked;
                //Test to see if piece is selected, if not add to strings and change selection to true
                if (getSelect == false) {
                    //Load each letter into letters
                    words += select.letter;
                    //Load colors as a CSV
                    colors += select.color + ",";
                    //Load shapes as a CSV
                    shapes += select.shape + ",";
                    //Load Score
                    score += select.score;
                    //Change isSelected to True
                    select.isSelected = true;
                    select.MouseClicked = true;

                }
            }
        }
    }

    #endregion

    #region Tests - Takes Values from ScreenMouseRay(); and tests them
    void ScoreTester() {
        //Checks Color - returns value T or F
        bool colorTest = EqualFinder(colors);
        if (colorTest) {
            cCheck = true;
        }
        else {
            cCheck = false;
        }
        //Checks Shapes - returns value T or F
        bool shapeTest = EqualFinder(shapes);
        if (shapeTest) {
            sCheck = true;
        }
        else {
            sCheck = false;
        }

    }

    #endregion

    void RemovePieces(){
        if (getSelect == true) {
            //Destroy(rObjects.gameObject);
        }
    }

    void Score() {
        if (sCheck & cCheck == true){
            Debug.Log("Both True");
            //RemovePieces();
        }
        else if (sCheck == true){
            Debug.Log("Shapes are True");
        }
        else if (cCheck == true) {
            Debug.Log("Colors are True");
        }
        else {
            Debug.Log ("None are true");
        }
    }

    #region PC Controls
    void RayCastingMouse() {

        if (mouseClicked == false) {
            Debug.Log ("Clicked");
            click = !click;
        }
        if (mouseClicked == true) {
            Debug.Log("Pressed left click.");
            //ScreenMouseRay();
            //ScoreTester();
            //Score();
        }
        else {
    
        }

    
    }
    #endregion


    // Use this for initialization
    void Start () {

    }
    // Update is called once per frame
    void Update () {
        //to do to value if it is false
        //if(selected == false) {
        //    RayCastingMouse();
        //    }
        //else {
    
        //}
    }
}

Referencing Code on each Game Object:

using UnityEngine;
using System.Collections;

public class PieceScore : MonoBehaviour {
    public string shape = "circle";
    public string letter = "a";
    public string color = "blue";
    public int score = 1;
    public int DropRate = 1;

    public bool isSelected = false;
    private bool mouseClicked = false;

    public bool MouseClicked {
        get
        {
            return mouseClicked;
        }
        set
        {
            mouseClicked = value;
        }
    }

    void OnMouseDown() {
        mouseClicked = !mouseClicked;
    }



}

The reason it appears that the click vale doesn’t appear to be working is due to the number of times you are calling it. To verify this, look at the number to the right of “Click Detected”) in your console window, or unclick ‘Collapse’ to see them all in a list. There should be a bunch of “Click Detected” logs.

Input.GetMouseButton returns true if the mouse button is currently down. In this case, every frame that you’re holding the mouse down,since I imagine you’re calling it in Update(), it’s going to run your toggle.

Input.GetMouseButtonDown returns true only on the frame that the mouse button was clicked, which is what you want.

And as another thought, I didn’t look at your code in too much detail, but this:

private mouseButtonDown = false;

public MouseButtonDown {
    get {
         return mouseButtonDown;
    }
    set {
         mouseButtonDown = value;
    }
}

is redundant. You should either remove the setter or make it private, otherwise this property is no different that a regular field.

Wow that was actually really simple! The devil is always in the details.

Thank you so much. Actually because it was so simple, I was able to completely delete the additional redundant code.