Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

New AddComponent Rules

Discussion in 'Scripting' started by Beniamino, Dec 17, 2015.

  1. Beniamino

    Beniamino

    Joined:
    Jul 25, 2015
    Posts:
    17
    I've seen some talk regarding the new way to use AddComponent. I know it was probably considered a cheap hack the way I used to use it. What I don't seem to be able to find is: how am I now to refer to scripts abstractly? What I had before was basically

    Skill newSkill = (Skill)hero.gameObject.AddComponent (nameOfSkill) as Skill;

    What I was doing was passing in the name of the component as nameOfSkill. Each skill was in its own script. I'm not sure if there's any way to do this without hardcoding each skill name.
     
    Yash987654321 likes this.
  2. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    There isn't anything inherently wrong with the method that you're using to add components. AddComponent(string) is supported and functional.

    You might be seeing people recommend the generic version of AddComponent, because it offers type-safety. Type safety is a boon to projects of large scale, with a lot of moving parts. When the type of one object changes, the compiler will alert you to any AddComponent<T>() calls that are no longer valid because the type no longer exists, or is no longer a monobehaviour.

    Using AddComponent(string) you don't get the compiler error that alerts you to the error. Unity will only alert you to the error when you actually try to add the invalid component string to a game object. That may only occur after several minutes of playing. Those types of errors can be tough to catch. With the generic version of AddComponent, you'd have been alerted immediately to the error.
     
  3. Beniamino

    Beniamino

    Joined:
    Jul 25, 2015
    Posts:
    17
    Hmm well the Unity 5.3 is showing it as deprecated. If I import from older Unity, it offers to do an autocorrection. This seems to work okay but then the game will not compile to Android because it then uses some hard references to other code or something so it only works with the Unity Editor.
     
  4. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
    Ah, interesting. You're right. It is marked obsolete.

    AddComponent(Type) is not marked obsolete, though. So you can parse your string for the Type and use that.

    Code (csharp):
    1. Type nameOfSkillType = Type.GetType(nameOfSkill);
    2. Skill newSkill = (Skill) hero.gameObject.AddComponent(nameOfSkillType);
     
  5. CloudKid

    CloudKid

    Joined:
    Dec 13, 2015
    Posts:
    207
    Well for your current project I will not bother to change it. It is marked as deprecated so you will not use it in future, but is left there for backwards compatibility. That is exactly your situation. It is left there so your code will still work. From now on try and use a different solution. My thumb rule is never use strings if you can. Replace strings with clases, Interfaces, Enums, and in case of animations use triggers (which is still a string, but a more manageable one). If you do this, and something breaks, it will be easier to debug, replace and refactor your problem.
     
    Kiwasi likes this.
  6. Beniamino

    Beniamino

    Joined:
    Jul 25, 2015
    Posts:
    17
    Thanks to both of you. CloudKid, I am not sure if I can keep it while transitioning from Unity 4 to Unity 5.3. The reason I'm importing it there is so I can use the new IAP plugin. It is my understanding that I can use it while in editor mode but not compile it to Android the way it is.
     
  7. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You're doing both types of casting here, which is redundant. Typically, this is fine as long as you know it will downcast
    Code (csharp):
    1.  
    2. (Skill)hero.gameObject.AddComponent(nameOfSkill);
    3.  
    The issue with an "as" cast in this case is if you pass it a valid MonoBehaviour derivative name but that class can't cast to Skill. It'll add the component but your variable will be null which might lead you to believe that it didn't add it.
     
  8. Beniamino

    Beniamino

    Joined:
    Jul 25, 2015
    Posts:
    17
    I see what you mean too, Kelso. I started looking into Generics and watched the video on the Unity page a couple times. Is this something that would be relevant to my problem?
     
  9. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    It would. The biggest question is why you're really using strings in the first place. There's almost always a better solution.
     
  10. Beniamino

    Beniamino

    Joined:
    Jul 25, 2015
    Posts:
    17
    Thanks for all the advice. What I had was a way of checking each character when he levels up or prestiges, to see if he has any skills that should be automatically learned. As such, I was cycling through all the skills that existed in the game and checking to see if it match on level and class. I was referring to each skill by its Component name in string format.

    The only alternatives I can see would be:
    1. Figure out a way to cycle through all scripts that inherit from Skill.
    2. List in code all the skills I've created.

    1 is preferable because I could create skills without having later to write them in code after I've done so. But either option I'm going to have to find a way to refer to scripts abstractly. That was my main problem here. I couldn't find anything online that answered it and actually most of what I did find seemed to imply that there was in fact no way to refer to them abstractly, other than Add and Get Component with string.
     
  11. Beniamino

    Beniamino

    Joined:
    Jul 25, 2015
    Posts:
    17
    I think I get it now.

    System.type type = typeof(ScriptName);

    It was "typeof" that was throwing me. I might not have used that before.