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

GetComponent() without a certain script name - C#

Discussion in 'Scripting' started by Spaetten1, Oct 24, 2011.

  1. Spaetten1

    Spaetten1

    Joined:
    Mar 23, 2010
    Posts:
    85
    Hey fellas, I have an array containing different strings. These strings are named exactly after scripts I have put on a GameObject, and I am now trying to access the scripts through the GameObject using GetComponent(). My problem here is that I don't know the exact scriptname before calling GetComponent(). Btw I'm using C#, that's why it's so challenging.. Looks something like this

    Code (csharp):
    1.  
    2. GameObject script_container = null;
    3. string[] Names = new string[5];
    4.  
    5. void dostuff(name_number){
    6.  
    7. // The following doesn't work in C#, but it did in Java, I hope you can see where I am goin
    8. script_container.GetComponent(Names[name_number]).use();
    9. }
    10.  
    That was just a very quick example, hope I was clear enough
     
  2. fffMalzbier

    fffMalzbier

    Joined:
    Jun 14, 2011
    Posts:
    3,276
    If you do not know the name of the class / script but you like to call a specific function you can use BroadcastMessage.
     
    CanisMajor likes this.
  3. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Alternately, store an array of Types instead of an array of strings.
     
  4. Ivenu Visuals

    Ivenu Visuals

    Joined:
    Oct 24, 2011
    Posts:
    9
    How do you post a new thread or do you have to just keep rplying to other peoples i have just joined the site?
     
  5. nazgul

    nazgul

    Joined:
    Oct 24, 2011
    Posts:
    10
    Agree with KelsoMRK. For example:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6. public interface MyInterface{
    7.      void use();
    8. }
    9. public class MyClass : MonoBehaviour{
    10.     private List<MyInterface> interfaces = new List<MyInterface>();
    11.    
    12.  
    13.     public void addMyInterface(MyInterface myInterface){
    14.          interfaces.Add(myInterface);
    15.     }
    16.  
    17.     public void dostuff(MyInterface myInterface){
    18.         myInterface.use(); 
    19.     }
    20. }
    21.  
    You create the class implementing MyInterface and add it in array interfaces.
     
    Last edited: Oct 24, 2011
  6. Spaetten1

    Spaetten1

    Joined:
    Mar 23, 2010
    Posts:
    85
    Well yeah but how would that work if my function is in a different script?
     
  7. Spaetten1

    Spaetten1

    Joined:
    Mar 23, 2010
    Posts:
    85
    I'll try and look it up real quick

    edit - can't figure it out really
     
    Last edited: Oct 24, 2011
  8. Spaetten1

    Spaetten1

    Joined:
    Mar 23, 2010
    Posts:
    85
    Ivenu Visuals, you can make a new thread if you want, just go to whatever sub-forum you like (f.x. scripting), scroll to the bottom of the page and select 'new thread'
     
  9. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    The same way it does when you use an array of strings? I'm not really sure what the question is.
     
  10. Spaetten1

    Spaetten1

    Joined:
    Mar 23, 2010
    Posts:
    85
    I just don't know what interface and list is, it's all pretty confusing to me.. Can't find it on the net, do you know where to find documentation on it?
     
  11. Spaetten1

    Spaetten1

    Joined:
    Mar 23, 2010
    Posts:
    85
    Plus there are a lot of different scripts.. Perhaps I should link my source code so you can see what I mean

    This is the file called 'skillsystem_class_database':
    Code (csharp):
    1.  
    2. public class skillsystem_class_database {
    3.     public GameObject spell_container;
    4.    
    5.     public string[] classes = new string[5];
    6.    
    7.     public string[] shaman_spells = new string[3];
    8.    
    9.     public void _init(){
    10.         // Define names of classes, create more if you want
    11.         classes[0] = "shaman";
    12.         classes[1] = "brute";
    13.         classes[2] = "archer";
    14.         classes[3] = "assassin";
    15.         classes[4] = "mage";
    16.        
    17.         shaman_spells[0] = "shaman_attack";
    18.     }
    19. }
    20.  
    This is the relevant part of my file called skillsystem_base, which is attached to my player:
    Code (csharp):
    1.  
    2. void use_skill(int skillnumber){
    3.     GameObject spell_container = class_db.spell_container
    4.     spell_container.GetComponent(class_db.shaman_spells[skillnumber]).use();
    5. }
    6.  
    And this is my spell script, which is attached to a prefab called spell_container:
    Code (csharp):
    1.  
    2. public class shaman_attack : MonoBehaviour {
    3.  
    4.     void use(){
    5.         Debug.Log("You Attacked");
    6.     }
    7. }
    8.  
    That's basically it, I am simply looking for a way that the skillsystem_base script can access all my spell scripts without too much repitition. I can't really use GetComponent in this case I think, don't know what to do..
     
    Last edited: Oct 25, 2011
  12. giyomu

    giyomu

    Joined:
    Oct 6, 2008
    Posts:
    1,094
    I am not that smart coder but maybe this can give you some hint for your system, this is just a simple example on how you could approach it

    first a file that handle some data
    Code (csharp):
    1.  
    2.  
    3. // classe type
    4. public enum Guild
    5. {
    6.     Shaman,
    7.     Brute,
    8.     Assassin,
    9.     Archer,
    10.     Mage
    11. }
    12.  
    13. // action
    14. public enum Action
    15. {
    16.     Attack,
    17.     Defend,
    18.     RunAway,
    19.     DanceSamba
    20. }
    21.  
    22. public struct CharacterData
    23. {
    24.     public Guild charGuild;
    25.     public Action charAction;
    26.    
    27.     public CharacterData(Guild charGuild, Action charAction)
    28.     {
    29.         this.charGuild = charGuild;
    30.         this.charAction = charAction;
    31.     }
    32. }
    33.  
    then have a base component to handle your characters ( be it one or many )
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class CharacterBase : MonoBehaviour
    6. {
    7.     // just for test purpose
    8.     public Guild currentGuild;
    9.     public Action currentAction;
    10.    
    11.     public delegate void UseSkillEventHandler(CharacterData data);
    12.     public event UseSkillEventHandler OnUseSkillEvent;
    13.    
    14.     private CharacterData characterData;
    15.    
    16.     void Awake()
    17.     {
    18.         ChangeData(currentGuild, currentAction);
    19.     }
    20.    
    21.     //just for test
    22.     void Update()
    23.     {
    24.         if(Input.GetKeyDown(KeyCode.Space))
    25.         {
    26.             ChangeData(currentGuild, currentAction);
    27.             UseSkill();
    28.         }
    29.     }
    30.    
    31.     //call this from some logic script
    32.     public void ChangeData(Guild guild, Action action)
    33.     {
    34.         characterData = new CharacterData(guild, action);
    35.     }
    36.    
    37.     public void UseSkill()
    38.     {
    39.         if(OnUseSkillEvent != null)
    40.             OnUseSkillEvent(characterData);
    41.     }
    42. }
    43.  
    44.  
    then your skill action , be it all in one script or separate it doesn't matter
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class ShamanAction : MonoBehaviour
    6. {
    7.     private Guild thisGuild = Guild.Shaman;
    8.    
    9.     void Start()
    10.     {
    11.         // considering character base in on the same GameObject
    12.         GetComponent<CharacterBase>().OnUseSkillEvent += UseSkill;
    13.     }
    14.    
    15.     void OnDisable()
    16.     {
    17.         GetComponent<CharacterBase>().OnUseSkillEvent -= UseSkill;
    18.     }
    19.    
    20.     void UseSkill(CharacterData data)
    21.     {      
    22.         if(thisGuild != data.charGuild)
    23.             return;
    24.        
    25.         switch(data.charAction)
    26.         {
    27.             case Action.Attack:
    28.                 Attack();
    29.                 break;
    30.             case Action.Defend:
    31.                 Defend();
    32.                 break;
    33.             case Action.RunAway:
    34.                 RunAway();
    35.                 break;
    36.             case Action.DanceSamba:
    37.                 DanceSamba();
    38.                 break;
    39.         }
    40.     }
    41.    
    42.     void Attack()
    43.     {
    44.         Debug.Log(GetType().ToString() + " Attack");
    45.     }
    46.    
    47.     void Defend()
    48.     {
    49.         Debug.Log(GetType().ToString() + " Defend");
    50.     }
    51.    
    52.     void RunAway()
    53.     {
    54.         Debug.Log(GetType().ToString() + " RunAway");
    55.     }
    56.    
    57.     void DanceSamba()
    58.     {
    59.         Debug.Log(GetType().ToString() + " DanceSamba");
    60.     }
    61. }
    62.  
    same you can define a class archer too
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class ArcherAction : MonoBehaviour
    6. {
    7.     private Guild thisGuild = Guild.Archer;
    8.    
    9.     void Start()
    10.     {
    11.         // considering character base in on the same GameObject
    12.         GetComponent<CharacterBase>().OnUseSkillEvent += UseSkill;
    13.     }
    14.    
    15.     void OnDisable()
    16.     {
    17.         GetComponent<CharacterBase>().OnUseSkillEvent -= UseSkill;
    18.     }
    19.    
    20.     void UseSkill(CharacterData data)
    21.     {      
    22.         if(thisGuild != data.charGuild)
    23.             return;
    24.        
    25.         switch(data.charAction)
    26.         {
    27.             case Action.Attack:
    28.                 Attack();
    29.                 break;
    30.             case Action.Defend:
    31.                 Defend();
    32.                 break;
    33.             case Action.RunAway:
    34.                 RunAway();
    35.                 break;
    36.             case Action.DanceSamba:
    37.                 DanceSamba();
    38.                 break;
    39.         }
    40.     }
    41.    
    42.     void Attack()
    43.     {
    44.         Debug.Log(GetType().ToString() + " Attack");
    45.     }
    46.    
    47.     void Defend()
    48.     {
    49.         Debug.Log(GetType().ToString() + " Defend");
    50.     }
    51.    
    52.     void RunAway()
    53.     {
    54.         Debug.Log(GetType().ToString() + " RunAway");
    55.     }
    56.    
    57.     void DanceSamba()
    58.     {
    59.         Debug.Log(GetType().ToString() + " DanceSamba");
    60.     }
    61. }
    62.  
    63.  

    well that just an example how you could go about it using event in C# , that way you don't care about get listing of your class , but do care about what you send to who

    as i say that just something you can tinker with..

    hope that help ;)

    try it put the character base and archer , shaman on same GO and test out...

    after regarding how you want architecture your stuff and how you want call that well it may be more or less appropriate..
     
    Last edited: Oct 25, 2011
  13. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    I would do this:

    Code (csharp):
    1.  
    2. public class Spell : MonoBehaviour
    3. {
    4.     // base spell implementation
    5.  
    6.     public void Use()
    7.     {
    8.         // whatever your default use logic is
    9.     }
    10. }
    11.  
    12. public class ShamanAttackOne : Spell
    13. {
    14.     // override specific properties of base Spell
    15.  
    16.     public override void Use()
    17.     {
    18.         // override default behaviour, or add to it by calling base.Use() first
    19.     }
    20. }
    21.  
    22. public class SomeOtherClass : MonoBehaviour
    23. {
    24.     // use this instead of your string[] from before
    25.     public Spell[] spellArray = new Spell[5];
    26.  
    27.     public void Use(int spellNum)
    28.     {
    29.         spellArray[spellNum].Use();
    30.     }
    31. }
    32.