# Unity3D: Touch and Objects have different coordinate systems

I would like to associate the same script to different empty objects I just use as placeholders in the game. The aim is to exploit their positions so that when the user touch a point in the screen, close to one of these objects, a dedicate GUI appears. The problem is that though the two objects are different their scripts seem to influence each other so that when the game is running and I touch one of these two objects both the gui appears. What am I doing wrong?

Some hours later... This happens because the object and the touch are in two different coordinate systems. For instance though I touch the object I get (-0.77, 0.46) for the object and (12.1,95.2) for the touch which, I guess, is measured in pixel. How to transform one into the other?

....
private var check: boolean;
var topCamera : Camera;
var customSkin : GUISkin;

function Update () {
if (Input.GetMouseButtonDown(0)){
if(Input.mousePosition.x > this.transform.position.x - Screen.width*0.20 && Input.mousePosition.x < this.transform.position.x + Screen.width*20){
if(Input.mousePosition.y > this.transform.position.y - Screen.height*0.2 && Input.mousePosition.y < this.transform.position.y + Screen.height*0.2){
check = true;
}
}
}

if(check){
//the camera zooms forward
}else{
//the camera zooms backward
}
}

function OnGUI () {
if (this.check){
var w = Screen.width;
var h = Screen.height;
var bw = 0.083;
var bws = 0.001 *w;
GUI.skin = customSkin;
GUI.Box(new Rect(w*0.6,h*0.3,w*0.38,h*0.45), "Stuff");
customSkin.box.fontSize = 0.04*h;
customSkin.textField.fontSize = 0.08*h;
customSkin.button.fontSize = 0.04*h;
textFieldString = GUI.TextField (Rect (w*0.62, h*0.39, w*0.34, h*0.1), textFieldString);
if (GUI.Button (Rect (w*0.62,h*0.50, w*bw, h*0.1), "+")) {
if (this.check){
this.check=false;

}else{
this.check = true;
}
//...
}
//...
}


Some hours later... This happens because the object and the touch are in two different coordinate systems. For instance though I touch the object I get (-0.77, 0.46) for the object and (12.1,95.2) for the touch which, I guess, is measured in pixel. How to transform one into the other?

As you said, touch/mouse clicks are measured in pixels, and transform.position is measured depending on the kind of GameObject you have. For example, for GUI Textures it is measured on Viewport coordinates; for a Mesh objects it is measured in World coordinates. Other objects like the GUI buttons etc, have pixels (screen) coords taken from the Rect that defines them.

Unity provides functions (actually accessible from a Camera Component) to change from one coordinate system into the other:

Camera.WorldToScreenPoint To change from world to pixels (screen)

[Camera.ScreenToWorldPoint] To change from screen to World

... and so on. Look for this kind of functions on the Camera Component specification

Hard to say without any code, but you seem to share the objects states in some way. I guess, there's a variable that determines whether the GUI is visible or not - does that happen to be a static variable? If so, make it non-static, because static variables only exist once (globally) und thus are shared among all object instances.

Another possible problem might be the code by which you determine whether an object is pressed by the user - even if the objects do not share a state, they might still trigger all at once due to some coding error. Again, hard to say without any code.

Edit: The code itsself doesn't seem to be wrong, but I'm not really experienced with UnityScript / JavaScript - I always used C# in Unity. However, you are comparing the transforms X and Y coordinates to X and Y screen coordinates - which can be correct but is not necessarily correct. Since transform describes a position in space (3D), it depends on the cameras view whether X-X and Y-Y comparisons are correct. If the camera looks at the scene at a different angle, it might be X-Z and Y-Y or even completely wrong due to non axis-aligned view or perspective projection parameters. I'm not using Unity anmore, but could you use an additional trigger-setting Collider Component to recieve mouse events? That should be a lot more robust and flexible.

• ok the code checking whether the touch is close to the object basically consists of two if statements comparing the touch position with the this.transform.position.x and y plus/minus a delta proportional to the screen.width/height. If these conditions are verified a boolean status variable which is private but not static is set to true. An OnGUI function is thus conditioned on the this.status variable so that the GUI apperas when the touch is around the object. The problem is that both the GUIs appear at the same time. If it is still hard to get I can post the code. – www.Sillitoy.com May 13 '12 at 8:19
• @www.Sillitoy.com Based on your description, everything should be fine. As far as I know there is no "secret script link" in Unity, two instances of the same script shouldn't be related in any unexpected way. So yes, code would be helpful. – Adam May 13 '12 at 9:09
• I have edited the question and added some code. Thank you for your help – www.Sillitoy.com May 13 '12 at 9:16
• edited again, important discovery on coordinates :) – www.Sillitoy.com May 14 '12 at 5:21
• @www.Sillitoy.com I've edited my answer based on your code. But still, just guessing. – Adam May 14 '12 at 9:05