Topic: NGUI Markers rendering in wrong locations, again :(

So I know I posted that the last code fix worked perfectly, but unfortunately I was wrong. Being new to NGUI myself, I had to go back and re-do a lot of my interface layout for it to work properly, and that uncovered some more problems with putting NGUI markers in the right place.

I've spent a couple of days drilling down through both NGUI and Online Maps code, and I *think* the problem lies getting to the final world position for the NGUI marker so that it will render in the right place. The chain that I've figured out so far is:

Geographical space (long/lat) => Map Screen Space (OnlineMapsControlBase.instance.GetScreenPosition) < = >  NGUI Screen Space (widget.setRect) => (lots of transform/widget manipulation => NGUI World Space.

My gut tells me that widget.setRect is missing/neglecting some coordinate space transform that is causing the offset...but it could also be zoom level related, since that also causes the markers to move to the wrong places.

What's happening right now is illustrated in two ways:

1) I have code that when I click on a marker, it uses  OnlineMaps.instance.SetPositionAndZoom(coords.x, coords.y, 10) to center the map on the marker's coordinates (long,lat). What actually happens however is that the map centers in the right place and zoom, but the marker is rendered far to the left of the center of the screen (see attached image).

2) As you zoom in and out, the markers move about drastically. The farther out you zoom, the worse the dislocation is (markers all cluster out in the ocean near each other), but the closer you zoom in, the closer the marker gets to the correct position (my house).

Another thing that I've noticed is that the culling algorithm in the marker example is broken again...and it appears that the map object is somehow offset to the left, and adding in the Vector2() to the rectangle in the code below isn't working at all--even out to adding in an x value of 1000+.

Finally, I went back to basics and loaded up the original example code in an empty scene (except for adding a map), and I did see that the very simple NGUI marker (I used a basic sprite) did jitter around as the map scrolled/updated. It wasn't as bad as my more intricate scene, but it was noticeable when compared to the default marker in the non-NGUI examples.

Here's my current marker system code's OnMapUpdated()--I left in the debugging code that simply identifies 1 marker (the one in the screenshot), and outputs a few data elements you see in the debug panel at the bottom of the screenshot. You'll notice that I commented out the culling portion completely just to get it out of the way.

 
        private void OnMapUpdated()
        {
            Vector2 tl = OnlineMaps.instance.topLeftPosition;
            Vector2 br = OnlineMaps.instance.bottomRightPosition;

            Rect rect = new Rect(tl.x, br.y, br.x - tl.x, tl.y - br.y);
            if (rect.width < 0) rect.width += 360;
            // eventually need to iterate over all marker lists
            foreach (CityMarker marker in cityMarkers)
            {
                Vector2 p = marker.coords;
                GameObject go = marker.gameObject;

                //if (!rect.Contains(p))
                //{
                    //if (!rect.Contains(p + new Vector2(360, 0)))
                    //{
                    //    if (go.activeSelf) go.SetActive(false);
                    //    continue;
                   // }
               // }
            

            if (!go.activeSelf) go.SetActive(true);

            Vector2 screenPosition = OnlineMapsControlBase.instance.GetScreenPosition(p);
            screenPosition.x -= Screen.width / 2;
            screenPosition.y -= Screen.height / 2;
            Vector2 buttonOffset = new Vector2(-marker.size.x / 2, 0);
            //Vector2 buttonOffset = new Vector2(0, 0);

            if (marker.mCityName == "Nemesis")
            {
                string coords = marker.coords.ToString();
                //Vector3 wToLocalPoint = NGUIMath.WorldToLocalPoint(Vector3 worldPos, Camera worldCam, Camera uiCam, Transform relativeTo)
                string overlayTrans = String.Format("X:{0} Y:{1}",
                                         transform.localPosition.x,
                                         transform.localPosition.y);
                string objTrans = String.Format("X:{0} Y:{1}",
                                         transform.localPosition.x,
                                         transform.localPosition.y);
                string worldTrans = String.Format("X:{0} Y:{1}",
                                         transform.position.x,
                                         transform.position.y);
                string setRectCall = String.Format("(X:{0} Y:{1}",
                                     (screenPosition.x + buttonOffset.x),
                                     (screenPosition.y + buttonOffset.y)
                                     );
                
                GameObject.Find("DebugPanelBase").GetComponent<DebugPanel>().setData(
                            marker.mCityName,
                            coords,
                            overlayTrans,
                            objTrans,
                            worldTrans,
                            setRectCall);

            }
            marker.widget.SetRect(screenPosition.x + buttonOffset.x, screenPosition.y + buttonOffset.y, marker.size.x, marker.size.y);
            }
        }
    }

I'm not sure how long ago the code was written for the NGUI example, but I think that they probably changed something recently that made the problem more obvious? I'm using the most recent release.

I do have an example build that I can FTP up somewhere (about 14 meg zipped) if you'd like to see the issue "live" so to speak...but right now I'm basically stuck, so any suggestions would be much appreciated!

Post's attachments

Attachment icon displaced marker.png 940.32 kb, 118 downloads since 2016-03-14 

Re: NGUI Markers rendering in wrong locations, again :(

Hello.

Please send us a scene where we can see the problem.
You can post a link here, or write to support (support@infinity-code.com).
I will check it and make changes or give you advice.

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: NGUI Markers rendering in wrong locations, again :(

I'll put together a standalone scene that exhibits the response as quickly as I can--my current scene has a host of dependencies from other code and back end server login/download.

Thanks for the quick response.

Re: NGUI Markers rendering in wrong locations, again :(

One thing that did occur to me late last night however: Since the setPositionAndZoom call is moving the map such that the marker is in the center of the screen, shouldn't the values generated for setRect be very close to 0,0 (center of screen)? Or am I missing something?

Re: NGUI Markers rendering in wrong locations, again :(

Yes, it should.

For the center of the screen, it should be approximately (if you did not change the alignment)
SetRect (-marker.size.x / 2, 0, marker.size.x, marker.size.y);

Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: NGUI Markers rendering in wrong locations, again :(

I just now sent off a .zip file to the support email with a scene + assets to duplicate the issue.

I did notice that in the other marker implementations (non-NGUI), I couldn't find any reference to the following:

            screenPosition.x -= Screen.width / 2;
            screenPosition.y -= Screen.height / 2;

In all the cases I back traced, there were other techniques used to establish the screen alignment, but honestly I got lost trying to extract the best technique. I *think* we need to pull it from NGUI somehow, but I've not yet seen how.

Re: NGUI Markers rendering in wrong locations, again :(

About alignment:
In screen coordinates (0, 0) - is the top-left corner of the screen.
In input coordinates (0, 0) - is the bottom-left corner of the screen.
In uGUI (0, 0) - position depends on the alignment of element.
In NGUI (0, 0) - is the center of the screen.

About the problem:
I found it.
UI Root / Transform / Position (-1, 0, 0).
Reset position, and everything will work correctly.

Also, I modified the script:

float ratio = (float)marker.widget.root.activeHeight / Screen.height;
float width = Mathf.Ceil(Screen.width * ratio);

screenPosition.x = (screenPosition.x / Screen.width - 0.5f) * width;
screenPosition.y = (screenPosition.y / Screen.height - 0.5f) * marker.widget.root.activeHeight;
Kind Regards,
Infinity Code Team.

Boost your productivity a lot and immediately using Ultimate Editor Enhancer. Trial and non-commerce versions available.

Re: NGUI Markers rendering in wrong locations, again :(

Wow...what a catch. I fixed the UI Root transform, and also added in the code you suggested and it's working again.

Amazing that such a tiny UI user mistake caused so much of a visual issue, but you nailed it...it was exactly what was wrong.

Outstanding support so far guys, thanks a lot!