- Home /
Clickable Object Problem - Help
Hello,
I have a cube that I have made clickable, that right now, just prints to the console if it has been clicked or not. It all works, if I click on the object is says 'Clicked' and when I click again on the object (like a toggle), it says 'Clicked OFF'.
Heres the problem, the click will activate no matter what I click on, as long as it has a collider, I would like the click to be specific to what ever I click on.
Here is my script:
var Clicked = false;
function Update() { //Make Click On if ( Input.GetMouseButtonDown(0) && Clicked == false){ var hit : RaycastHit; var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition); var select = GameObject.FindWithTag("Select").transform; if (Physics.Raycast (ray, hit, 100.0)){ select.tag = "Unselect"; hit.collider.transform.tag = "Select"; print("clicked"); Clicked = true; } } //Make Click Off else if ( Input.GetMouseButtonDown(0) && Clicked == true){ var hitOff : RaycastHit; var rayOff : Ray = Camera.main.ScreenPointToRay (Input.mousePosition); var selectOff = GameObject.FindWithTag("Unselect").transform; if (Physics.Raycast (rayOff, hitOff, 100.0)){ selectOff.tag = "Select"; hitOff.collider.transform.tag = "Unselect"; print("clicked OFF"); Clicked = false; } } }
About My Scene:
I have no player controller, just a simple camera looking downwards.
Would appreciate any help, thanks
ALSO: The script is a property of the cube that I want to click on
In Unity, scripts are not "properties" of GameObjects, they are Components.
Answer by skovacs1 · Nov 22, 2010 at 08:20 PM
Your script will cast a ray. If the ray hits, it will change the select variable and set the tag of the object hit by the raycast.
If you want it to only happen on the object the script is attached to, you should check that you actually hit the object the script is attached to before doing anything.
Since your code is convoluted and inefficient, here is a much simpler piece of code that will do as you intend without you calling raycast or find or any of the other nonsense:
MouseDownSelection.js
var clicked : boolean = false;
function OnMouseDown() {
clicked = !clicked;
if(tag == "Selected") tag = "Unselected";
else tag = "Selected";
Debug.Log("clicked" + (clicked? "" : " off"));
}
EDIT:
According to your comments, because you are trying to check a collider inside of another collider, you are trying to do something a bit more troublesome. The solution is to only raycast against a subset of colliders including the one you care to hit and excluding the one that is in your way. This can be done with layer masking or even more simply by casting against just the collider of the current object.
SpecificColliderMouseDownSelection.js
//Needed due to Unity js issue //Alternatively specify the type with (collider as Collider).Raycast... #pragma strict
var clicked : boolean = false; var hit : RaycastHit; function Update() { if(Input.GetMouseButtonDown(0) && collider.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), hit, Mathf.Infinity)) { clicked = !clicked; if(tag == "Selected") tag = "Unselected"; else tag = "Selected"; Debug.Log("clicked" + (clicked? "" : " off")); } }
If you used a Physics.Raycast with an appropriate layer mask, you would check and operate on the thing the raycast hit. If you have multiple selectable objects, that is a better way to go so that you can instead attach the script to the camera or something and only raycast once.
SingleSelection.js (only one per scene)
var selected : Transform; var mask : LayerMask = -1;
function Update() { if(Input.GetMouseButtonDown(0) && Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), hit, Mathf.Infinity, mask.value)) { if(hit.transform.tag == "Selected") { hit.transform.tag = "Unselected"; selected = null; } else if(!selected) { selected = hit.transform; selected.tag = "Selected"; } Debug.Log("clicked" + (selected? "" : " off")); } }
MultipleSelection.js (only one per scene)
var selection : Array = new Array(); var mask : LayerMask = -1;
function Update() { if(Input.GetMouseButtonDown(0) && Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), hit, Mathf.Infinity, mask.value)) { if(hit.transform.tag == "Selected") { hit.transform.tag = "Unselected"; var index : int = 0; for(;index < selection.Length; index++) { if(selection[index] == hit.transform) break; } if(index < selection.Length) selection.RemoveAt(index); Debug.Log("clicked off"); } else { hit.transform.tag = "Selected"; selection.Add(hit.transform); Debug.Log("clicked"); } } }
This isn't working at all. It looks like it would, but it's not, Im not getting anything in my console, any suggestions why? I'm using an Orthographic camera if that would make any difference. I've also changed your tags from Selected, to Select (and Deselected - Deselect) as those are the tags I have
Okay, it does work -- but heres my situation - I have a sphere collider going around a child within my cube (with trigger on - deter$$anonymous$$es range). The script has been applied to my cube, now the sphere collider is bigger than the cube collider therefore it does not register when I hit the cube collider, and I don't want to make the cube collider bigger as then the user will be able to select out of the cube ... Help
<< Hope that made sense: I have a Cube (with original collider), a child of that cube, I have an empty (with a big sphere collider - trigger). Cube/Empty
You should really have included that information in your question as that changes what you are trying to do a fair bit. I will post the code for that specific case.
Your answer
Follow this Question
Related Questions
Hard to select certain objects (collider problem??) 2 Answers
Clickable area problem? 0 Answers
Click On Objects Within Scene 2 Answers
Why 2D colliders doesn't work? 1 Answer
Adding multiple simple mesh colliders to be able to click on an objects parent 0 Answers