Author Topic: NGUI custom markers with Infinity Code Online Maps -- matching coordinate spaces  (Read 2973 times)

StephenZepp

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 7
    • View Profile
I've spent the last several days trying to figure out how to properly place NGUI objects as markers on top of an Infinity Code Online Map implementation, but am running into multiple issues with proper positioning on the screen. I'm pretty sure I've narrowed it down to an issue with coordinate spaces, but I'm stuck at this point.

The Online Maps implementation basically has two spaces: geographical space (longitude/latitude), and screen space, with helpers to convert from geo-space to screen space, with the expectation that the helper provides a location to place a widget's render location with widget.SetRect...unfortunately, the marker doesn't actually render where the map thinks it should.

My scene has one camera with both Camera and UI Camera components, and my map is in it's own Panel. At run time, my script instantiates a marker set (basic UIWidget with a few child sprites) from an object in the hierarchy for each of the markers in the list with the following code:

  1.             GameObject go = NGUITools.AddChild(instance.container.gameObject,instance.cityPrefab);
  2.             go.transform.localScale = Vector3.one;
  3.             go.transform.localPosition = Vector3.one;
  4.  
  5.  
and then sets the coordinates based on the long/lat of where the marker should be. (All of this works fine). Note that "instance.container" is the actual Panel that contains the map.

The problem comes when the markers want to update their position based on a map change (scroll, zoom changes), which has to update the position of the markers. The current (not working properly) code is:

  1.  
  2.             foreach (CityMarker marker in cityMarkers)
  3.             {
  4.                 Vector2 p = marker.coords;
  5.                 GameObject go = marker.gameObject;
  6.  
  7.                 if (!go.activeSelf) go.SetActive(true);
  8.  
  9.                 Vector2 screenPosition = OnlineMapsControlBase.instance.GetScreenPosition(p);
  10.                 screenPosition.x -= Screen.width / 2;
  11.                 screenPosition.y -= Screen.height / 2;
  12.                 Vector2 buttonOffset = new Vector2(-marker.size.x / 2, 0);
  13.                 marker.widget.SetRect(screenPosition.x + buttonOffset.x, screenPosition.y + buttonOffset.y, marker.size.x, marker.size.y);
  14.             }
  15.  
  16.  

GetScreenPosition is the primary helper I have from the Online Maps implementation, and I don't have any helpers that are designed to return world space.

My root question is what do I need to do with the NGUI UIWidget to get it to draw at the screen position indicated by the GetScreenPosition helper? I'm sure there are coordinate space and camera relationship issues that the simple widget.setRect call isn't handling properly, but after 2 days of working this I'm totally lost as to how NGUI wants me to place the UIWIdget.

StephenZepp

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 7
    • View Profile
Follow up with answer, and notes:

The root issue was a simple "stupid newb" mistake: I had somehow changed the position of my UI Root to have an X value of -1...the developers over at Infinity Code (Online Maps Asset) found the mistake, and along the way validated that setRect() was a valid way of accomplishing my task (which was from their demo code on NGUI Marker integration).

I do want to note (and this isn't a judgement, just an observation) that it was difficult to find out the "NGUI Way" of procedurally creating and positioning UI objects. I did a lot of searching through the forums here, and code study of the documentation along the way and picked up a bunch of separate tidbits ("use panels for complex UI's", "localPosition/localScale may be important") but it was difficult to find a working example of procedurally generating and manipulating UI objects in general...all of the examples were around tying UI elements to "in game" objects, and/or using tweens (neither of which fit what I needed to do).

I do fully admit it's an unusual use case, but I'd vote for this type of example in future releases if it's on the table ;)