- Home /
Calling non applied scripts
Hi, i added a system similar to source engine's console system, and i faced a difficult problem, i can't seem to be able to call a function in a script that isn't applied to any object in the game. What i want: I type "exec test_explode" in a textfield, hit enter, and it will split the textfield String, into a string array, in which i use temp[1](=the "test_explode") as a script to execute. So, what i want is a way to gather this String, change it into a type so i can execute a static function in that respective script file. (javascript files)
Example: the string sent is "test_explode", it will do test_explode.Execute();, if it is "blop" it will do blop.Execute();. It seems easy to do, but this isn't. As the user will be able to create various files and names, so i can't do if (scriptname == "blop") Execute..... As the user will be able to name the script as he wants and send it with a string, lets say: "exec blopayoierthiolphac_nacder_4245", would end up like blopayoierthiolphac_nacder_4245.Execute();
Here is the codes i started with, but these didn't work.
else if (temp[0] == 'exec')
{
var script = null;
(Object.GetComponent(script) as Thing).Execute();
//ExecuteScript(temp[1]);
//temp[1].Execute();
}
I tried creating a new function on the player script (as the code above is a part of the player main script) but it failed, as it was just repeating over and over function to function and carrying the same numbers around, if you know what i mean...
Any help on this? I searched everywhere but couldn't find anything really helpful... (An idea would be to create an empty entity and adding the component to it and then executing a function on the new entity's component... but i'm not sure if it would work, as i can directly call functions from scrits not added as components anywhere)
How are the users going to add scripts? Is this a plugin?
Answer by Loius · May 01, 2013 at 03:23 AM
You can use reflection to get a class and method by name - so your executable classes would have a function "Execute" which you'd call on them (to keep the user from arbitrarily executing any code they want).
http://stackoverflow.com/questions/1044455/c-sharp-reflection-how-to-get-class-reference-from-string
I don't know my string or [] functions by heart but the words will at least lead you to the right place to find them:
using System.Reflection;
...
public void Exa$$anonymous$$eCommand(string input) {
if ( input.Substring(1,4)=="exec" ) {
string command = input.Substring(input,5);
string[] args = command.Split(' ');
Type t = Type.GetType(args[0]);
if ( null == t ) {
// bad
} else {
args.RemoveAt(0); // discard the class name
$$anonymous$$ethodInfo mi = t.Get$$anonymous$$ethod("UserExecute", BindingFlags.Static | BindingFlags.Public);
mi.Invoke(null,args);
}
}
}
...
class DestroyUniverse {
public static void UserExecute(string size) {
Debug.Log("You destroyed a universe of size "+size);
}
}
...
exec DestroyUniverse 24
How would i be able to do it on javascript? Some stuffs are missing, and i am not able to add "using System.Reflection" in javascript, so:
BCE0018: The name 'Type' does not denote a valid type ('not found'). Did you mean 'System.Type'?
BCE0018: The name '$$anonymous$$ethodInfo' does not denote a valid type ('not found'). Did you mean 'System.Reflection.$$anonymous$$ethodImplAttributes'?
var t : Type = Type.GetType(temp[1]);
var method : $$anonymous$$ethodInfo = t.Get$$anonymous$$ethod("Execute", BindingFlags.Static | BindingFlags.Public);
method.Invoke(null, null);
i tried doing what the compiler tells me, but it doesn't seems to be better...
Always fix the first error first. One error usually creates more 'phantom' errors that aren't really errors once the original is fixed.
using -> import:
import System.Reflection;
Type -> System.Type, or import System:
import System;
Thanks, it was import :P But it didn't work out very well, whatever i write, example, "exec test_pillar_1", becomes "NullReferenceException: Object reference not set to an instance of an object", here is my codes:
else if (temp[0] == 'exec')
{
var t : System.Type = Type.GetType(temp[1]);
var method : $$anonymous$$ethodInfo = t.Get$$anonymous$$ethod("Execute", BindingFlags.Static | BindingFlags.Public);
method.Invoke(null, null);
Well, debug.log things like temp[1], make sure you have a class named test_pillar_1 which has a public static method named Execute, only one line is throwing the error and that's the one the problem is on.
Answer by Waz · Apr 30, 2013 at 10:28 PM
Unity does not even compile-in unused scripts (or other assets), so you need to rethink your plan entirely.
I don't think that is true of scripts: you can certainly call AddComponent with a script that wasn't attached to anything previously.
yea but how would i use: thing.AddComponent(String); as i can't seem to use a string... Basically i need to do this: "scriptName" -> scriptName, just to be able to add it as an argument.
Can you answer my question in the comments above with regards to the audience for this plugin?
Are we talking about loading assemblies written by someone else at run time?
Are you talking about compiling their C# code at runtime?
or are these scripts written and added to the project before it is compiled?
I don't have plugins for that yet, but what i plan to do is having a specific folder with script files inside, that will be loaded ingame, so we can go in the _DATA dolder, and place a file in it, then it will compile it, and we can then execute a function of that script by entering << exec (script name here) >>, then the rest of my code should do the rest.
Answer by DaveA · May 01, 2013 at 05:58 AM
Look into using Eval, which can be dangerous. http://msdn.microsoft.com/en-us/library/b51a45x6(v=vs.80).aspx