M.U.S.H.A.
M.U.S.H.A.

Reputation: 19

How to have a GetTouch() input act the same as a OnMouseDown() input

My game is designed to be played on mobile devices. Since a computer doesn't have touch input, I initially programmed it to use a OnMouse() function to select the game's block objects. In a block's script, a set of if statements are executed when clicked on. However, while still functional, the OnMouse() function didn't allow for blocks to be selected by simply sliding your finger, and was required to be individually tapped every time.

For this, I had switched to a Input.GetTouch/Touchphase.Moved method, but that caused a major problem as a random number of blocks would be sporadically selected on the grid rather than the one I have tapped.

here's the original OnMouseDown() function:

void OnMouseDown()
     {
         if (canBeSelected)
         {
             if (!selected && SelectedBlocks.Count <= 6)
             {
                 if (firstSelect && gameObject.tag != "Operation" && SelectedBlocks.Count < 1)
                 {AddBlock();}


             else if (SelectedBlocks.Count >= 1) 
             {
                 if(SelectedBlocks[SelectedBlocks.Count - 1].tag != gameObject.tag)
                 {
                     if ((int)gameObject.transform.position.x <= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.x + 1 && (int)gameObject.transform.position.x >= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.x - 1)
                     {
                         if ((int)gameObject.transform.position.y <= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.y + 1 && (int)gameObject.transform.position.y >= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.y - 1)
                         {AddBlock();}
                     }
                 }
             }
         }

         else if (selected)
         {
             SpawnBlocks.RemoveBlock(myID, false);
             audioData.PlayOneShot(removeAudio);
         }
     }
 }

And here's the redone broken GetTouch version:

void Update()
 {
     if ((Input.touchCount > 0) && (Input.GetTouch(0).phase == TouchPhase.Moved))
         {
             Ray raycast = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
             RaycastHit raycastHit;
             if (Physics.Raycast(raycast, out raycastHit))
             {
                 if (canBeSelected)
                 {
                     if (!selected && SelectedBlocks.Count <= 6)
                     {
                         if (firstSelect && raycastHit.collider.tag != "Operation" && SelectedBlocks.Count < 1)
                         {AddBlock();}
 
                         else if (SelectedBlocks.Count >= 1) 
                         {
                             if(SelectedBlocks[SelectedBlocks.Count - 1].tag != raycastHit.collider.tag)
                             {
                                 if ((int)gameObject.transform.position.x <= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.x + 1 && (int)gameObject.transform.position.x >= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.x - 1)
                                 {
                                     if ((int)gameObject.transform.position.y <= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.y + 1 && (int)gameObject.transform.position.y >= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.y - 1)
                                     {AddBlock();}
                                 }
                             }
                         }
                     }
 
                     else if (selected)
                     {
                         SpawnBlocks.RemoveBlock(myID, false);
                         audioData.PlayOneShot(removeAudio);
                     }
                 }
             }
 }

Upvotes: 0

Views: 135

Answers (2)

M.U.S.H.A.
M.U.S.H.A.

Reputation: 19

I solved this problem by using the IPointerEnterHandler and IPointerClickHandler for selecting and deselecting blocks respectively.

Here's the final result of my code, which behaves close to what I want it to:

public void OnPointerEnter(PointerEventData pointerEventData)
    {
        if (canBeSelected)
        {
            if (SelectedBlocks.Count <= 6 && !selected)
            {
                if (firstSelect && gameObject.tag != "Operation" && SelectedBlocks.Count < 1)
                {AddBlock();}

            else if (SelectedBlocks.Count >= 1) 
            {
                if(SelectedBlocks[SelectedBlocks.Count - 1].tag != gameObject.tag)
                {
                    if ((int)gameObject.transform.position.x <= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.x + 1 && (int)gameObject.transform.position.x >= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.x - 1)
                    {
                        if ((int)gameObject.transform.position.y <= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.y + 1 && (int)gameObject.transform.position.y >= (int)SelectedBlocks[SelectedBlocks.Count - 1].transform.position.y - 1)
                        {AddBlock();}
                    }
                }
            }
        }
    }
}

public void OnPointerClick(PointerEventData pointerEventData)
{
    if (selected)
    {
        SpawnBlocks.RemoveBlock(myID, false);
        audioData.PlayOneShot(removeAudio);
    }
}

Upvotes: 1

derHugo
derHugo

Reputation: 90724

Your issue is that you have attached that script to every block.

So the Update is executed for each and every one of them.

BUT you don't check what you hit! They Raycast uses the same parameters for all blocks so it will be true for all of them.

You should compare if what you got actually is the current block like e.g.

if(raycastHit.gameObject == gameObject) 

Then in general performance and logic wise it would make more sense to put this code only on one central controller object, again allow it to hit any block and control the rest within that controller so there is again only one Raycast and only one hit.

Upvotes: 0

Related Questions