Can Reflection and Invocation be used in WebPlayer?

Howdy team,

I’ve got a pretty cool dialog flow system that I wrote for a project. To keep things open and flexible, I used reflection throughout it. Now, the client wants to see if things will work in the WebPlayer - so I load it up, and immediately the dialog flow system craps out with this error:

Did a little research and it sounds like this should work, based on this line from Unity’s documentation:

I did indeed write the methods myself, and they are not private classes… at least I don’t think so. Maybe you guys can give some advice. This here is the block of code that it’s dying on:

	var newDialogObj = new object();
	getDialogScriptForDialog<System.Type>(thisDialog, out newDialogObj);
			
	Type type = newDialogObj.GetType();
	var method = type.GetMethod(methodString);
	method.Invoke(newDialogObj, inObj); // This line specifically is where it dies

Any help or pointers would be very appreciated - thanks in advance!

Bump.

Also, doing some research into it, it looks like it’s not specifically the .Invoke that is causing the failure - it’s actually the parameters. I experimented by doing a .SendMessage into an object instead, and while that worked - it hated the idea of figuring out what the parameter types were. Which means the following code works fine on all platforms, but will not work on WebPlayer:

void sendMessageToObj(GameObject target, string Message, object variable)
{
  target.SendMessage(Message, variable);
}

So the question is - how do you make the above code work on WebPlayer? What needs to be modified so that the conversion between ‘object’ and its correct Type will occur? I’ve tried the following but it doesn’t work:

  target.SendMessage(Message, (typeof(variable.GetType()))variable);

You’re doing it wrong.

1 Like

Reference this MSDN page MethodBase.Invoke Method (System.Reflection) | Microsoft Learn

If you’re trying to invoke on a method info in which you don’t know the parameter list type you might be able to use reflection again to discover this at runtime but that just seems like bad design.

Edit: The first arg is not the Type instance. You need to give it an instance of the Type that you peeled the method info from. Otherwise it needs to be a static method. Essentially the invoke on the MethodInfo needs an instance of the object you’re trying to invoke the method from.

Thank you for the helpful response (unlike the one above yours - of course I know I’m doing it wrong why do you think I’m asking for help? ;)). I’m still learning my way through Reflection so your help is very appreciated.

I see what you are saying, makes sense! Okay. Though I’m not entirely sure how to create an object when the type is acquired from the parameter. I imagine it would be something like (and this is pseudo code):

ObjectType(get object type from obj) newObj = parameter convert to object type

That is my guess at least… could you please supply me with an example however that would show how to create an object of a particular type when the type is acquired at runtime and not known in advance?

If you have a Type instance of an object but you want to create an instance of that object you should use this:

http://msdn.microsoft.com/en-us/library/vstudio/system.activator.createinstance

Instantiating it via reflection. However, all of this is a VERY expensive operation. Be wary of reflection as it can hinder performance.

Edit: As a warning Reflection changes a bit from 3.5 .Net to 4.5 .Net. So watch out as Unity is 3.5

Glader,

Thank you for the continued assistance and pointers, it’s very appreciated!

So to reduce the use of reflection, would it perhaps be best to have a series of functions for different parameter types? Something like this (pseudo code style again)

void doStringFunction(dialogtype, stringtosend)
{
   Dialog = getDialogWithReflection
   Method = getMethod
   Method.invoke(object, stringtosend);
}

void doIntFunction(dialogtype, inttosend)
{
   Dialog = getDialogWithReflection
   Method = getMethod
   Method.invoke(object, inttosend);
}

Etc. For each parameter type used

That then would reduce one use of reflection. Would that be a more appropriate direction?

I think what @KheltonHeadley actually meant wasn’t that there’s something wrong with how you’re using reflection, but that attempting to solve your problem by using reflection in that particular way is not optimal.

The following image kind of summarizes what comes to my mind when I look at your current implementation:

1609542--97705--$pipemaze.jpg

I think you’re pushing openness and flexibility to the point of breaking, and you’re actually fighting against the .NET framework’s type system instead of leveraging it to your advantage.

I’m not sure what your system is supposed to do exactly, but here’s a few ideas for you to consider:

Instead of calling a method by using reflection and the method’s name, why not create an interface named IDialogue that implements the methods that make sense for your usecase? e.g:

interface IDialogue
{
  void Show(Dictionary<string, object> parameters);
  bool IsShowing();
  IDialogue GetNextDialogue();
}

And instead of trying to figure out what parameters a method takes at runtime, stuff them all in the parameters dictionary shown in the example above and let each class that implement IDialogue extract the parameters it needs from that dictionary.

Then you can use reflection to get all the types that implement IDialogue in your app (see this Stack Exchange question), but I think that even that can be avoided entirely, although there’s no way to know for sure without knowing the specifics of your requirements.

I could be wrong of course and it could be that your requirements can only be met with the way you’re trying to get to work, but I think that’s unlikely.

Anyways, just my two cents. Make of it what you will.

Good luck.

Shaderop,

That’s actually a pretty cool idea, I hadn’t thought of that! In my case the use of reflection still looks (I think? read below…) like the best way to achieve the result that’s needed for this project, however your suggestion above regarding the use of an Interface actually answers some lingering questions in my mind. For one, I had seen people use Reflection to create extraordinarily generic enemies and items, which seemed great - however when I learned it’s also not optimal, I kept wondering what could have been done to make those enemies and objects better, as generic enemies / objects do seem like a great way to implement very flexible setups.

Actually in my case, the primary reason I used Reflection, was because I had integrated a main DialogScript object class, which is the master class for all parent Dialogs. So in my hierarchy, it looks a little like this:

OkayDialog
LoginDialog
SettingsDialog

Etc., and each of those is a child of DialogScript. I had integrated singletons for all of those also, and needed a quick way to access each Singleton. Rather than putting a singleton on each Child Class, I had wanted it in the DialogScript class, which resulted in a class definition like the following:

public class DialogScript<T> : MonoBehaviour

At that point, it seemed like using reflection to access the methods was absolutely required, otherwise there was no way to access the objects due to the generic. So as a result, to pass a method into one of the singletons, I had to create a function that would get the singleton, determine its class, get the method, then invoke into it. The process then worked like this:

// This sends the request to call a method on an object
  object[] vars = new object[]{InputTagManager.inputTags.None};
  invokeDialogMethod(thisPopup, "TransitionDialogIn", vars);

// Then the invokeDialogMethod does the work...
	private static void invokeDialogMethod(MainBoomUI.uiDialogs thisDialog, string methodString, object[] inObj)
	{
		if(thisDialog == MainBoomUI.uiDialogs.None)
			return;

		try
		{
			var newDialogObj = new object();

                        // getDialogScriptForDialog is just a switch/case statement that sends back the proper Singleton for the thisDialog object pushed in
			getDialogScriptForDialog<System.Type>(thisDialog, out newDialogObj);
					
			Type type = newDialogObj.GetType();
			var method = type.GetMethod(methodString);

			method.Invoke(newDialogObj, inObj);
		}
		catch
		{
			Debug.LogError("invokeDialogMethod failed when performing the string " + methodString + " on dialog " + thisDialog + " with the variable " + inObj[0] + ". This is completely fatal. Best call the digital coroner, IE, Dave.");
		}
	}

Again, I add that I’m somewhat new to using Reflection, so I’m open to any suggestions I can get, even if I’m using Reflection entirely wrong. (It’s working well for this project, but I’d love to learn better uses of it for future projects).

I’m still a bit sketchy on the structure of your code, but here it goes:

If the only reason you’re doing this is to stuff all the dialogue classes in a single GameObject that acts like a singleton, why not do it like this: Have a GameObject named, say, “DialogeContainer,” and have a script on it that enforces the singleton behavior, i.e. ensures that only one instance loaded and all that jazz.

And then on that same object have several MonoBehaviours, one for each of your dialogue classes. Use the singleton script to get a reference to that gameobject, and use GetComponent method to grab whichever DialogueScript you need.

Reflection is a valid solution to some problems, but such problems should be few and far in between. C and C++ never had anything even remotely resembling run-time reflection, and yet programmers continue to write code in those languages just fine.