简体   繁体   中英

How to remap mouse position to a potentially moving UI element?

I'm working on an RTS game with some pretty extensive UI, so I moved the main camera's output to a quad which only makes up about half the screen, and I'm blitting some UI effects over the rest. My current way of interacting with the game uses unity's Input.mousePosition. When I moved the camera's feed to the quad, obviously those pixel coordinates were distorted, so I fixed them like this:

mapMousePos = (Input.mousePosition * mscaleCorr - mapCorrection * mscaleCorr);

mapCorrection being the pixel offset of the smaller feed, and mscaleCorr being a magic number that got through trial and error — a temporary fix.

Point is, now I'm realizing that running this game at a different resolution will almost certainly break these magic numbers.

What I want mapMousePos to be is what Input.mousePosition was before I moved the gameplay to the small quad - going from (0,0) in the bottom left of the quad to the screen (width, height) in the top right of the quad. This is just so it works with screenToWorld point really nicely on my gameplay camera.

I have the camera-feed quad parented to a full-screen quad, and tried using their relative positions to apply the necessary transformations, but it didn't work, I'm guessing because it's a pixel problem.

I've dug around the docs for a solution using Camera's builtin worldToScreenPoint function, without any luck. I'm sure I'll bump into a fix eventually, but would greatly appreciate any pointers.

Here's what I've come up with; it's stupid, but it works.

I've placed objects at the bottom left and top right of the quad, stored in code as bL and tR.

Then I convert the mousePosition to a worldPosition using ScreenToWorldPoint(), remap it by subtracting the bottom left position, and get it as a percentage across the screen by dividing it by the delta to the top right. Multiply the percentage by the pixel dimensions of the gameplay camera, and voila.

In code, this:

    Vector3 wPos = finalcam.ScreenToWorldPoint(Input.mousePosition);
    wPos -= bL.transform.position;
    mapMousePos = new Vector2(Mathf.Abs(wPos.x), Mathf.Abs(wPos.y));

    mapMousePos = new Vector2(
        mapMousePos.x / (tR.transform.position.x -bL.transform.position.x),
        mapMousePos.y / (tR.transform.position.y - bL.transform.position.y));

    mapMousePos = new Vector2(mapMousePos.x * Camera.main.pixelWidth, mapMousePos.y * Camera.main.pixelHeight);

Again, it's dumb, but it seems to work. I'm leaving this up in case anybody knows a cleaner method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM