11

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; }

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
MIke
  • 283
  • 3
  • 4
  • 13
  • 1
    Vector3 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); – Barnstokkr Jan 26 '15 at 08:35
  • I will make that change now, Hopefully that was what my issue was. – MIke Jan 26 '15 at 08:37
  • @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 Jan 26 '15 at 08:58
  • Sorry but if im asking how to make a "Sprite" clickable.. not how to make the whole screen clickable and activate a sprite.. – MIke Jan 26 '15 at 09:14

5 Answers5

25

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.

maZZZu
  • 3,585
  • 2
  • 17
  • 21
  • Thanks so much and sorry for late reply... yes exactly why i do not want to use code that is position based as I keep changing my mind and moving things around.. I will give this a go.. I was unaware of raycast 2d... i Googled it and it came up that ray cast does not work on 2d but thanks for letting me know about that :P I will give this a go in a few hrs and fingers crossed it's what i'm after :P thanks again. – MIke Jan 27 '15 at 06:21
  • 1
    No problem. I just realized that your suggestion `OnMouseDown` works as well. I edited my answer to that. It is much better because it has to be done only when the user has clicked. – maZZZu Jan 27 '15 at 06:28
  • Thanks so much! We have a winner! I knew there was an easy way to do this and you found it!!! If i could buy you a beer i would! – MIke Jan 27 '15 at 06:38
  • Wow! This is a great answer! Didn't know it was this easy! – Barnstokkr Jan 27 '15 at 09:30
3

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.

Benjamin James Drury
  • 2,353
  • 1
  • 14
  • 27
  • Looks like a much easier option, but i guess i have to import raycasting? at the moment it says Assets/mute.cs(33,37): error CS0117: `UnityEngine.Physics' does not contain a definition for `RayCast' – MIke Jan 26 '15 at 09:17
  • Sorry @MIke, I had meant Raycast; no capital letter half way through. I've changed the answer now. – Benjamin James Drury Jan 26 '15 at 09:21
  • oh no problem, sorry i should have noticed that. – MIke Jan 26 '15 at 09:25
  • bugger it doesn't work.. unsure why.. doesn't pose any errors just doesn't activate the sprite at all now. – MIke Jan 26 '15 at 09:29
  • The code has been put in the object you are trying to click, and it does have a collider of some description on it too? – Benjamin James Drury Jan 26 '15 at 09:34
  • yes it has a 2d collieder, and yes i have a gameobject called mute, then inside that i have the sprite.. on the game object i have the script mute.cs and inside that script i placed this code. – MIke Jan 26 '15 at 09:37
  • Is the collider in the right place is all I can think of to ask then? If the collider is not over the sprite, it won't work. If it is in the right place, then I'm afraid my lack of knowledge of using Unity for 2D things means I can't help any further, in which case I can only offer my apologies. – Benjamin James Drury Jan 26 '15 at 10:04
  • Yes it is, Thanks anyways.. It seems i cannot find a simple way to do this.. I shall try a few more of the complicated options below.Thanks again. – MIke Jan 26 '15 at 10:13
1

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)

Imtiaj Ahmed
  • 350
  • 1
  • 2
  • 12
  • Thanks for the advice, If i make that change will that work now? I'm not up tp speed with raycasting yet – MIke Jan 26 '15 at 08:36
  • I have changed it but still actiavtes no matter where i click. any simple ideas? – MIke Jan 26 '15 at 09:00
1

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

MX D
  • 2,453
  • 4
  • 35
  • 47
  • Thanks for the help offered anyways :P I ended up getting onmousedown to work i just needed to make it a void and not input.get but ahh finally... Thanks so much. – MIke Jan 27 '15 at 08:35
1

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.

Gounemond
  • 353
  • 1
  • 9
  • Thanks for helping out with a repsonse, however i ended up getting mousedown to work.. I did not want to go with a position one as i may need to move the sprites later and i didn't want to have to recode it all. – MIke Jan 27 '15 at 08:37