Search Unity

Can't get type from string

Discussion in 'Scripting' started by MCrafterzz, Jul 23, 2017.

  1. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    Im working on loading game data and therefor want to convert a string to a type so that I then can add the component. The problem is that it gives me a NullReferenceException: Object reference not set to an instance of an object:
    Code (CSharp):
    1. Type type = Type.GetType ("UnityEngine.UI.Text");
    2. print (type.ToString());
    UnityEngine.UI.Text is just a example for testing. I can't understand why it doesn't work so all help is welcomed!
    EDIT: "Text" doesn't work either
     
  2. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    do you have a script named Type.
     
  3. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    No
    EDIT: I accually have a enum named Type maybe that's why?
    EDIT 2: Changing to System.Type.GetType didn't do any difference
     
  4. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    can you explain what you're trying to do. it looks like you're trying to get the text of a UI element.
     
  5. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    I have a variable with a string that represents a class(component) in this example Text. I want to convert the string to a Type so I then can call the AddComponent(type);
     
  6. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    so maybe something like this, sorry for code typos

    private string compString = "UnityEngine.Collider, UnityEngine";

    var mytype = new Type.GetType(compString);
    gameObject.AddComponent(mytype);
     
    FlightOfOne and Kiwasi like this.
  7. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    Why have you a added UnityEngine twice to your compString?
     
  8. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    string compString = "UnityEngine.UI.Text, UnityEngine";

    var mytype = new Type.GetType(compString);
    gameObject.AddComponent(mytype);
    print(getComponent<Text>().text);
     
    FlightOfOne likes this.
  9. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    Yest that's kind of how I did it but it didn't work. It gives me the exception on this line: print (type.ToString());
    So the type is for some reason null
     
  10. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    i say a past post that said this is the format it needs.
     
  11. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Your script and UnityEngine.UI.Text end up in different assemblies. So you need to specify the assembly to look in.

    However I suspect te assembly name is still wrong. The UI is in a different assembly again to UnityEngine.

    Do some basic reflection on the type to figure out what the assembly its in is called.
     
  12. ThomasTrenkwalder

    ThomasTrenkwalder

    Joined:
    Jun 18, 2017
    Posts:
    10
    Note that Type.GetType requires the assembly-qualified name of a type, unless it is in the currently executing assembly or something.
    See https://msdn.microsoft.com/en-us/library/w3f99sx1(v=vs.110).aspx
    and https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx

    That's why you need to add ", UnityEngine" or whatever the assembly display name for the ui stuff is, or it will return null.
    Try to find out what the assembly name for the ui stuff is (I don't know anymore) and you should be able to get it to work ;)
     
    Kiwasi likes this.
  13. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,332
    Type.GetType requires the assembly qualified name. You can check what that is from the .AssemblyQualifiedName property of a Type:

    Code (csharp):
    1.  
    2. var text = typeof(UnityEngine.UI.Text);
    3. print (text.AssemblyQualifiedName);
    4. //prints "UnityEngine.UI.Text, UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
    That's a mouthful, so you only want to use GetType if you've already stored that from earlier.

    If you want to get an arbitrary type by name, you'll either need to know which assembly it lives in, or search through all assemblies:

    Code (csharp):
    1.  
    2. Type textType = null;
    3. string typeName = "UnityEngine.UI.Text";
    4. var assemblies = AppDomain.CurrentDomain.GetAssemblies();
    5. foreach (var assembly in assemblies)
    6. {
    7.     textType = assembly.GetType(typeName);
    8.     if (textType != null)
    9.         break;
    10. }
    11.  
    12. Debug.Log(textType);
    13.  
    @johne5, if you're going to help people, try saying what you're doing, don't just throw code at them.
     
  14. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    To save the type I use this:
    Code (CSharp):
    1. saveComponent.type = component.GetType().ToString ();
    And that saves into the file "UnityEngine.UI.Text" so shouldn't it be possible to access a component with that string?
     
  15. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,332
    You want GetType().AssemblyQualifiedName, as I did. C# needs the assembly to figure out where to look for the type.

    If you want to know why C# doesn't spit out AssemblyQualifiedName from ToString(), which would've been the convenient thing, call Microsoft.
     
    MCrafterzz likes this.
  16. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    The docs suggest its for backwards compatibility.
     
    MCrafterzz likes this.
  17. MCrafterzz

    MCrafterzz

    Joined:
    Jun 3, 2017
    Posts:
    354
    Thanks for your help! Had not idea that it worked like that :D