To understand the issue it's best to understand how ScreenToWorldPoint
works. Close one of your eyes and look straight ahead and don't move your eye (like a 2D camera). Then extend one of your arms and take your pointer finger and place it on top of something in the distance of your view (like a mouse pointer) but don't move your eye or look directly at it. The ScreenToWorldPoint
function works somewhat by taking note of where your finger is on the X and Y axis of your eye's view, but it will also need to know how far out you extended your arm and finger on the Z axis (depth) to make your finger align with what you are pointing at. Like drawing a line from your eye to your finger.
The issue is that Input.mousePosition
will return a Vector3 where the Z axis (depth) is 0. That means when you pass it to ScreenToWorldPoint
it basically doesn't know how far out you extended your arm and finger. That is like taking your finger and placing it directly on top of your eyeball, but adding very little X or Y so the finger is still pointing at your object. You will get very small X and Y values, and the Z value will be whereever your eyeball (camera) is.
The other issue is that you are manually setting the resulting X value to 0. So X will always be 0, and the Z will always be at the camera's Z position, and the Y value will be very small, all because no depth value was passed to the ScreenToWorldPoint
function. This will result in the ballPrefab
always ending up in roughly the same location in the world.
So try to give it a depth reference like this:
public float distanceFromCamera = 5f;
public GameObject ballPrefab;
void Update()
{
if (Input.GetButtonDown("Fire1"))
{
Vector3 mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(
new Vector3(mousePos.x, mousePos.y, distanceFromCamera));
Instantiate(ballPrefab, mousePos, ballPrefab.transform.rotation);
}
}
It seems you want the ball to always be on the X axis of the world, so another solution is to use the absolute value of the camera's X position (which is the distance the camera is from X = 0) as the depth value.
mousePos = Camera.main.ScreenToWorldPoint(
new Vector3(mousePos.x, mousePos.y,
Mathf.Abs(Camera.main.transform.position.x)));
This will allow you to move your camera in and out (in your case along the X axis) without having to adjust any distanceFromCamera
variable.