Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Getting a varible using a string?

Discussion in 'Scripting' started by UnityUser9860, Jul 26, 2016.

  1. UnityUser9860

    UnityUser9860

    Joined:
    Dec 8, 2015
    Posts:
    179
    hey

    ive got an issue in witch I want to get a variable using a string as the varibles are all the same exept a number at the end and I want to get a specific variable by getcomponent<script>().string_that_varibles_start_in+specific_number;


    but I cant get the variable with a string how would I do this?
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    sounds a lot like the variables in question should be in some sort of collection, so instead of

    Code (csharp):
    1.  
    2. // not real code, but to give the idea
    3. [type] var1 = something;
    4. [type] var2 = somethingElse;
    5. [type] var3 = somethingElseAgain;
    6.  
    you use

    Code (csharp):
    1.  
    2. // not real code, but to give the idea
    3. List<type> vars = new List<type>();
    4. var.Add(something);
    5. var.Add(somethingElse);
    6. var.Add(somethingElseAgain);
    7.  
    and access the, using var[0], var[1], var[2]

    http://unity3d.com/learn/tutorials/...ripting/lists-and-dictionaries?playlist=17117
     
  3. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    since you mentioned you are accessing it with a number, why not use a Array or List and access it via index.
    But if you really want to access it via a string name Dictionary<string, mytype> might be to your liking.
     
  4. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,766
    You can use System.Reflection for this.
    You search all public members of a class for the variable with the name you're looking for.

    Code (csharp):
    1.  
    2. using System.Reflection;
    3.  
    4. Type script = GetComponent<Script>.GetType();
    5.  
    6.   FieldInfo[] allPublicVariablesArray = script.GetFields(); //Get all public variables contained in a script
    7.  
    8.   for(int i = 0; i < allPublicVariablesArray.Length; i++)
    9.        {
    10.          FieldInfo publicVariable = allPublicVariablesArray[i];
    11.          string variableName = publicVariable.Name;
    12.    
    13.          if (variableName == "the variable name")
    14.           {
    15.                object value = publicVariable.GetValue(...)
    16.                publicVariable.SetValue(...); //Assign a value to it
    17.           }
    18. }
    19.  
    20.  
    I think this is what you're asking.
    This is also probably very slow to use System.Reflection
     
    Last edited: Jul 26, 2016
  5. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    reflection seems like overkill when what he wants sounds like it could be achieved with a collection type that takes a key or index
     
  6. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,766
    Yeah but if used wisely it could be made very generic. I use it for the save and loading game process. No need to create a special list.
    I guess it really depends on what the OP is trying to do with this. The system.reflection is probably not the best approach to take for most situations like you mentioned.
     
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Looks like all of the options are already well covered.

    In most cases there is no need to drop to reflection. Structuring your program in an smart way can often avoid the need for reflection. However its a powerful tool to have when there are no other options. Or when you are doing meta programming.
     
    ArachnidAnimal and image28 like this.
  8. UnityUser9860

    UnityUser9860

    Joined:
    Dec 8, 2015
    Posts:
    179
    ok thx guys sorry for slow response my wifis been down for 2 days but thx a lot for all the replys I will see what I can do with this info
     
  9. UnityUser9860

    UnityUser9860

    Joined:
    Dec 8, 2015
    Posts:
    179
    Hey @TTTTTa ive tried your method but ive modified the script a bit as I was getting errors anyway I'm getting one error I'm not sure how to fix this is my script:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.Networking;
    4. using UnityEngine.UI;
    5. using System.Reflection;
    6.  
    7. public class inventory : NetworkBehaviour {
    8.     public int itemid = 1;
    9.     public GameObject button;
    10.     public Material mati;
    11.     public int i;
    12.  
    13.  
    14.  
    15.  
    16.  
    17.  
    18.  
    19.  
    20.  
    21.  
    22.     // Use this for initialization
    23.     void Start () {
    24.        
    25.     }
    26.    
    27.  
    28.     public void change (int itemID) {
    29.         if (button.GetComponent<slide>().itemid1 == 1){
    30.         itemid = itemID;
    31.         }if (button.GetComponent<slide>().itemid1 == 2){
    32.             itemid = itemID + 9;
    33.         }if (button.GetComponent<slide>().itemid1 == 3){
    34.             itemid = itemID + 18;
    35.         }
    36.  
    37.  
    38.         //=======================
    39.         var script = GetComponent<slide>();
    40.  
    41.  
    42.  
    43.  
    44.  
    45.         FieldInfo[] allPublicVariablesArray = script.GetType().GetFields(); //Get all public variables contained in a script
    46.  
    47.  
    48.  
    49.  
    50.  
    51.         for(i = 0; i < allPublicVariablesArray.Length; i++)
    52.  
    53.  
    54.         {
    55.  
    56.  
    57.             FieldInfo publicVariable = allPublicVariablesArray[i];
    58.  
    59.  
    60.             var variableName = publicVariable.Name;
    61.  
    62.  
    63.  
    64.  
    65.  
    66.             if (variableName == "mat"+itemid.ToString())
    67.  
    68.  
    69.             {
    70.  
    71.                 var finddis = "mat" + itemid.ToString ();
    72.                 var value = publicVariable.GetValue (finddis) as Material;
    73.                 mati = value;
    74.  
    75.  
    76.  
    77.  
    78.             }//if
    79.  
    80.  
    81.         }//for
    82.  
    83.  
    84.         //=========
    85.         GameObject.Find ("BlockDispImage").GetComponent<Image>().material = mati;
    86.  
    87.  
    88.     }//function
    89.  
    90.  
    91.  
    92.  
    93.  
    94. }//class
    95.  
    and I get the error of

    Parameter name: objArgumentException: Field mat2 defined on type slide is not a field on the target object which is of type System.String.


    please help thx!
     
  10. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,766
    As others have pointed out, my method might not be the best method to use. You should try to use the other methods other people have posted about here. I only posted it because I didn't know what you were trying to do. But now, looking at the code, I don't think using my method is the best approach.
    What is "slide"? Is that the name of a script?
    You don't need "ToString()" here because "mat"+itemid is already a string.

    Using system.reflection throws Exceptions during certain situations
    https://msdn.microsoft.com/en-us/library/system.reflection.fieldinfo.getvalue(v=vs.110).aspx

    But again looking at the code and trying to determine what you're doing, I don't think my method should be used.