Author Topic: [Solved] EventDelegates: Couldn't bind to method  (Read 11551 times)

shaggydog

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
[Solved] EventDelegates: Couldn't bind to method
« on: December 10, 2013, 01:07:10 PM »
Hi,

I've been having difficulty working out how to set up UIButton via script.
I am think what you have to do to get Event Delegates to work is:

  1.                 UIButton button = myButtonGameObject.AddComponent<UIButton>();
  2.                 button.onClick.Add( new EventDelegate());
  3.                 button.onClick[button.onClick.Count-1].Set(myMonoBehaviourScript, stringMethodName);
  4.  
For example myMonoBehaviour script is set by dragging a script into the public Monobehavior myMonoBehaviourScript box in the inspector.
stringMethodName is set to the method name "Build"

  1.   class myMonoBehaviourScript : Monobehavior{
  2.  
  3. public void Build()
  4. {
  5. Debug.Log("Build Button Pressed")
  6. }
  7. }
  8.  

However, when i press the button when the game is running I get

ArgumentException: Couldn't bind to method 'Build'.

Does anyone know were I'm going wrong?

Thanks
« Last Edit: December 12, 2013, 05:35:28 AM by shaggydog »

UncleAcid

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 51
    • View Profile
Re: EventDelegates: Couldn't bind to method
« Reply #1 on: December 10, 2013, 01:41:58 PM »
You are overcomplicating it.

  1.     UIButton button = myButtonGameObject.AddComponent<UIButton>();
  2.     EventDelegate.Add(button.onClick, myMonoBehaviourScript.Build);
  3.  


shaggydog

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: EventDelegates: Couldn't bind to method
« Reply #2 on: December 10, 2013, 03:35:50 PM »
Thank you UncleAcid,

In doing that I have now got a compiler error relating to that line:

ArgumentException: Value does not fall within the expected range.

Do you have any idea what this means? As for as i can tell the .Add() function increase the size of the list anyway so it that shouldn't happen.

I've tried artificially increasing the size of the button.onClick list. But that doesn't help.


UncleAcid

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 51
    • View Profile
Re: EventDelegates: Couldn't bind to method
« Reply #3 on: December 10, 2013, 03:43:53 PM »
hmm. It works fine on my end.

Are you doing it your old way any where else in your scripts ?

Can you post your code (if it differs at all from mine) ? and all also the stack trace of the error (the full error message from the Unity Console) ?

shaggydog

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: EventDelegates: Couldn't bind to method
« Reply #4 on: December 10, 2013, 03:50:14 PM »
Here is the error

  1.  
  2. ArgumentException: Value does not fall within the expected range.
  3. InteractionButton.generateButton (UnityEngine.Transform InteractionGUITransform, Int32 GUIDepth, Vector3 coord) (at Assets/GameAssets/Scripts/InteractionGUI.cs:141)
  4. InteractionGUI.openMenu () (at Assets/GameAssets/Scripts/InteractionGUI.cs:37)
  5. InteractionGUI.Start () (at Assets/GameAssets/Scripts/InteractionGUI.cs:63)

Here is my full Code:
Interaction GUI Script
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4.  
  5. // Creates Radial Menu
  6. public class InteractionGUI : MonoBehaviour {
  7.  
  8.         public int numActions;
  9.         private float angle;
  10.         private float angleIncrement;
  11.         public float radius;
  12.         private Vector3 origin = new Vector3(0,0,0);
  13.         //private Vector3 iconCoordinates;
  14.         public InteractionButton[] interactionButton;
  15.         Transform thisTransform;
  16.  
  17.         public void openMenu()
  18.         {
  19.  
  20.  
  21.                 //Calculate Menu Locations
  22.                 angleIncrement = Mathf.Deg2Rad * (360/numActions);
  23.  
  24.                 int i = 0;
  25.                 while (i < interactionButton.Length)
  26.                 {
  27.  
  28.                         Vector3 iconCoordinates;
  29.                         iconCoordinates.x = radius * Mathf.Sin( angleIncrement*i);
  30.                         iconCoordinates.y = radius * Mathf.Cos( angleIncrement*i);
  31.                         iconCoordinates.z = 0;
  32.                         Debug.Log(thisTransform + " " +  iconCoordinates + " " + i);
  33.                         interactionButton[i].generateButton(thisTransform, 2, iconCoordinates); // This is line 37
  34.                         i++;
  35.                 }
  36.                 //Build Menu
  37.  
  38.         }
  39.  
  40.  
  41.  
  42.         // Closes Menu
  43.         public void destroyMenu()
  44.         {
  45.  
  46.         }
  47.  
  48.  
  49.         void Awake()
  50.         {
  51.                 // Get gameManager
  52.                 thisTransform = this.transform;
  53.         }
  54.  
  55.         // Use this for initialization
  56.         void Start () {
  57.                 openMenu(); //This is line 63
  58.         }
  59.        
  60.         // Update is called once per frame
  61.         void Update () {
  62.        
  63.         }
  64. }
  65.  
  66. [System.Serializable]
  67. public class InteractionButton
  68. {
  69.  
  70.         private GameObject gameManagerObject;
  71.         private GameManager gameManager;
  72.  
  73.         //ICON
  74.         [HideInInspector]
  75.         public GameObject iconButton;
  76.         public string buttonName;
  77.         public string buttonIconName;
  78.         public int iconSize;
  79.         public Color32 iconColor;
  80.         public CharacterInputInterface TargetInputInterfaceScript;
  81.         public string methodName;
  82.  
  83.        
  84.         //BGICON + BUTTON
  85.         private GameObject iconBackground;
  86.         public string BGName = "ButtonAndBackground";
  87.         public string buttonBackgroundName = "itemNR";
  88.         public int BGiconSize = 64;
  89.  
  90.  
  91.  
  92.         public void generateButton(Transform InteractionGUITransform, int GUIDepth, Vector3 coord)
  93.         {
  94.                 Debug.Log(InteractionGUITransform + " " +  GUIDepth + " " + coord);
  95.                 // Get Gamemanger
  96.                 gameManagerObject = GameObject.Find("01_GameManager");
  97.                 gameManager = gameManagerObject.GetComponent<GameManager>();
  98.  
  99.                 // sprite Button
  100.                 iconButton = new GameObject(buttonName);
  101.                 iconButton.layer = 23;
  102.                 iconButton.transform.parent = InteractionGUITransform;
  103.                 iconButton.transform.localPosition = coord;
  104.  
  105.                 iconButton.AddComponent("UISprite");
  106.                 UISprite spriteRef = iconButton.GetComponent<UISprite>();
  107.                 //spriteRef.color = iconColor;
  108.                 spriteRef.atlas = gameManager.gameAtlas;
  109.                 spriteRef.spriteName = buttonIconName;
  110.                 spriteRef.depth = GUIDepth;
  111.                 spriteRef.width = iconSize;
  112.                 spriteRef.height = iconSize;
  113.                 spriteRef.GetAtlasSprite();
  114.                 spriteRef.color = iconColor;
  115.                
  116.                
  117.                 iconBackground = new GameObject(buttonBackgroundName);
  118.                 iconBackground.layer = 23;
  119.                 iconBackground.transform.parent = iconButton.transform;
  120.                 iconBackground.AddComponent<BoxCollider>();
  121.                 iconBackground.AddComponent("UISprite");
  122.                 iconBackground.transform.localPosition = new Vector3(0,0,0);
  123.  
  124.                 UISprite spriteBGRef = iconBackground.GetComponent<UISprite>();
  125.                 spriteBGRef.atlas = gameManager.gameAtlas;
  126.                 spriteBGRef.spriteName = buttonBackgroundName;
  127.                 spriteBGRef.GetAtlasSprite();
  128.                 spriteBGRef.depth = GUIDepth-1;
  129.                 spriteBGRef.width = BGiconSize;
  130.                 spriteBGRef.height = BGiconSize;
  131.                 spriteBGRef.autoResizeBoxCollider = true;
  132.                 spriteBGRef.ResizeCollider();
  133.  
  134.                 UIButton button = iconBackground.AddComponent<UIButton>();
  135.                 EventDelegate.Add(button.onClick, TargetInputInterfaceScript.Build, false); // This is line 141 - removing this line gets rid of the bug. I.E. GUI draws but clicking on it does nothing
  136.  
  137.  
  138.         }
  139.  
  140. }
  141.  

TargetInputInterfaceScript
  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class CharacterInputInterface : MonoBehaviour {
  5.  
  6.         // Use this for initialization
  7.         void Start () {
  8.        
  9.         }
  10.        
  11.         // Update is called once per frame
  12.         void Update () {
  13.        
  14.         }
  15.        
  16.         public void Build(){
  17.                 Debug.LogWarning("Build Called");
  18.         }
  19. }
  20.  
  21.  

And thank you for the help. Its greatly appreciated
« Last Edit: December 10, 2013, 03:56:36 PM by shaggydog »

UncleAcid

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 51
    • View Profile
Re: EventDelegates: Couldn't bind to method
« Reply #5 on: December 10, 2013, 04:08:58 PM »
That code works fine here, I'm going to assume the problem is caused some where else in your code.

Are you using EventDelegate anywhere else ?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: EventDelegates: Couldn't bind to method
« Reply #6 on: December 10, 2013, 09:36:35 PM »
The error clearly points to your own code there -- InteractionButton.generateButton, line 141.

Nicki

  • Global Moderator
  • Hero Member
  • *****
  • Thank You
  • -Given: 33
  • -Receive: 141
  • Posts: 1,768
    • View Profile
Re: EventDelegates: Couldn't bind to method
« Reply #7 on: December 11, 2013, 04:24:16 AM »
TargetInputInterfaceScript probably doesn't have a reference to an instance, so when you try to grab the method it goes bonkers.

shaggydog

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 5
    • View Profile
Re: EventDelegates: Couldn't bind to method
« Reply #8 on: December 12, 2013, 05:35:05 AM »
Thank you all for your help!

Nicki was indeed correct, I had not set the TargetInputInterfaceScript reference in the inspector for all instances of this serilisable class.

The compilers error "ArgumentException: Value does not fall within the expected range" Had thrown me as I would have expected a null reference exception for mistake and had assumed it was due to the way i was trying to use the EventDelegates list;

Again big thanks to UncleAcid for this little gem:
  1. EventDelegate.Add(button.onClick, myMonoBehaviourScript.Build);
- the correct way to create the event delegate.

And Thanks to Nicki for being able to decipher the enigmatic compiler error.