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;
}
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.
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.