8
votes

I have googled plenty and only come up with really complicated methods of doing it. I also found the function OnMouseDown() but I haven't been able to make it work.

At the moment the sprite activates when you tap anywhere on screen.

EDIT - Yes it has a 2d Box collider

My code below:

using UnityEngine;
using System.Collections;

public class mute : MonoBehaviour 
{
    public bool isMuted = false;
    public Sprite mute1, mute2;

    private SpriteRenderer spriteRenderer; 

    private void Start () 
    {
        spriteRenderer = GetComponent<SpriteRenderer>();

        if (spriteRenderer.sprite == null) 
            spriteRenderer.sprite = mute1;
    }
    private void Update () 
    {
        if (Input.GetKeyDown (KeyCode.Mouse0)) 
        {
            if (!isMuted)
            {
                AudioListener.pause = true;
                AudioListener.volume = 0;

                isMuted = true;
                ChangeSprite();

            }
            else
            {
                AudioListener.pause = false;
                AudioListener.volume = 1;

                isMuted = false;
                ChangeSprite();
            }
        }
    }
    private void ChangeSprite() => spriteRenderer.sprite = 

spriteRenderer.sprite == mute1 ? mute2 : mute1; }

5
Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); - Barnstokkr
I will make that change now, Hopefully that was what my issue was. - MIke
@Barnstokkr where would i use that? I changed Input.GetKeyDown (KeyCode.Mouse0) to Input.GetMouseButtonDown(0) and it still activates no matter where i click - MIke
Sorry but if im asking how to make a "Sprite" clickable.. not how to make the whole screen clickable and activate a sprite.. - MIke

5 Answers

17
votes

Using OnMouseDown

The easiest method is to add this function into any script component attached to the gameObject containing the sprite:

void OnMouseDown(){
    Debug.Log("Sprite Clicked");
}

The gameObject also need to have a collider. Both 2D and 3D colliders work.

Comparison to other methods

Raycasting only works on one collider type at the time Physics.Raycast works only against 3D colliders and Physics2D.Raycastworks only against 2D colliders. OnMouseDown works on both, but it is possible that its performance is as bad as the performance of executing both of the raycasts.

Position based methods stated in other answers are good for performance. Couple of if statements is much faster to compute than ray casting, but ray casting is still fast enough for basic scenes. The disadvantage of the position checks is that if you change anything (scale or position) you are likely to break your if clauses. Also the ifs are quite complicated if you want sprites to be on top of each other.

2
votes

I'm not 100% sure about how unity handles 2D things compared to 3D things, but I'm fairly sure the principal of ray-casting is the same, so try something like the following and stick it under the update in your script you want clicked.

if (Input.GetMouseButtonDown(0))
{
    RaycastHit hit;
    if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit))
    {
        if (hit.collider == collider)
        {
            //Do your thing.
        }
    }
}

So what this is doing is checking to see if the mouse is clicked, checking to see if where the mouse clicked there actually was anything, and then checking that what was clicked is the thing with the script on it.

1
votes

First I think you should have a collider with your gameobject and for clicking you should use sort of raycasting. And you can use Input.GetMouseButtonDown (0) instead of Input.GetKeyDown (KeyCode.Mouse0)

1
votes

I changed Input.GetKeyDown (KeyCode.Mouse0) to Input.GetMouseButtonDown(0) and it still activates no matter where i click

It is not that weird that it activates no mater where you click, because you are not limiting it to a specific location. Right now you are just checking

input.GetMouseButtonDown(0)

You will want to check if the click is within a certain area, or hits a certain object. So you can limit it by the current mouse position you have, with something like this.

if(mousePosition.x < 100 && mousePosition.x > 10)
    if(mousePosition.y < 500 && mousePosition.y > 10

Or you could use a raycast to determine which object you are currently hitting. Which I would actively advice in pretty much every scenario. For more about raycasting please check out the unity tutorials

1
votes

As I saw in the comments you can get the real touch position

if (Input.GetTouch(0) /*|| buttondown or what you want*/)
{
    fingerPos =  Input.GetTouch(0).position; // or buttondown
    Vector3 realPos = Camera.main.ScreenToWorldPoint(fingerPos);

    if (realPos.transform.position.x >= SpriteRenderer.transform.position.x -10
        && realPos.transform.position.x <= SpriteRenderer.transform.position.x +10)
        && realPos.transform.position.y >= SpriteRenderer.transform.position.y -10
        && realPos.transform.position.y <= SpriteRenderer.transform.position.y +10)
    {
        ChangeSprite();
    }
}

I may have missed the condition of check xD The idea is to check if your tap is within a reasonable range where your sprite should be. I put plain number there, you can of course use SpriteRenderer size x and size y.