Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Reference another script members in editor (as in uGUI event handlers)

Discussion in 'Scripting' started by Javier-Maria, Jun 25, 2015.

  1. Javier-Maria

    Javier-Maria

    Joined:
    Mar 16, 2015
    Posts:
    6
    In order to better explain what I am trying to do, please check the following images that I'll reference ahead.

    reference_1.png reference_2.png

    Some background: I am trying to create a component that will poll against a public attribute in another component and do stuff when it changes. I am going to use this to check a fairly large number of variables from several scripts, so avoiding specific implementation for each of those scripts (inheritance already taken into account) could save me hours of work.

    In order to achieve this, I thought I could recreate the Event Handler "picker" from uGUI components (as seen in the images), because it looks exactly like what I need. Unfortunately, I lack the technical knowledge to make it happen. Is it possible to create a similar picker in one of my scripts? If so, how? Any help will be greatly appreciated, even if it confirms that it cannot be done.
     
    Last edited: Jun 25, 2015
  2. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,209
    script a:

    Code (csharp):
    1. int current = 0;
    2.  
    3. void Update() {
    4.    if (otherObject.GetComponant<OtherScript>().testAttribute != current) {
    5.       current = otherObject.GetComponant<OtherScript>().testAttribute;
    6.       AttributeChange();
    7.    }
    8. }
    9.  
    10. void AttributeChange () {
    11.    //do stuff
    12. }
    something like this? You can of course use events. and reading up on scripting EventSystems is REALLY useful in unity. I'm not clear what it is you ultimately want to do though. Just looking at another variable is pretty easy stuff..? You want this to be an event so it is not constantly being checked?

    if you put 3 into that variable box for the button I think it well set the variable to 3 when the button is clicked. I personally would script this like this:
    Code (csharp):
    1.  
    2. void Start () {
    3.    testButton.onClick.AddListener(() => { TestButtonClicked(); });  
    4. }
    5.  
    6. public void TestButtonClicked () {
    7.    //do stuff
    8. }
    9.  
    the TestButtonClicked will be called everytime the button is clicked. you can mix and match, add in states, etc.
     
  3. Javier-Maria

    Javier-Maria

    Joined:
    Mar 16, 2015
    Posts:
    6
    Nope, I must have expressed myself poorly. I obviously know how to access another scripts member. The issue with your solution is that I need to write specifically otherScript.testAttribute, and I need to know the type OtherScript and the name of the testAttribute.

    In my application I am going to be checking against OtherScript1.attribute, OtherScript2.anotherAttribute, OtherScript3.attribute25, ... OtherScript2000.attributeABC and so on. I would have to write 2000 different implementations of the code you just posted (exactly what I am trying to avoid), where the only change would be the name of the other class and the name of the attribute.

    I am looking for a solution like this, that would allow me to use the exact same component for all 2000 cases.

    Code (CSharp):
    1. public class FloatListener : MonoBehaviour
    2. {
    3.     // This is a reference to an attribute that happens to be a float in some other class. It is certainly NOT a float
    4.     public /* attribute reference type */ attributeToCheck;
    5.  
    6.     private float oldValue;
    7.  
    8.     void Update()
    9.     {
    10.         if (attributeToCheck.value != oldValue)
    11.         {
    12.             DoStuff();
    13.         }
    14.     }
    15.  
    16.     void DoStuff()
    17.     {
    18.         // operate with the new value
    19.         oldValue = attributeToCheck.value;
    20.     }
    21. }
     
  4. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,209
    Well I'm not very fancy, I'll put that up front.
    You could set a Dictionary<string, float[]> in a manager class that could record all the objects its interacted with so far by storing their name as a key in the dictionary. Then keep track of whatever number of attribute you are checking against in an array separate for each Dict entry. You could even have Dictionary<string, Dictionary<Attribute, float>>. I get the feeling I still don't fully understand the question though.

    You want a manager class to pay attention to thousands of other object oriented scripts? does the total number of scripts fluctuate? can you search for them all at the start, stuff em into an array and have the manager check against them all. can they each report to the manager themselves when they've changed making his job easier?
     
  5. Javier-Maria

    Javier-Maria

    Joined:
    Mar 16, 2015
    Posts:
    6
    Thanks for your input. While your idea does help (it is pretty much how my data manager works), it is not what I am looking for.

    The most important part of my problem though is how to replicate the editor thing that allows you to pick a member from any of the components attached to a gameObject, just like the one in the images I attached to the original post. I've reworded the question to reflect this.
     
  6. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    Javier-Maria likes this.
  7. malkere

    malkere

    Joined:
    Dec 6, 2013
    Posts:
    1,209
    does types sounds like it will help? can grab all the componants on transform that are type Weapon. or if they are inherited from Item you can assign each a variable to let the checked know they are Weapon or Armor and then cast them (Weapon)newItem so you can now treat them like Weapons and get Weapon.attribute1

    you can check against all objects in a scene, on a specific object, or on the current object etc. you don't have to know their name if you know their location or type. you could broadcast and make everything able to respond respond (not recommended to be used frequently from my understanding)

    I don't seem to be able to understand what it is your actually trying to do though without understanding the project, sorry.
     
  8. Javier-Maria

    Javier-Maria

    Joined:
    Mar 16, 2015
    Posts:
    6
    I think reflection and a custom editor are the way to go. If I make any advancements I'll post them here.