启用Display 2时Hit Camera无法识别鼠标位置的问题排查
Alright, let's break down why your Cam 1 isn't picking up mouse input when you're on Display 2, and walk through how to fix it.
Root Causes
Your issue stems from two key problems with how Unity handles multi-display setups and camera input:
- Unreliable
Camera.mainreference:Camera.mainpulls the first enabled camera with theMainCameratag. When you switch to Display 2, even if Cam 1 is still running, Unity might prioritize Cam 2 (if it's enabled) or the lookup might behave unexpectedly—breaking your raycast source. - Mismatched mouse coordinates across displays:
Input.mousePositionuses the main display (Display 1) as its origin. When your mouse is on Display 2, its coordinates will be outside Cam 1's screen bounds (e.g., if Display 1 is 1920px wide, Display 2 mouse X will be 1920+). Using these coordinates with Cam 1'sScreenPointToRayshoots a ray outside Cam 1's view, so it never hits your ground layer.
Fix Steps
Let's address both issues with concrete changes to your code and setup:
1. Replace Camera.main with a direct reference
Ditch the fragile tag-based lookup and reference Cam 1 directly. This eliminates any ambiguity about which camera is handling the raycast:
public class HitCameraController : MonoBehaviour { // Assign Cam 1 directly in the Inspector public Camera hitCamera; public static Vector3 mousePos; public static bool gotMouse; public static bool mouseMoved; private Vector3 lastMouseMovement; void Start () { gotMouse = false; mouseMoved = false; lastMouseMovement = Vector3.zero; // Fallback to Camera.main if you forget to assign in Inspector if (hitCamera == null) { hitCamera = Camera.main; } } void Update () { // Use our direct camera reference + corrected mouse position Ray ray = hitCamera.ScreenPointToRay(GetMousePositionForCamera(hitCamera)); RaycastHit hit; LayerMask ground = LayerMask.GetMask("GroundLayer"); if(Physics.Raycast(ray, out hit, 300, ground)) { mousePos = new Vector3(hit.point.x, 0f, hit.point.z); mouseMoved = !mousePos.Equals(lastMouseMovement); lastMouseMovement = mousePos; gotMouse = true; } else { gotMouse = false; } } // Helper to get mouse coordinates relative to the target camera's display private Vector3 GetMousePositionForCamera(Camera targetCamera) { // Get mouse position relative to the specific display the camera is targeting Vector3 relativeMouse = Display.RelativeMouseAt(Input.mousePosition); // Only process input if the mouse is on the camera's display if (relativeMouse.z == targetCamera.targetDisplay) { return new Vector3(relativeMouse.x, relativeMouse.y, 0f); } // Return an off-screen position if mouse is elsewhere (prevents false raycasts) return new Vector3(-1f, -1f, 0f); } }
2. Verify Camera Display Settings
Double-check your camera configuration in the Inspector:
- For Cam 1: Set
Target Displayto 1 - For Cam 2: Set
Target Displayto 2
This ensures Unity routes each camera's output to the correct monitor, and ourRelativeMouseAtcheck works as intended.
3. Optional: Cross-Display Input (If Needed)
If you want Cam 1 to handle mouse input even when the cursor is on Display 2 (e.g., cross-monitor ground selection), modify the helper method to skip the display check and convert coordinates properly:
private Vector3 GetMousePositionForCamera(Camera targetCamera) { // Convert global mouse position to the camera's viewport space, then back to screen space Vector3 viewportPos = targetCamera.ScreenToViewportPoint(Input.mousePosition); return targetCamera.ViewportToScreenPoint(viewportPos); }
Note: This might feel unintuitive for users, so only use it if cross-display interaction is a requirement.
Quick Sanity Checks
- Make sure only Cam 1 has the
MainCameratag—remove it from Cam 2 to avoid anyCamera.mainconfusion. - If you don't need Cam 1 active when on Display 2, you could toggle its enabled state when switching displays, but that would disable ground selection on Display 2 entirely.
内容的提问来源于stack exchange,提问作者Bradley William Elko

