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 this, like GetVariable(“String”);
Obviously that’s not a thing, but something similar just so I can use this 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

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 think about “lookup” the best way to implement this 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 this you need a list of serializable data classes. Just use a list of something 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 this 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 this 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 which 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 this should be faster than using reflection (If you use it multiple times to access the same variable). This 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 this plattform). Overall this 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.