- Home /
Getting variables by their names?
Is that possible?
barDisplay = PlayerStats."VariableName"
or
barDisplay = PlayerStats.GetComponent("VariableName");
The variable is float type. I just want to know if that's possible to get them by their name given by string VariableName. Can someone give me a clue?
If it's needed here's the code
using UnityEngine;
using System.Collections;
public class PlayerBar : MonoBehaviour {
public float barDisplay; //current progress
public StatsScript PlayerStats;
public string VariableName;
public Texture2D emptyTex;
public Texture2D fullTex;
public Vector2 size = new Vector2 (200, 50);
public float posx;
public float posy;
public Color BarColor;
void OnGUI()
{
Vector2 position = transform.position;
GUI.BeginGroup(new Rect(Screen.width - posx,Screen.height - posy, size.x, size.y));
GUI.color = BarColor;
BarColor.a = 255;
GUI.DrawTexture(new Rect(0,0, size.x, size.y), emptyTex);
GUI.BeginGroup(new Rect(0,0, size.x * barDisplay, size.y));
GUI.DrawTexture(new Rect(0,0, size.x, size.y), fullTex);
GUI.EndGroup();
GUI.EndGroup();
}
void Update() {
//barDisplay = PlayerStats.GetComponent(VariableName);
}
}
The answer is reflection, as posted by @WilliamLeu. The question is why?
Strings are dangerous in terms of typos. There is no compile time error that will fix a spelling mistake. The error won't be apparent until runtime. And it can sometimes take hours of painful debugging to find.
Its almost always better to get the variable directly. The only time you shouldn't do that is when you can't. There are only a few circumstances where there is not a more efficient way.
If you post what effect you are trying to achieve (I can't tell from your script) we may be able to suggest a way that does not require reflection.
Answer by WilliamLeu · Jul 23, 2014 at 12:22 AM
Dude, can of worms. Definitely possible but if you're not advanced enough, chances are you're opening up a can of worms. Then again, I have nothing to loose so I'll share.
What you're looking for is called language reflection, or introspection, which is a programming language's ability to look at its own properties (and modify them). The full write-up of how to use reflection for C# can be found here, but I'll cut to the crux.
Here's an example of a MonoBehaviour using C# reflection to modify its name property without directly referencing its name property/variable...
using UnityEngine;
using System.Collections;
public class NameToBlorp : MonoBehaviour {
// Find the closest point on AB to a point
void Awake()
{
// Examining the name of all variables in a C# object
// In this case, we'll list the variable in this NameToBlorp
// class
System.Reflection.PropertyInfo [] rProps = this.GetType().GetProperties();
foreach(System.Reflection.PropertyInfo rp in rProps )
Debug.Log( rp.Name );
// Getting the info of a specific variable name.
// This gives us the ability to read/write it
System.Reflection.PropertyInfo propName = this.GetType().GetProperty( "name" );
if( propName != null )
{
// The PropertyInfo isn't the actual variable, just the "idea" of
// the variable existing in an object.
//
// It needs to be used in conjunction with the object...
// Equivalent of this.name = "blorp"
propName.SetValue(
this, // So we specify who owns the object
"blorp", // A C# object as the value, will be casted (if possible)
null
);
// And GetValue can be used in a similar fassion.
// Equivalent of Debug.log( "..." + this.name )
Debug.Log( "The name is " + propName.GetValue( this, null ) );
}
}
}
Obviously this is going to run slower because there's more stuff going on and should be avoided unless absolutely necessary. Just have the script know the type of the object and access it directly or through a class function instead (i.e PlayerStats.variable = bleh).
Ok i obviously dont understand half of the code but it will be usefull in future. Anyway thanks for help, now i will try putting this into the function that "converts" string, returns variable and i will be calling that with help of enum.
Answer by tanoshimi · Jul 22, 2014 at 10:03 PM
It's better to access a component by type but yes, you can access it by a string if necessary. It's all in the manual: http://docs.unity3d.com/ScriptReference/GameObject.GetComponent.html
Hmm when i'am calling: barDisplay = PlayerStats.GetComponent (VariableCode);
i get something like this error CS0029: Cannot implicitly convert type
UnityEngine.Component' to float
Answer by Kiwasi · Jul 23, 2014 at 12:41 AM
You could make a method on your PlayerStats class to convert a string into a float.
public float GetProgress(string attribute){
switch (attribute){
case "Strength":
return strength;
case "Wisdom":
return wisdom;
case default:
return 0;
}
}
Your answer
Follow this Question
Related Questions
HasComponent 4 Answers
GetComponent with variable script possible? 1 Answer
Script reference from another c# script 2 Answers
Creating an ordered list from a variable 1 Answer
Implicit type GetComponent call 0 Answers