- Home /
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; } }
Any suggestions would be greatly appreciated.
I understand that this will need to be changed to Vector3, but not too sure on the best approach to do this while maintain the 2D component of the game.
Hi
Apologies for bumping this again.
Having a difficult time converting this to accept Vector3 as opposed to Vector2, any help would be very greatly appreciated.
What would be the best way to insert Vector3 functions but still preserve the 2D mechanics of the games?
Thanks
Answer by wibble82 · Dec 07, 2015 at 11:20 AM
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:
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
Thanks for such an amazing answer.
I'll begin to implement this at once, how about the segment of code below as it is Vector2 do I need to convert the Vector3 readings to Vector2?
You see I want the 2D game mechanics to work as normal and just change the way the mouse clicks are recognised.
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;
}
No prob :)
The general rule is that whenever you're doing stuff that depends on conversion from screen positions (i.e. mouse clicks) to world space positions, you'll want to make sure you're working in the correct plane using the approach I showed (crucially the getting of a ray, then calculating a position on the correct plane).
I'm not sure exactly whether your code below will need changing as I can't see precisely what it does. If you're dependent on 'move' being in world space, you'll need to do some extra work. If all you're interested in is how much the user moved the cursor, then you needn't worry!
BTW - if you're happy with the answer, mark it as 'correct' - then others with similar questions will find it more easily! :)
I honestly can't thank you enough, it worked perfectly!
Thanks again!!
Me funcionó a la primera, que ganas de chuparte la pija hermano.
Answer by Yword · Dec 07, 2015 at 10:56 AM
Maybe you should try Physics2D.GetRayIntersection.
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit2D hit = Physics2D.GetRayIntersection(ray);
Your answer
![](https://koobas.hobune.stream/wayback/20220612051559im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
2D game with angled top-down camera perspective 1 Answer
Camera Rotation, Side to top-down view 1 Answer
Unity3d or Maya-style Camera navigation 5 Answers
Camera follow help? 1 Answer
Fixed "angle/perspective" on 3D camera 2 Answers