- Home /
Problem with ScreenToWorldPoint and touches (C#)
I am trying to instantiate an object at the point where the the player touches the screen. Here is my code so far:
public class CreateObject : MonoBehaviour
{
public GameObject createdObject;
void Update ()
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
Vector3 vec = Camera.main.ScreenToWorldPoint(touch.position);
vec.z = 0;
Instantiate(createdObject, vec, Quaternion.identity);
}
}
}
}
The problem is that vec always returns as 0,0,0 (or rather 0, 0, -10, but I changed the z value to 0). What am I doing wrong? Just FYI, I have my camera located at 0, 0, -10 and facing 0, 0, 0 in world space. Not sure if that matters or not. Thanks!
Answer by aldonaletto · Dec 27, 2011 at 12:42 AM
ScreenToWorldPoint must receive a Vector3 where x and y are the screen coordinates, and z is the distance from the camera. Since you're passing a Vector2, the compiler promotes it to Vector3 setting the z coordinate to 0, what will always return the camera position, no matter what x and y are.
If must copy touch.position to a Vector3 variable and set its z component to the distance you want:
Vector3 tch = touch.position; tch.z = 15; // define distance from the camera Vector3 vec = Camera.main.ScreenToWorldPoint(tch); Instantiate(....);Unfortunately, this will create all objects at a fixed distance from the camera - or at the surface of a sphere with radius 15, in this case.
If you want to create the objects in a plane, you should use ScreenPointToRay instead: create the base plane, create the ray, use plane.Raycast to find the distance, and ray.GetPoint(distance) to find the point... a piece of cake, for sure! But don't panic, the whole thing is easier than it may look:
public class CreateObject : MonoBehaviour {
public GameObject createdObject;
// create a plane in xy, at z = 5
Plane basePlane = new Plane(-Vector3.forward, new Vector3(0, 0, 5));
void Update (){
foreach (Touch touch in Input.touches){
if (touch.phase == TouchPhase.Began){
// no need to set z, because ScreenPointToRay ignores it
Ray ray = Camera.main.ScreenPointToRay(touch.position);
float distance;
if (basePlane.Raycast(ray, distance)){
Vector3 vec = ray.GetPoint(distance); // get the plane point hit
Instantiate(createdObject, vec, Quaternion.identity);
}
}
}
}
}
Answer by Rod-Green · Dec 27, 2011 at 01:03 AM
It's an issue with vec2 to vec3 conversion:
public class CreateObject : MonoBehaviour
{
public GameObject createdObject;
void Update ()
{
foreach (Touch touch in Input.touches)
{
if (touch.phase == TouchPhase.Began)
{
Vector3 vec = Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, Camera.main.nearClipPlane + 5.0f));
Vector3 oldVec = Camera.main.ScreenToWorldPoint(touch.position);
Debug.Log (oldVec + " vs " + vec);
//vec.z = 0;
Instantiate (createdObject, vec, Quaternion.identity);
}
}
}
}
Your answer
Follow this Question
Related Questions
Unity 2D Rouge-Like game tutorial help 0 Answers
Distribute terrain in zones 3 Answers
Multiple Cars not working 1 Answer
Objects seemingly not being instantiated after touch. 1 Answer
Trying To Find Mouse Position On Tap 1 Answer