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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Add Script from Project to GameObject

Discussion in 'Scripting' started by Martin_Gonzalez, Aug 25, 2015.

  1. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    Is this possible?
    I'm creating in runtime a script and saving it in the project but i cannot find the way to get that script and add it to a gameobject via script.
    Steps:
    Create GameObject via Script
    Create Script via Script
    *Get the Script created
    *Add to the GameObject

    Thanks!
     
  2. adnan-e94

    adnan-e94

    Joined:
    Dec 17, 2012
    Posts:
    70
    How do you "create" a script? You cant instantiate MonoBehaviours.
    Looks like I've been wrong, you can. But still, do it like this:

    You add components like:
    Code (CSharp):
    1.  
    2. MyScript script = gameObject.AddComponent<MyScript>();
    3.  
    4. /* init script here */
    5.  
     
  3. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    The problem is that in that moment MyScript do not exist. Is just a file. Im creating it with the StreamWriter and adding the lines.
    If there a way to seach scripts by the name "MyScript.cs" or something like that
     
  4. adnan-e94

    adnan-e94

    Joined:
    Dec 17, 2012
    Posts:
    70
    You can't load a script runtime, it has to be compiled into bytecode.
    What are you trying to achieve, exactly?

    You can load DLL's at runtime though, is that an option? Building a .NET assembly.
     
  5. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    I'm developing a ScreenManager where with an editor popup you can create the Screen template. So i create the GameObject, the Prefab and the Script, but i would like to add that script into the prefab so users will not have to drag and drop.
     
  6. adnan-e94

    adnan-e94

    Joined:
    Dec 17, 2012
    Posts:
    70
    Oh, so it's not at runtime, its an editor extension?

    Well, you still need to build it somehow, after creating the MyScript.cs file, you need to wait for unity to build it and then you will be able to add it. But there's no onBuild callback I know of..
    You'll have to instruct the user to add the script manually I think, but would love to know if there's a way for this actually!
     
    Martin_Gonzalez likes this.
  7. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    There are some reflection tricks you could use. But the whole scheme doesn't sit right with me. I guess I'm not understanding your use case properly.
     
  8. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    I have an editor window where the steps i want to do are:
    Create GameObject (done)
    Rename it (done)
    Create a script in editor runtime (done)
    Create the prefab of the GameObject created (done)
    Add the script created to the gameobject created (can't)
     
  9. Code to Reality Studios

    Code to Reality Studios

    Joined:
    Aug 25, 2015
    Posts:
    64
    I once tried this but ended in tears. You cannot add a script that is created through a script to an object. Unity needs to compile the script before it can be used and, this is not done through a script. Sorry, I tried for maybe 6 1/2 hours one day to no avail.
     
    Martin_Gonzalez likes this.
  10. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    Well, its not so bad to drag and drop something xD
     
  11. Code to Reality Studios

    Code to Reality Studios

    Joined:
    Aug 25, 2015
    Posts:
    64
    Yeah. Good luck though!
     
  12. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    I'm still not getting why an AddComponent + Reflection combination won't work. You can use DidReloadScripts to get a call back after compilation is finished. Then you can scan the assembly for the script you just created with Reflection. Then you add the component with AddComponent.

    It requires a fair bit of coding know how, I don't have the time now to do a mock up for you. But if you are writing editor scripts then you should be able to handle it.

    Run time compilation is possible on some platforms. Check out Emit. That said most games with run time compilation use an interpreted scripting language like LUA. Its far easier to implement and control.

    Edit: Its also worth noting that by putting logic into data that can be parsed by your own system you can often avoid adding new scripts at runtime altogether.
     
    Last edited: Aug 26, 2015
  13. Code to Reality Studios

    Code to Reality Studios

    Joined:
    Aug 25, 2015
    Posts:
    64
    Very interesting. I will have to look into Emit. I might be able to use it one day! :)
     
  14. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Just be careful on the platforms, I know you can't use it for iOS. Apple wants to be able to approve every single line of code that runs on their machines. I think the other platforms are mostly okay.
     
  15. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    Thanks for your answer. Now i'm able to know when compiler fnished, but i don't know how to search the file in the assembly. Im trying with this:

    Code (CSharp):
    1. Assembly assembly = typeof(string).Assembly;
    2.         Type type = assembly.GetType("ScreenBla");
    3.  
    4.         Debug.Log(type.Name);
     
  16. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    With this, now i can search the class type!

    Code (CSharp):
    1. [DidReloadScripts]
    2.     static void ScriptsReloaded()
    3.     {
    4.         if(scriptName == "") return;
    5.  
    6.         foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
    7.         {
    8.             foreach (Type t in a.GetTypes())
    9.             {
    10.                 if(t.IsClass && t.Name == scriptName)
    11.                 {
    12.                     Debug.Log (t.Name);
    13.                 }
    14.             }
    15.         }
    16.     }
    My problem now is that scriptName is a static string that in a previous method has value, but when finished compiling returns to be null :/

    I need in a way get the name of the script i had created.

    Perhaps if i save it locally in a .txt and read it from there. Is that dirty?
     
  17. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    Finally i could thanks to BoredMormon!

    What i did was saving in a .txt the name of my class and doing what i posted up here.
    Then scriptName matches with the type.Name and i add it to a GameObject that a created!