Help Please - 2D Game Perspective Camera

Hi

I’ve change the camera to Perspective to give it a ‘3D’ look, but in doing so, my mouse clicks are all over the place.

Can anyone help?

  if (Input.GetMouseButtonDown(0)) {
		Vector2 point = controlCamera.ScreenPointToRay(Input.mousePosition).origin;
		hit = Physics2D.Raycast(point, Vector2.zero);
		if (!hit.transform) return;
		pressedChip = hit.transform.GetComponent<Chip>();
		pressPoint = Input.mousePosition; 
	}
	if (Input.GetMouseButton(0) && pressedChip != null) {
		Vector2 move = Input.mousePosition;
		move -= pressPoint;
		if (move.magnitude > Screen.height * 0.05f) {
			foreach (Side side in Utils.straightSides)
				if (Vector2.Angle(move, Utils.SideOffsetX(side) * Vector2.right + Utils.SideOffsetY(side) * Vector2.up) <= 45)
					pressedChip.Swap(side);
			pressedChip = null;
		}
	}

Your issue comes fromt the fact that with an orthographic camera, the x and y of the ray direction returned by ScreenPointToRay are 0 (assuming the camera is facing directly forwards). This is because an orthographic camera is ‘flat’, so regardless of where you click, your ray is correctly represented by an ‘origin’ on the front camera plane, and a ray that points directly forwards.

In your case you disregard the z of the camera origin, and use the x and z to construct a 2d ray that goes from where the user clicked to [0,0]. Assuming the camera is at [0,0,something], this is a ray pointing from where the user cicked to the centre of the screen.

Once you switch to a perspective camera, your assumption is no longer true - the direction of the ray changes depending on where you click. This link might help:

http://blender.stackexchange.com/questions/648/what-are-the-differences-between-orthographic-and-perspective-views

As a result you need to do a few extra steps:

  • First, get the ray from the perspective camera that corresponds to where the user clicked
  • Now project forwards along this ray, to calculate the world space position that the user clicked on that corresponds to the world space z position of your level (probably 0?)
  • From there, you have a position you can run your existing logic with

This would look something like the below:

//first we get the ray represented by the mouse click. because its a perspective camera, 
//the direction will change depending on where you click
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

//the ray origin is the position in world space on the 'front' plane of the camera. however
//for your game we need to go forwards to the plane of your objects. I am going to assume
//that is z==0 for now, so...
float z_plane_of_2d_game = 0;
Vector3 pos_at_z_0 = ray.origin + ray.direction * (z_plane_of_2d_game - ray.origin.z) / ray.direction.z;

//now we have a 3D point on the correct plane, we can continue with your code
Vector2 point = new Vector2(pos_at_z_0.x,pos_at_z_0.y);
hit = Physics2D.Raycast(point, Vector2.zero);

Hope that helps

-Chris

Maybe you should try Physics2D.GetRayIntersection.

			Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

			RaycastHit2D hit = Physics2D.GetRayIntersection(ray);