Author Topic: Getting a UIRect to follow a GameObject in screen space  (Read 2197 times)

Vesuvian

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 32
    • View Profile
Getting a UIRect to follow a GameObject in screen space
« on: March 05, 2014, 10:02:49 AM »
Hey guys

I'm probably reinventing the wheel here, but I'm trying to write a component for tracking a given UIRect in screen space to a GameObject in world space.



I'm basically trying to abstract the process of setting a UIRect to Unified anchor mode and assigning a camera. Unfortunately my panels still don't seem to move away from the center of the screen.

Apologies for the code dump, I promise it isn't complicated!

The component:

  1.         [ExecuteInEditMode]
  2.         /// <summary>
  3.         /// Anchor class which anchors a NGUI object to a GameObject
  4.         /// </summary>
  5.         public class AnchorNguiToGameObject : AthgoMonoBehaviour
  6.         {
  7.                 #region Properties
  8.  
  9.                 private UIRect m_Target;
  10.                 /// <summary>
  11.                 /// Gets or sets the UIRect we are anchoring.
  12.                 /// </summary>
  13.                 /// <value>The target.</value>
  14.                 public UIRect target
  15.                 {
  16.                         get
  17.                         {
  18.                                 return this.m_Target;
  19.                         }
  20.                         set
  21.                         {
  22.                                 this.SetTarget(value);
  23.                         }
  24.                 }
  25.                
  26.                 /// <summary>
  27.                 /// Gets or sets the target camera.
  28.                 /// </summary>
  29.                 /// <value>The target camera.</value>
  30.                 public Camera targetCamera
  31.                 {
  32.                         get
  33.                         {
  34.                                 return this.GetTargetCamera();
  35.                         }
  36.                         set
  37.                         {
  38.                                 this.SetTargetCamera(value);
  39.                         }
  40.                 }
  41.  
  42.                 #endregion
  43.  
  44.                 #region Methods
  45.                
  46.                 /// <summary>
  47.                 /// Sets the target that is being anchored to the GameObject.
  48.                 /// </summary>
  49.                 /// <param name="target">Target.</param>
  50.                 public void SetTarget(UIRect target)
  51.                 {
  52.                         if (target == this.m_Target)
  53.                                 return;
  54.                        
  55.                         this.m_Target = target;
  56.  
  57.                         if (this.m_Target is UIPanel)
  58.                                 (this.m_Target as UIPanel).clipping = UIDrawCall.Clipping.ConstrainButDontClip;
  59.  
  60.                         foreach (UIRect.AnchorPoint anchor in this.GetAnchorPoints())
  61.                                 anchor.target = this.transform;
  62.                 }
  63.                
  64.                 /// <summary>
  65.                 /// Returns the camera that is used to track the UIRect.
  66.                 /// </summary>
  67.                 /// <returns>The target camera.</returns>
  68.                 public Camera GetTargetCamera()
  69.                 {
  70.                         foreach (UIRect.AnchorPoint anchor in this.GetAnchorPoints())
  71.                                 return anchor.targetCam;
  72.  
  73.                         return null;
  74.                 }
  75.                
  76.                 /// <summary>
  77.                 /// Sets the camera that is used to track the UIRect.
  78.                 /// </summary>
  79.                 /// <param name="camera">Camera.</param>
  80.                 public void SetTargetCamera(Camera camera)
  81.                 {
  82.                         if (this.m_Target == null)
  83.                                 throw new Exception("Can't set target Camera. No target!");
  84.  
  85.                         foreach (UIRect.AnchorPoint anchor in this.GetAnchorPoints())
  86.                                 anchor.targetCam = camera;
  87.                 }
  88.                
  89.                 /// <summary>
  90.                 /// Returns the list of anchor points for the current target.
  91.                 /// </summary>
  92.                 /// <returns>The anchor points.</returns>
  93.                 public List<UIRect.AnchorPoint> GetAnchorPoints()
  94.                 {
  95.                         List<UIRect.AnchorPoint> anchorPoints = new List<UIRect.AnchorPoint>();
  96.  
  97.                         if (this.m_Target != null)
  98.                         {
  99.                                 anchorPoints.Add(this.m_Target.bottomAnchor);
  100.                                 anchorPoints.Add(this.m_Target.topAnchor);
  101.                                 anchorPoints.Add(this.m_Target.leftAnchor);
  102.                                 anchorPoints.Add(this.m_Target.rightAnchor);
  103.                         }
  104.  
  105.                         return anchorPoints;
  106.                 }
  107.  
  108.                 #endregion
  109.         }

The result:



It's a coincidence that the first anchor is above the sphere:



But the second and third anchors are to the right and below the sphere:





My first question:
Am I missing anything important from my component to get a given UIRect to reliably anchor to the GameObject?

Second question:
I suspect the reason the UIRects are stuck in the center of the screen is because they are parented to the center anchor. If this is the case, what should they be parented to? It doesn't make sense to parent them to my tracking component since I don't want them moving in world space.

As always, please let me know if my hierarchy is garbage. I think the hierarchy stuff is the hardest part for me to grasp with NGUI.

Thanks,
Ves
« Last Edit: March 05, 2014, 10:15:37 AM by Vesuvian »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Getting a UIRect to follow a GameObject in screen space
« Reply #1 on: March 06, 2014, 11:25:17 AM »
I'm confused a bit by what you mentioned. You're trying to set a a game object from UIRect? NGUI's anchoring system goes the other way around. It sets the rectangle based on some anchor targets -- which can be in your UI, or just 3D game objects.

If you are indeed just trying to do the opposite of what I interpreted it as, then setting an anchor is as simple as calling UIWidget's SetAnchor function. If you need to set them to 4 separate game objects instead, look inside that function to see what it does, and mimic the code, giving 4 different game objects as targets.

Vesuvian

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 32
    • View Profile
Re: Getting a UIRect to follow a GameObject in screen space
« Reply #2 on: March 06, 2014, 05:34:41 PM »
Hey ArenMook

I need to be able to get a given UIRect to follow a GameObject in screen space. I understand I can do this by using the "Unified" anchor mode, but I want to be able to set this up programatically. There are a few parts I'm a little stuck with:

1) "Unified" is just an abstraction in the editor script. How do I get the same behaviour programatically?
2) What should the UIRect be parented to in the UI hierarchy while it follows the GameObject?
3) My GameObject is presented in a perspective camera while my UIRects are in an orthagraphic camera in the UI hierarchy. Will the UIRect correctly follow its target?

Apologies if I've completely misunderstood how anchoring works.

Thanks,
Ves

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Getting a UIRect to follow a GameObject in screen space
« Reply #3 on: March 07, 2014, 08:49:22 AM »
1. UIRect has a SetAnchor() function that sets your unified anchor. You can look inside that function to find out what it does exactly.
2. Doesn't matter.
3. Yup.

Vesuvian

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 32
    • View Profile
Re: Getting a UIRect to follow a GameObject in screen space
« Reply #4 on: March 07, 2014, 02:04:49 PM »
Thanks for the tips ArenMook, I'm starting to get somewhere!

http://gyazo.com/6716dcaff90f8c638bc77d2814578028