Author Topic: How do I position instantiated buttons prefab?  (Read 4036 times)

dwjkim

  • Guest
How do I position instantiated buttons prefab?
« on: August 28, 2013, 11:24:13 PM »
                  showRingMenu = true;            
                  //GameObject go = NGUITools.AddChild(mPanel, mButtonPrefab);
                  //go.GetComponentInChildren<UILabel>().text = "text";   
                  RingMenuOptions[0] = NGUITools.AddChild(mPanel, mButtonPrefab);
                  RingMenuOptions[0].GetComponentInChildren<UILabel>().text = "S";                  
                  RingMenuOptions[1] = NGUITools.AddChild(mPanel, mButtonPrefab);
                  RingMenuOptions[1].GetComponentInChildren<UILabel>().text = "W";                  
                  RingMenuOptions[2] = NGUITools.AddChild(mPanel, mButtonPrefab);
                  RingMenuOptions[2].GetComponentInChildren<UILabel>().text = "M";                  
                  RingMenuOptions[3] = NGUITools.AddChild(mPanel, mButtonPrefab);
                  RingMenuOptions[3].GetComponentInChildren<UILabel>().text = "E";                     
                  
                  Vector2 center = new Vector2(0, 0);
                  float radius = 0.00000000000000000001f;
                  for (int idx = 0; idx < 4; ++idx)
                  {
                     //RingMenuOptions[idx].GetComponent<Transform>().Translate (center.x+radius * Mathf.Cos ((float)idx*Mathf.PI*2f/4+Mathf.PI*1.5f), 0f, 0f);
                     //RingMenuOptions[idx].GetComponent<Transform>().Translate (0f, center.y+radius * Mathf.Sin ((float)idx*Mathf.PI*2f/4+Mathf.PI*1.5f), 0f);
                     RingMenuOptions[idx].transform.localposition.x = center.x+radius * Mathf.Cos ((float)idx*Mathf.PI*2f/4+Mathf.PI*1.5f);
                     RingMenuOptions[idx].transform.localposition.y = center.y+radius * Mathf.Sin ((float)idx*Mathf.PI*2f/4+Mathf.PI*1.5f);
                     Debug.Log (RingMenuOptions[idx].transform.localposition.x);
                     Debug.Log (RingMenuOptions[idx].transform.localposition.y);
                  }   

I am trying to make a ring menu, that displays the menu as a ring.

My problem is that the buttons keep showing up in the same position, no matter how small the radius of the ring is.

It shows 1, -1 etc. On Debug.Log.

But when I check with inspector by clicking the Instantiated clone of the prefab, it shows something like y = 212 or y = -212?

Result is the same with attaching buttons to anchor or panel.

dwjkim

  • Guest
Re: How do I position instantiated buttons prefab?
« Reply #1 on: August 29, 2013, 12:33:22 AM »
This problem has been solved by using float function instead of vector function.

However, how do I know from script which button has been clicked?

For example in OnGUI,

I could use if (GUI.Button)

so if the button is clicked it would become true.

But how do I know if any of the newly instantiated button has been clicked, so I can move on to the next step?

dwjkim

  • Guest
Re: How do I position instantiated buttons prefab?
« Reply #2 on: August 29, 2013, 01:30:09 AM »
   // Update is called once per frame
   void Update () {
      
      RaycastHit hitinfo;
      if (Input.GetMouseButtonDown(0))
      {
         Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
         
         if (Physics.Raycast (ray, out hitinfo))
         {
            if (hitinfo.transform == player.transform)
            {
               if (showRingMenu)
               {
                  showRingMenu = false;
                  CloseRingMenu();
               }
               else{
                  showRingMenu = true;            
                  DrawRingMenu ();
               }
            }
         }   
      }
   }
   
   void DrawRingMenu()
   {
      //GameObject go = NGUITools.AddChild(mPanel, mButtonPrefab);
      //go.GetComponentInChildren<UILabel>().text = "text";   
      RingMenuOptions[0] = NGUITools.AddChild(mPanel, mButtonPrefab);
      RingMenuOptions[0].GetComponentInChildren<UILabel>().text = "S";                  
      RingMenuOptions[0].GetComponent<UIButtonMessage>().functionName = "S";
      RingMenuOptions[1] = NGUITools.AddChild(mPanel, mButtonPrefab);
      RingMenuOptions[1].GetComponentInChildren<UILabel>().text = "W";                  
      RingMenuOptions[1].GetComponent<UIButtonMessage>().functionName = "W";
      RingMenuOptions[2] = NGUITools.AddChild(mPanel, mButtonPrefab);
      RingMenuOptions[2].GetComponentInChildren<UILabel>().text = "M";                  
      RingMenuOptions[2].GetComponent<UIButtonMessage>().functionName = "M";
      RingMenuOptions[3] = NGUITools.AddChild(mPanel, mButtonPrefab);
      RingMenuOptions[3].GetComponentInChildren<UILabel>().text = "E";                     
      RingMenuOptions[3].GetComponent<UIButtonMessage>().functionName = "E";
      
      Vector2 center = new Vector2(0, 0);
      
      for (int idx = 0; idx < 4; ++idx)
      {
         RingMenuOptions[idx].GetComponent<Transform>().Translate (center.x+radius * Mathf.Cos ((float)idx*Mathf.PI*2f/4+Mathf.PI*1.5f), 0f, 0f);
         RingMenuOptions[idx].GetComponent<Transform>().Translate (0f, center.y+radius * Mathf.Sin ((float)idx*Mathf.PI*2f/4+Mathf.PI*1.5f), 0f);
         //RingMenuOptions[idx].transform.localPosition.x = center.x+radius * Mathf.Cos ((float)idx*Mathf.PI*2f/4f+Mathf.PI*1.5f);
         //RingMenuOptions[idx].transform.localPosition.y = center.y+radius * Mathf.Sin ((float)idx*Mathf.PI*2f/4f+Mathf.PI*1.5f);
      }      
   }
   
   void CloseRingMenu()
   {
      for (int idx = 0; idx < 4; ++idx)
      {
      Destroy (RingMenuOptions[idx]);
      }      
   }
   
   void S()
    {
       showRingMenu = false;
      CloseRingMenu ();
      Debug.Log ("Started s");
    }
   void W()
    {
       showRingMenu = false;
      CloseRingMenu ();
      Debug.Log ("Started W");
    }
   void M()
    {
       showRingMenu = false;
      CloseRingMenu ();
      Debug.Log ("Started M");
    }
   void E()
    {
       showRingMenu = false;
      CloseRingMenu ();
      Debug.Log ("Started E");
    }
   

I have been trying to use that UIButtonMessage thing but it does not work on prefab buttons with prefab target.

Is it wrong?

dwjkim

  • Guest
Re: How do I position instantiated buttons prefab?
« Reply #3 on: August 29, 2013, 03:28:12 AM »
      RingMenuOptions[0].GetComponentInChildren<UILabel>().text = "S";                  
      RingMenuOptions[0].AddComponent<UIButtonMessage>();
      RingMenuOptions[0].GetComponent<UIButtonMessage>().target = gameObject;
      RingMenuOptions[0].GetComponent<UIButtonMessage>().functionName = "S";
      NGUITools.AddWidgetCollider(RingMenuOptions[0]);
      
      RingMenuOptions[1] = NGUITools.AddChild(mPanel, mButtonPrefab);
      RingMenuOptions[1].GetComponentInChildren<UILabel>().text = "W";                  
      RingMenuOptions[1].AddComponent<UIButtonMessage>();
      RingMenuOptions[1].GetComponent<UIButtonMessage>().target = gameObject;
      RingMenuOptions[1].GetComponent<UIButtonMessage>().functionName = "W";
      RingMenuOptions[1].GetComponent<UIButtonMessage>().trigger = UIButtonMessage.Trigger.OnRelease;
      
      NGUITools.AddWidgetCollider(RingMenuOptions[1]);
      
      RingMenuOptions[2] = NGUITools.AddChild(mPanel, mButtonPrefab);
      RingMenuOptions[2].GetComponentInChildren<UILabel>().text = "M";                  
      RingMenuOptions[2].AddComponent<UIButtonMessage>();
      RingMenuOptions[2].GetComponent<UIButtonMessage>().target = gameObject;
      RingMenuOptions[2].GetComponent<UIButtonMessage>().functionName = "M";
      NGUITools.AddWidgetCollider(RingMenuOptions[2]);
      
      RingMenuOptions[3] = NGUITools.AddChild(mPanel, mButtonPrefab);
      RingMenuOptions[3].GetComponentInChildren<UILabel>().text = "E";                  
      RingMenuOptions[3].AddComponent<UIButtonMessage>();
      RingMenuOptions[3].GetComponent<UIButtonMessage>().target = gameObject;
      RingMenuOptions[3].GetComponent<UIButtonMessage>().functionName = "E";
      NGUITools.AddWidgetCollider(RingMenuOptions[3]);

Clicking has been sorted but from there another bug follows.

This ring menu comes up when an object is clicked. And when an object is clicked, the newly instantiated ringmenu is automatically clicked simultaneously and closes the ring menu as written in the function.

How can I prevent that happening, so if the object is clicked once, the menu is not clicked while the object is being clicked, and does not get closed until the menu is clicked again?

It seems to be solved by double click trigger but that is only work half done because it is supposed to be a mobile game.

How does it work with touch?


Input.GetMouseButtonUp(0)

used this instead of buttondown to solve the problem, as this was not with NGUI but with raycast condition.
« Last Edit: August 29, 2013, 03:55:39 AM by dwjkim »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How do I position instantiated buttons prefab?
« Reply #4 on: August 29, 2013, 05:50:34 PM »
What are you doing here?

First of all, cache your GetComponent reference and re-use it. Why are you doing it repeatedly?

Second -- why are you using Input? NGUI has a built-in event system. Want to react to a button being clicked? Implement "void OnClick()" function on that button.

dwjkim

  • Guest
Re: How do I position instantiated buttons prefab?
« Reply #5 on: August 29, 2013, 09:32:12 PM »
Thanks I cached GetComponent so it does not get called repeatedly.

Now the next step of this is sending the parameters to the functions.

It is not so efficient to create a named function for every button.

I have read somewhere that the functionname also sends the gameobject. What is this gameobject it sends to the function? Is it the button?


ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: How do I position instantiated buttons prefab?
« Reply #6 on: August 30, 2013, 05:18:19 PM »
What named functions? NGUI event system triggers functions on the target game object -- OnClick for a click. If you want, you can alternatively subscribe to remote object's events instead using UIEventListener. That one will send a game object as the parameter. OnClick does not because it gets triggered on that object to begin with.