Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Question Can you access another script using a string name?

Discussion in 'Scripting' started by CarlRe, May 23, 2024.

  1. CarlRe

    CarlRe

    Joined:
    Jan 6, 2023
    Posts:
    3
    I'm used to doing the likes of the following to access one script from another script. But how would you achieve the same result where the script's name is in a string?
    Code (CSharp):
    1. public class ScriptA : MonoBehaviour
    2. {
    3.     void Start()
    4.     {
    5.         ScriptB scriptB = FindObjectOfType<ScriptB>();
    6.         print(scriptB.aVariable);
    7.     }
    8. }
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,922
    Accessing (or "finding") any type by string is really bad practice. It throws so much out of the window for no good reason - it will break often, it is hard to debug, and what if multiple objects carry the same name?

    You can find components (or assets for that matter) by their type. This ensures type safety, when that thing is Xyz you will only get the Xyz and not an Abc that happens to have the same name.

    var scriptB = GetComponent<ScriptB>();
    Debug.Log(scriptB.aVariable);


    GetComponent has variants for getting multiple, finding them in children or parents.
     
  3. TeaJunkie

    TeaJunkie

    Joined:
    Nov 23, 2016
    Posts:
    24
    another method is also to manually add it via the inspector.

    public ScriptB scriptB;

    This way you can avoid Find and GetComponent and you can just access it like any other variable. eg:

    scriptA.itemName = scriptB.itemName;

    Hope this helps.
     
  4. CarlRe

    CarlRe

    Joined:
    Jan 6, 2023
    Posts:
    3
    I know it's bad practice, but it's the only method I could think of that might possibly work.

    What I've been trying to do is have one script send a message (or whatever) to another script saying they should access so and so a script to do X. How would you do that?
     
  5. TeaJunkie

    TeaJunkie

    Joined:
    Nov 23, 2016
    Posts:
    24
    if your scripts are on GameObjects then creating a public variable like i stated above would allow you to access the script that has been attached in the inspector. after which it would be as simple as:

    Code (CSharp):
    1. scriptA.TestFunction();
    or others as any public function or variable on the attached script would be able to be accessed. its the same as calling a function or variable inside a normal script except now you just need to include the script variable before.

    if you want a function that requires you to input information into it then below is a good idea.

    Script 1 ScriptA:

    Code (CSharp):
    1. public ScriptB scriptB;
    2.  
    3. public void Attack()
    4. {
    5.     scriptB.TakeDamage(50);
    6. }
    Script 2 ScriptB:

    Code (CSharp):
    1. public void TakeDamage(int damage)
    2. {
    3.     health -= damage;
    4. }
    all you would need to do is drag the game object holding ScriptB into the inspector or ScriptA in the field called scriptB.

    I hope this makes sense.

    Summary: Script A is calling the take damage function on ScriptB with an int amount. ScriptB has a TakeDamage function that requires and int value to be passed when it is called.

    The same method can work with strings, floats, GameObjects and more.

    Hope this helps.
     
    CarlRe likes this.
  6. CarlRe

    CarlRe

    Joined:
    Jan 6, 2023
    Posts:
    3
    Thanks for all that TeaJunkie. Much appreciated. I'm sure that'll allow me to come up with something better than my current work around. The main object of the exercise is to come up with a prefab that doesn't need tweaking for each scene it's in, or for use in future projects.