Search Unity

generate a script in a script; create instance of it when compiled?

Discussion in 'Scripting' started by jimmio92, Sep 12, 2018.

  1. jimmio92

    jimmio92

    Joined:
    Nov 3, 2009
    Posts:
    31
    Hello all,

    I'm trying to make a little utility that generates correct C# based on options the user sets in an EditorWindow, and generate it, save it as an asset, load that asset.. and then I want to add it as a component to a GameObject. My problem is, there's no way to do it?

    As an example: go.AddComponent<GameMgr>(); won't work until the current script is recompiled after GameMgr.cs is compiled. The other solution is obsolete, which was go.AddComponent("GameMgr"), but that's obviously not type safe. The problem is... without that, I don't know how else I can do what I need.

    Any help would be greatly appreciated.

    Thanks,
    Jim
     
  2. FernandoHC

    FernandoHC

    Joined:
    Feb 6, 2018
    Posts:
    338
    I believe doing that in editor mode should be possible, if you add enough UI interfaces for each step.
    But I don't think this is possible to do in real time with a compiled build, for several reasons.

    You could always use an interpreted based language instead of a compiled one instead, like lua. Not sure what is your final goal with this, but it's something games usually have.
     
  3. jimmio92

    jimmio92

    Joined:
    Nov 3, 2009
    Posts:
    31
    I'm looking at this all wrong. This system of templated scripts was not necessary at all. The templates... are the scripts. Why I thought I'd need to add to a script programmatically is beyond me.

    Basically, I'm making a little utility to just do a bunch of the mundane setup stuff I do every time a quick little game mechanic idea pops in my head and I fire up a new project for it. I figured I'd share it with the community when it's actually worth something to someone, so I'm trying to think ahead a bit.

    After much annoyance, I've decided it's not worth the trouble to write it if it is even possible. I should give the user more credit and just provide well documented barebones scripts for them to build onto, surely. Especially when it's something as complex and varied as a game state machine, effectively.

    Lua inside Mono inside Unity inside Javascript inside WebKit inside Chrome... no thanks, haha. Though I do very much enjoy working with Lua, I don't think I want to introduce that extra layer, at least for now. Thanks for the great suggestion, though!
     
  4. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    1,317
    Your only solution isn't going to be strictly type safe. I know you decided against this course of action, but I figured I'd lay out what you'd need to do to pull it off.

    Creating and adding the script itself is the easy part. All you need to do is just create a file with whatever code you want in it. Easy peasy.

    In order for the class to exist at all to Unity, your project needs to go through an assembly reload. Luckily, Unity has a solution for this in the
    AssemblyReloadEvents
    class. You can add an
    afterAssemblyReload
    callback and handle your new class there.

    However, you have a new problem; an assembly reload also means that all your in-memory data gets wiped, which means now you don't know which class you're even looking for. This is where
    EditorPrefs
    comes in. You can save your type name into
    EditorPrefs
    , and in your reload callback, check to see if that key exists to get the go-ahead to create the object.

    Now you have the class in your assembly and you have the class name available. You can't AddComponent with a string, but you can AddComponent with a Type. What you need to do is call
    Type.GetType
    with your saved type name to retrieve the actual type. Once you have the type, you can just create a new GameObject and toss the component onto it!
     
    jimmio92 and lordofduct like this.
  5. jimmio92

    jimmio92

    Joined:
    Nov 3, 2009
    Posts:
    31
    Thank you, Madgvox. That sounds like it'd for sure work! I'll keep that in mind in case it ever gets complex enough that it's actually needed.
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Upvoting Madgvox's suggestion. It's pretty much what I was coming in here to suggest.
     
    Madgvox likes this.