string and variables to reference a variable

Hey everyone,

Had a really hard time trying to find any info on using a string and getting the variable value of it.


var xLoc:float = 3;
var zLoc:float = 2;

var enemy_3_2:float = 4;

var currentEnemies = SOMETHINGHERE(“enemy_”+xLoc+“_”+zLoc);

Debug.Log(currentEnemies); -----> trying to get 4.


In flash it would be this[“enemy_”+xLoc+“_”+zLoc]… how would I get this in Unity?

Thank you so much!

Are you trying to fetch an array of the “enemies” in the scene? and therefore their positions?

Nope I am simply trying to access the float variable “enemy_3_2” …by combining strings and variables to get it. Any thoughts?

PlayerPrefs.SetString(“thisString” + thisInVar.ToString(), someValue)
var stringValue : String = PlayerPrefs.GetString(“thisString”);

:?

Have you thought of useing reflection?

public object GetPropValue( object source, string propName )
 {
     return src.GetType( ).GetProperty( propName ).GetValue( source, null );
 }

Make a two dimensional array and access the data that way. values[2][3] or values[xLoc][zLoc]

I appreciate it, but none of these work the way I need to use them. This is such an easy thing to do in flash, there must be something that being missed here. There’s no way this can be this tricky.

This is common in Actionscript, because most classes are what Flash calls ‘dynamic’. What it really means is that the prototype that describes the interface of the object is a hashtable, and it hashes out the property from a string name.

Unity does NOT have this feature.

Mono/.net has reflection though (which actionscript lacks), which you can use to access members by name. ‘pislar’ showed a simple example of this.

I’ve written actionscript and I liked this feature and I wrote this function (which is incomplete at this time, lacks support for methods as of yet) to accomplish the task:

NOTE - you don’t get to call it on the object like obj[“myprop”], instead you have to call it like GetValue(obj, “myprop”);

Though I guess you could use extension methods and be able to say: obj.GetValue(“myprop”);

        public static object GetValue(this object obj, string sprop, params object[] args)
        {
            if (obj == null) return null;

            try
            {
                var tp = obj.GetType();
                var members = tp.GetMember(sprop);
                if (members == null || members.Length == 0) return null;

                foreach (var member in members)
                {
                    switch (member.MemberType)
                    {
                        case System.Reflection.MemberTypes.Field :
                            var field = member as System.Reflection.FieldInfo;
                            return field.GetValue(obj);

                        case System.Reflection.MemberTypes.Property:
                            var prop = member as System.Reflection.PropertyInfo;
                            if (prop.CanRead  prop.GetIndexParameters().Length == args.Length)
                            {
                                if (args.Length > 0)
                                {
                                    //TODO - check types... but need to allow downcasting... how?
                                    return prop.GetValue(obj, args);
                                }
                                else
                                {
                                    return prop.GetValue(obj, null);
                                }
                            }
                            break;

                        case System.Reflection.MemberTypes.Method:
                            var meth = member as System.Reflection.MethodInfo;
                            if (meth.GetParameters().Length == args.Length)
                            {
                                if (args.Length > 0)
                                {
                                    //TODO - check types... but need to allow downcasting... how?
                                    return meth.Invoke(obj, args);
                                }
                                else
                                {
                                    return meth.Invoke(obj, null);
                                }
                            }
                            break;
                    }
                }
            }
            catch
            {

            }

            return null;
        }

Thank you Lord. That’s good to know at least. This is a bit over my head so I’m going to just use a bulky algorithm to sort it all out. Thank you!

It’s just so funny that I can do the same thing with a game object:

var currentRoom = gameObject.Find(“zdun_”+xLoc+“_”+zLoc);

but there is no version for a variable. Oh well.

Please please think about the children :slight_smile:

There is a cost for using reflection, if you use it often it may make things perform poorly.

Why not use a Dictionary or HashSet. This will allow you to use your “variables” as you posted above for the key and get the value.

gameobjects aren’t variables.

There is already a table of all the gameobjects out there. There isn’t tables of all the variables.

Unity/Mono uses Reflection to do this stuff. It’s just the interface is far more complicated than that of actionscript. It’s also far more powerful than actionscript.

Here’s a method for ‘setting’:

        public static bool SetValue(this object obj, string sprop, object value)
        {
            if(obj == null) return false;

            try
            {
                var tp = obj.GetType();

                var members = tp.GetMember(sprop);
                if(members == null || members.Length == 0) return false;

                Type vtp = (value != null) ? value.GetType() : null;

                //first strict test
                foreach(var member in members)
                {
                    switch(member.MemberType)
                    {
                        case System.Reflection.MemberTypes.Field:
                            var field = member as System.Reflection.FieldInfo;
                            if(vtp == null || field.FieldType == vtp)
                            {
                                field.SetValue(obj, value);
                                return true;
                            }
                            break;
                        case System.Reflection.MemberTypes.Property:
                            var prop = member as System.Reflection.PropertyInfo;
                            if(prop.CanWrite  (vtp == null || prop.PropertyType == vtp)  prop.GetIndexParameters().Length == 0)
                            {
                                prop.SetValue(obj, value, null);
                                return true;
                            }
                            break;
                        case System.Reflection.MemberTypes.Method:
                            var meth = member as System.Reflection.MethodInfo;
                            var args = meth.GetParameters();
                            if(args.Length == 1  (vtp == null || args[0].ParameterType == vtp))
                            {
                                meth.Invoke(obj, new object[] { value });
                                return true;
                            }
                            break;
                    }
                }

                //now weak test
                foreach(var member in members)
                {
                    switch(member.MemberType)
                    {
                        case System.Reflection.MemberTypes.Field:
                            var field = member as System.Reflection.FieldInfo;
                            field.SetValue(obj, value);
                            return true;
                        case System.Reflection.MemberTypes.Property:
                            var prop = member as System.Reflection.PropertyInfo;
                            if(prop.CanWrite)
                            {
                                prop.SetValue(obj, value, null);
                                return true;
                            }
                            break;
                        case System.Reflection.MemberTypes.Method:
                            var meth = member as System.Reflection.MethodInfo;
                            var args = meth.GetParameters();
                            if(args.Length == 1)
                            {
                                meth.Invoke(obj, new object[] { value });
                                return true;
                            }
                            break;
                    }
                }
            }
            catch
            {

            }

            return false;
        }

note, the two functions are just gave you are intended to just be utility methods. You just need to have a static member class with this in it, and you’re done. (noting I wrote them in C#). The algorithm making up its guts is kind of inconsequential to you.

Anyways, here they are supplied for anyone else who may want them.

If this comment was pointed at me, let me help you out a little. The OP was using variables(xLoc/zLoc) to concat a string and return a value from a lookup table, those are the variables i was referring to and i’m saddened i have to explain that. This same functionality can be recreated without reflection and without taking most likely a huge hit in performance.

If is going to become an argument, please send me a PM.

MSDN Blog about avoid pitfalls in reflection.

Stack Overflow discussion

nope, wasn’t directed at you, I was responding to OP saying:

I know what the OP was attempting, I used to write actionscript, and offered him functions to accomplish the same functionality using reflection

and I know reflection pretty well… as well as its downsides

And hashtables/dictionaries are an alternative. But it doesn’t help OP do what they want to do exactly, it’s an alternative method that requires all dynamically accessed values to be pre-setup for such access. Which is the ‘proper’ way to do things. But actionscript isn’t known for doing things the proper way.

I don’t even know how the heck you thought what I said was directed at you.

I apologize for my mistake.