• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
Question by magnusm · Oct 06, 2013 at 08:51 PM · javascriptvariablestringfind

Finding A Variable With A String Variable

Hey,

I am trying to find a variable in a script, using another variable (String). I will explain with an example:

 var a : AssetList;
 
 var code : String; // I enter in the specific ID here in the inspector (eg. A1, A2, D1)
 var fullCode : String;
 var mod : GameObject;
 
 function Start ()
 {
     a = gameObject.Find("Assets").GetComponent("AssetList");
     fullCode = "mod_" + code; // Combines with another string to form correct variable name
     
     mod = a.fullCode; // Here's the problem, I cannot use a String to find the variable in the AssetList
     
     var instanceMod : GameObject = Instantiate(mod, gameObject.transform.position, gameObject.transform.rotation); // Then it should spawn the desired mod
     Destroy(gameObject);
 }


Surely there is a way to acheive t$$anonymous$$s, like GetVariable("String"); Obviously that's not a t$$anonymous$$ng, but somet$$anonymous$$ng similar just so I can use t$$anonymous$$s String to find a variable.

I have heard of using Reflection. But apparently that is very slow, especially as it will be called several times when AI spawns.

Thanks for your time, Magnus

Comment

People who like this

0 Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robertbu · Oct 06, 2013 at 08:56 PM 0
Share

You cannot use a variable this way. Typical solutions to this kind of problem use dictionaries, arrays, or even 'switch' statements. I don't know which one to suggest since I don't know the nature of the problem you are trying to solve.

avatar image magnusm · Oct 06, 2013 at 09:10 PM 0
Share

So there is no simple way to do this?

Because I have just done:

     ...
             if (code == "A1")
         mod = a.mod_A1;
         
         if (code == "A2")
         mod = a.mod_A2;
 ...

And that work fine, but laborious as i have a whole load of mods to write if statements for :(

avatar image Eric5h5 · Oct 06, 2013 at 09:28 PM 0
Share

There's no reason to ever write code like that; as robertbu said, use dictionaries or arrays instead.

1 Reply

· Add your reply
  • Sort: 
avatar image
Best Answer

Answer by billykater · Oct 06, 2013 at 09:27 PM

You are right, Reflection the "only" way to access variables by name. The better question to ask here is why you need to access a variable by a string.

I suppose what you want to do is implement some kind of lookup that you can set from the inspector and have them differentiated by a name you attach to them.

1. Everytime you t$$anonymous$$nk about "lookup" the best way to implement t$$anonymous$$s is through the Dictionary class.

 import System.Collections.Generic;
 
 var dict : Dictionary.<String, GameObject> = new Dictionary.<String, GameObject>();
 
 function Start () 
 {
    dict.Add("a", gameObject);
 }
 
 function OnGUI()
 {
    GUILayout.Label(dict["a"].ToString());
 }

Unfortunately dictionaries aren't editable from the inspector and won't be saved through unity's serialization system. For t$$anonymous$$s you need a list of serializable data classes. Just use a list of somet$$anonymous$$ng like

 var entries : List.<Entry> = new List.<Entry>();
 
 @Serializable
 public class Entry
 {
     public var key : String;
     public var asset : GameObject;
 }

you can then loop over these entries in your awake / other initialization method and push all entries into the dictionary. To make t$$anonymous$$s easier to see in the inspector you can either add a custom inspector or a custom property drawer. If you want a more contained solution (Not having to implement t$$anonymous$$s everytime you want such a lookup) there are serializable dictionary implementations somewhere in the unify community wiki.

2. Expression Trees: I put "only" into quotes because there is another way than using reflection w$$anonymous$$ch is the Expression class located in System.Linq.Expressions. You can use Expression.Lambda, Expression.Field and Expression.Parameter to compile a function that will return the value of a variable given a string name. Theoretially t$$anonymous$$s should be faster than using reflection (If you use it multiple times to access the same variable). T$$anonymous$$s option is most likely not available on iOS (I haven't tried android either but it should be possible due to JIT compiler being available on t$$anonymous$$s plattform). Overall t$$anonymous$$s is an advanced construct and should only be used for cases where you can't really use the dictionary method above or are fully understanding what it is doing under the hood.

Comment
robertbu
TrickyHandz
Jamora
Bob-The-Zealot

People who like this

4 Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image magnusm · Oct 07, 2013 at 10:24 AM 0
Share

Thanks for the sweet response, helped a lot :)

Also to make it editable in the inspector I just added a variable in place of the "a", it works a treat:

 import System.Collections.Generic;
  
 var dict : Dictionary.<String, GameObject> = new Dictionary.<String, GameObject>();
 var a : AssetList;
 var code : String; // change this
 
 function Start () 
 {
     a = gameObject.Find("Assets").GetComponent("AssetList");
   
    dict.Add("A1", a.mod_A1);
    dict.Add("A2", a.mod_A2);
    dict.Add("A3", a.mod_A3);
    
    Instantiate(dict[code], gameObject.transform.position, gameObject.transform.rotation);
    Destroy(gameObject);
 }

How ever I do not understand what you mean by 'won't be saved through unity's serialization system', is that an issue?

avatar image billykater · Oct 07, 2013 at 04:41 PM 1
Share

Unity's serialization system If you have something like an int or a List. and you modify the value of it in the inspector(or code for that matter) unity automatically remembers its value (e.g. having var speed : float and setting it to 5 will be remembered even if you close unity and restart it). If you add any value to a dictionary and restart unity the content will be gone. Thats why you need to reinitialize the dictionary like you do in your Start method.

One advice for the future, move the whole dictionary to your AssetList component this way you won't need to modify two components if you every decide to add another variable.

Another thing I would do (advanced topic) is to not have hardcoded variables. This way you can extend how many entries there are without ever touching the code again. This is what will need all the additional stuff I was talking about (Serializable Dictionary and Custom Inspectors)

avatar image magnusm · Oct 08, 2013 at 01:43 PM 0
Share

Ah very good idea indeed, I will do that.

Awesome thanks, yeah I might look into custom inspectors. Look like they could be very useful for other things too.

Thanks again :)

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

17 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Separate objects from GameObject[] group 0 Answers

Variable in String 1 Answer

Access a GameObject through it's tag, using a string. 1 Answer

Best way to emulate Swift String Interpolation in UnityScript? 1 Answer

How to edit string? How to add text to string? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges