Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Change string into a runnable code (kind of)

Discussion in 'Scripting' started by rango3526, Jan 2, 2015.

  1. rango3526

    rango3526

    Joined:
    Jan 1, 2015
    Posts:
    6
    I basically need to use a string passed in through a function as a part of the code.

    This is an example of how I'd call the function:
    Code (CSharp):
    1. findPathVar("GetComponent<exampleScript>()", "ItemID");
    Code (CSharp):
    1. public int findPathVar(string path, string varName) {
    2.      
    3.        int variableNeeded = gameObject.(path).(varName);
    4.      
    5.        return variableNeeded;
    6. }
    So this way I could find the value of 'ItemID' in 'exampleScript'.
    Is this, or something similar, possible?

    Thanks,
     
  2. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,121
    Thats not really possible with C#. Your C# scripts are compiled and executed, C# isn't an interpreted language like PHP, so you can't really just 'execute a string'.
     
  3. Oana

    Oana

    Joined:
    Sep 28, 2012
    Posts:
    87
    Well, you could use reflection in C#, although I've never tried it in Unity... It would look something like this:

    using System.Reflection;
    ...

    Type type= gameObject.GetComponent(path).GetType();
    int variableNeeded = type.GetProperty(varName);

    Read more about it here: http://csharp.net-tutorials.com/reflection/introduction/
     
    rango3526 and image28 like this.
  4. image28

    image28

    Joined:
    Jul 17, 2013
    Posts:
    457
    Reflection is fun...
     
  5. Kirk Clawson

    Kirk Clawson

    Joined:
    Nov 4, 2014
    Posts:
    65
    It's also horribly slow, so you probably shouldn't use it inside Update().
     
  6. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    Why not just make a mini-language for the functionality you'll need at runtime?

    "move 3;dir (-1,0,1);"

    You can split the number of commands by a delimiter like ; and then split the command into arguments with another delimiter. I used spaces in that example. Have a class / huge function to execute certain operations when it sees certain strings.

    Code (CSharp):
    1. if(arg[0].Equals("move"))
    2. {
    3.     gameObject.transform.position += blah(arg[1]);// your function to convert a string into a vector
    4. }
     
    Prodigga likes this.
  7. Kirk Clawson

    Kirk Clawson

    Joined:
    Nov 4, 2014
    Posts:
    65
    Is this something that you'll need a huge amount of flexibility in? Or is there only going to be a small number (20 or so) of possibilities? If it's the latter, I'd consider using a dictionary of lambdas.
     
  8. rango3526

    rango3526

    Joined:
    Jan 1, 2015
    Posts:
    6
    This seems like exactly what I need, I'll try it. Thanks!
     
  9. rango3526

    rango3526

    Joined:
    Jan 1, 2015
    Posts:
    6
    What I'd like to do is have a function that checks for certain similarities between game objects in a certain group. But I want the function to be able to check a specified variable in a certain script and return the ones that have a certain value for that variable. So in the function call, I want to specify where the variable is (like which script), and then when a variable name is passed in, locate that variable in the earlier specified script. I think Oana's idea for using reflections could work for this, but if you have a good idea to solve this in a different way, I'd love to hear it.
     
  10. rango3526

    rango3526

    Joined:
    Jan 1, 2015
    Posts:
    6
    That's not really what I need right now, but I really like that idea for other parts of my code. I don't really have much experience with working with strings in code, though, so I'm not exactly sure how to do this. How do you get a string divided into a String[] or array with each word in a different slot? (like how you used 'arg[x]')
     
  11. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    I did this for a magic system. You format your strings like so:

    String whatever = "function1 arg1 arg2 arg3;function2 arg1 arg2;function3 arg1 ... arg 4";
    String[] listOfFunctions = whatever.split(";");
    String[] functionArguments = listOfFunctions[index].split(" ");

    Just look up the syntax for split because my memory of it is unreliable due to the varying syntax between languages.

    Code (CSharp):
    1. String input = "walk 5;run -5;crawl 5";
    2. String[] commands = input.split(";");
    3.  
    4. for(int i = 0;i < commands.length;i++)
    5. {
    6.     String[] args = commands.split(" ");
    7.     if(args[0].Equals("walk"))
    8.     {
    9.         doWalkFunction(int.parse(args[1]));
    10.     }
    11.     if(args[0].Equals("run"))
    12.     {
    13.         doRunCode(int.parse(args[1]));
    14.     }
    15.     /*etc etc check args[0] for the function you want to call and every following index is a variable to pass*/
    16. }
    Strings aren't the fastest things to work with, so I used the system just to read changes from the armor & equipment to set up properties of a spell rather than using that system to determine spell properties per cast. It can be used for anything :D
     
    rango3526 likes this.
  12. rango3526

    rango3526

    Joined:
    Jan 1, 2015
    Posts:
    6
    That makes a lot of sense now. Thanks for spending your time to explain that to me! I'll definitely use that for something in the future; maybe a way to call a function in-game for bug testing (or they could be cheat codes).
     
  13. Tomnnn

    Tomnnn

    Joined:
    May 23, 2013
    Posts:
    4,148
    My pleasure :)

    What's great about the way it's set up is that the order doesn't matter. Since it checks for every possible argument 0, you can have walk and then run or run and then walk or whatever. It's definitely a great idea for cheat codes :p