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. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Calling function from other scripts c#

Discussion in 'Scripting' started by juntao, Aug 11, 2010.

  1. juntao

    juntao

    Joined:
    Jul 29, 2010
    Posts:
    3
    how would one go about calling a function from one script from another? in c#
    eg
    scriptB calls function test() from scriptA

    if it make a difference the objects the the scripts are on is know before execution
     
    mcbt996v, terminator9 and Letizeus like this.
  2. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    Typically you would acquire the component using GetComponent(), and then call the function. e.g.:

    Code (csharp):
    1. myObject.GetComponent<MyScript>().MyFunction();
     
  3. juntao

    juntao

    Joined:
    Jul 29, 2010
    Posts:
    3
    could you explain a little more
    im not entirely sure how that works, what is game object supposed to be? the name of the object the script is on ? and <MyScript> should be the name of the script with the function so <scriptA>.

    i tryed using the code from the unity reference
    Code (csharp):
    1. ScriptName sn = gameObject.GetComponent<ScriptName>()
    2. sn.DoSomething();
    but get the error
    The type or namespace name `ScriptName' could not be found. Are you missing a using directive or an assembly reference?
     
  4. Kokumo

    Kokumo

    Joined:
    Jul 23, 2010
    Posts:
    416
  5. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    Right on both counts.

    Well, why would you expect that to work? :) The name of your particular script doesn't appear anywhere in that code, so how would it know what component to look for? (Hint: it's just example code - 'ScriptName' is a placeholder for whatever component type you're interested in.)
     
  6. ericbenner91

    ericbenner91

    Joined:
    Nov 13, 2013
    Posts:
    7
    Just upgraed to 4.3; not sure if that is a variable in this equation. Even with a switch of names, it still cannot find the script reference. On top of that, I also cannot access the containing object with this script. Additional annotation is required on this answer, hands down.
     
  7. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    So the hard part is getting a handle to your other script. If the objects already exist in the game scene, then you can drag the object with ScriptA onto the inspector for ScriptB.

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class ScriptB {
    4.   // Assign by dragging the GameObject with ScriptA into the inspector before running the game.
    5.   public ScriptA m_someOtherScriptOnAnotherGameObject;
    6.  
    7.   void Start() {
    8.     m_someOtherScriptOnAnotherGameObject.Test();
    9.   }
    10. }
    There are tons of ways to get handles to other scripts. Another example:
    Code (csharp):
    1. void Start() {
    2.   m_someOtherScriptOnAnotherGameObject = GameObject.FindObjectOfType(typeof(ScriptA)) as ScriptA;
    3.   m_someOtherScriptOnAnotherGameObject.Test();
    4. }
     
    Last edited: Nov 21, 2013
  8. ericbenner91

    ericbenner91

    Joined:
    Nov 13, 2013
    Posts:
    7
    Garth, you sir, and this is not idle compliment, are a genius.

    To anyone searching henceforth. It would seem in my code as it is now, that one must use Garth's syntax of accessing a brethren method to achieve any degree of success. Any deviation from GameObject.FindObjectOfType(typeof(scriptName) as scriptName; does now not seem to work, and Garth's example above rings true.

    Once again, thank you, and I will be referencing another thread to this location considering the lack of response of both extensive searching and thread response.
     
    Last edited: Nov 21, 2013
  9. GarthSmith

    GarthSmith

    Joined:
    Apr 26, 2012
    Posts:
    1,240
    Thanks for the kind words! Glad to help =)
     
    raajcm1 likes this.
  10. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    14,965
    Here's that thread, for anyone interested: http://forum.unity3d.com/threads/21...ommunication?p=1427010&viewfull=1#post1427010

    Edit: I'd suggest checking out that link because while the above is definitely one option it's only useful in certain cases. Other cases are covered by other options which are discussed in the linked thread.
     
    Last edited: Nov 21, 2013
    PolygonPros likes this.
  11. ericbenner91

    ericbenner91

    Joined:
    Nov 13, 2013
    Posts:
    7
    Very well
     
  12. Zynigma

    Zynigma

    Joined:
    Sep 23, 2012
    Posts:
    22
    Thank you so much for this. I couldn't wrap my brain around what I was doing wrong, and honestly, I still don't FULLY understand how this works. But one thing is for sure, IT WORKS!!! I'm going to study it and use the docs to really dissect how this works.

    I really appreciate it.
     
  13. ridethesun

    ridethesun

    Joined:
    Apr 30, 2014
    Posts:
    1
    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class ScriptA {
    5.  
    6.    public class ScriptAPartToUse {
    7.       void ScriptAFunction(){
    8.          //some code here
    9.       }
    10.    }
    11.  
    12. }
    13.  
    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class ScriptB {
    5.    ScriptAPartToUse Name = new ScriptAPartToUse();
    6.    
    7.    void Start() {
    8.       Name.ScriptAFunction();
    9.    }
    10.  
    11. }
    12.  
    I think it would be better. This example does not require dragging scripts anywhere. This example is a simplified version.

    http://unity3d.com/learn/tutorials/modules/intermediate/scripting/properties

    Type of all scripts in Unity3d - MonoScript. This code looks strange.
     
    Last edited: Apr 30, 2014
  14. AlanGreyjoy

    AlanGreyjoy

    Joined:
    Jul 25, 2014
    Posts:
    192
    posted in the wrong damn forum xD

    Sorry.
     
    hacertime05lol likes this.
  15. StrikeMasterz

    StrikeMasterz

    Joined:
    Sep 27, 2014
    Posts:
    1
    Would it be easier to simply use the SendMessage command? In this example, I will use the Damage Function of another object.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class findObjectControls : MonoBehaviour
    5.     {
    6.  
    7.     public Transform activateDamage;
    8.  
    9.     // Update is called once per frame
    10.     void OnCollisionEnter(Collision other)
    11.         {
    12.         if (other.transform.tag == "Player")
    13.             {
    14.             playerTransform.SendMessage("DamagePlayer", 100f, SendMessageOptions.DontRequireReceiver);
    15.             }
    16.         }
    17.     }
    18.  
    Is there something this doesn't do? Or is there a benefit of the other posibilities?
     
    hacertime05lol and AntonioZL like this.
  16. AMU4u

    AMU4u

    Joined:
    Feb 16, 2015
    Posts:
    9
    Yep, exactly what I needed. Short and to the point. Thanks!
     
    hacertime05lol likes this.
  17. Recluse

    Recluse

    Joined:
    May 16, 2010
    Posts:
    476
    SendMessage is limited to passing only a single parameter. If you need to pass more info between scripts on different objects you can achieve the same thing like this...

    Code (CSharp):
    1.  
    2.  
    3. Public GameObject objectToAccess;
    4. // drag the object you're calling a method on into the inspector, or alternatively use GameObject.Find to get a handle on it
    5.  
    6. ScriptName scriptToAccess = objectToAccess.GetComponent<ScriptName>();
    7. // get the script on the object (make sure the script is a public class)      
    8.  
    9. scriptToAccess.YourMethodName(your parameters etc);
    10. // calls the method in the script on the other object.
    11.  
    12.  
     
  18. mr_freedo

    mr_freedo

    Joined:
    Nov 6, 2014
    Posts:
    2
    For me it only tels me that m_someOtherScriptOnAnotherGameObject does not exist in the current context, If it is suposed to be a variable, what kind of variable is it?
     
    hacertime05lol likes this.
  19. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    in the example you are replying to it is of type "ScriptA", that error is basically saying "ScriptA" doesn't exist in your project. Replace all instances of "ScriptA" in that example with the type of your specific scriptname. i.e. if you are trying to access "GameManager" script "ScriptA" is replaced with "GameManager". The variable name is mostly irrelevant to the mechanical function, but using something appropriately descriptive would be good
     
  20. Recluse

    Recluse

    Joined:
    May 16, 2010
    Posts:
    476
    Try

    Code (CSharp):
    1. ScriptToAccess=ObjectName.GetComponent("ScriptName") as MonoBehaviour;
    Where ObjectName is the name of the object that contains the script you are accessing from elsewhere.

    As LeftyRighty says, make sure "ScriptName" is the same as the name of the script you need.

    See this similar post:

    http://answers.unity3d.com/answers/669527/view.html
     
    hacertime05lol likes this.
  21. AlanGreyjoy

    AlanGreyjoy

    Joined:
    Jul 25, 2014
    Posts:
    192
    Honestly... I just make master classes and set their namespaces.

    Works perfect.
     
    hacertime05lol likes this.
  22. Heresy Studios

    Heresy Studios

    Joined:
    Mar 23, 2016
    Posts:
    4
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. public class CrossRoad : MonoBehaviour {
    6.    
    7.     public Canvas canvas;
    8.     public GameObject character;
    9.    
    10.     void OnTriggerEnter(Collider other)
    11.     {
    12.         if (other.gameObject.tag=="player")
    13.         {
    14.             canvas.GetComponent<CanvasGroup>().alpha = 1;
    15.             character.GetComponent<Character>().AnimStop();
    16.         }
    17.     }
    18. }
    For my script I created a public GameObject which is the object holding the script I want to access, so I would drag that object in the inspector view and then the "character.GetComponent<Character>().AnimStop();" line is what you're looking for, "character" is my reference for the gameobject within this script, "<Character>" is the name of the script and "AnimStop" is the name of the function I wanted to call,,,
     
  23. mrsev

    mrsev

    Joined:
    Oct 1, 2016
    Posts:
    2
    Yup don't forget he function in the script A has to be set public, otherwise can't access it from the script B

    public void FunctionOnScriptA()
    {
    }
     
  24. mistergreen2016

    mistergreen2016

    Joined:
    Dec 4, 2016
    Posts:
    226
    +1
    Don't forget to TO make your function PUBLIC!
     
    UtopianKing likes this.
  25. Indra_O

    Indra_O

    Joined:
    May 9, 2017
    Posts:
    2
    all I needed was this
     
    UtopianKing likes this.
  26. PrOScANneRDiV

    PrOScANneRDiV

    Joined:
    Feb 1, 2018
    Posts:
    1
    I had the same problem. U can use this:
    scriptB:

    GetComponent<scriptA>().test();

    And also don't forget to make your function public! If u don't know, then look at and copy this:
    scriptA:

    public void test() {
    //Whatever code u have here
    }

    Hope this works for u. ;)
     
    Last edited: Feb 1, 2018
    VVubbas, AlexArts and Laniemme like this.
  27. MysticInteractive

    MysticInteractive

    Joined:
    May 13, 2018
    Posts:
    2
    This would be the best way to access another script. In the script below. I have another script called MyScript2. And I am trying to call a function from MyScript2 in MyScript. So I use "gameObject.GetComponent" to get a component. Then I use "<MyScript2>()" to get MyScript2. And then finally, I use ".MyFunction()" to get the function that I want to call from MyScript2. It is as easy as that!

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using Systems.Collections;
    3. using UnityEngine;
    4.  
    5. public class MyScript : MonoBehaviour
    6. {
    7.      void Start()
    8.      {
    9.            gameObject.GetComponent<MyScript2>().MyFunction();
    10.      }
    11. {
     
    kortexx007 and agbeyeid like this.
  28. killaonmocospace

    killaonmocospace

    Joined:
    Apr 20, 2018
    Posts:
    1
    APTEM59 likes this.
  29. bitlysub2anf

    bitlysub2anf

    Joined:
    May 8, 2020
    Posts:
    71
    It's been 10 YEARS and nobody could give a simple straightforward answer┗( T﹏T )┛
     
  30. Recluse

    Recluse

    Joined:
    May 16, 2010
    Posts:
    476
    If you have an instance of the other script in the scene (let's call it 'RocketLauncher' in this case) you can drag it into the 'myRocketLauncher' public variable in the inspector on your calling script (in this case 'launchControl'), which will save repeatedly calling GetComponent. You can call any public functions on that script (for example a 'Fire' function) as in Start() below....

    Code (CSharp):
    1. public class launchControl : MonoBehaviour
    2. {
    3.  
    4.     public rocketLauncher myRocketLauncher;
    5.  
    6.     void Start()
    7.     {
    8.        myRocketLauncher.Fire();
    9.     }
    10.  
    11.  
    12. }
    If you don't have an instance in the scene you will need to find it at start. If the script is a singleton (like a level manager), you can make a public static instance so all other scripts can access it without needing to find it first.
     
    kabyy likes this.
  31. DigitalHardware

    DigitalHardware

    Joined:
    Oct 30, 2016
    Posts:
    12
    I'm sure somewhere in this thread is the solution to my problem, but I can't figure it out :(

    Here's my post - if anyone can help that would be appreciated.
    https://forum.unity.com/threads/noo...-code-from-another-script-not-working.903830/

    In a nutshell, I want to take the value of the lap time and use it in the script which triggers when the finish line is crossed. IF I run the track twice, it works, but on one lap it doesn't - which means the value isn't being read at the right time?
     
  32. mistergreen2016

    mistergreen2016

    Joined:
    Dec 4, 2016
    Posts:
    226
    There's no one answer because there are multiple solutions.
     
  33. MFKJ

    MFKJ

    Joined:
    May 13, 2015
    Posts:
    264
    Call one script method from another script in unity C#. Here is 2-minute explanation:
     
  34. irshadgirachirshu

    irshadgirachirshu

    Joined:
    Sep 14, 2020
    Posts:
    7
    Thank you! This helped me big time :)
     
  35. LSchou

    LSchou

    Joined:
    Sep 12, 2015
    Posts:
    2
  36. neo-mashiro

    neo-mashiro

    Joined:
    Aug 7, 2020
    Posts:
    19
    It's easy to drag ScriptB's game object onto a public field in ScriptA, so that ScriptA can call any public functions in ScriptB. But what if the function is frequently called???

    So for example, I have a player script which has a public method TakeDamage(), it's going to be called by many other game objects (various things that can deal damage to the player, such as enemies, other players, danger zone effects, debuffs, skills, explosions and even special items).

    Ofc the drag-and-call or GetComponent works fine, but I don't want to do it for every gameobject, which can mess up my editor window, and I think it's a very bad design. If some function in ScriptB is universal and commonly used, there must be a better way to do it, any ideas?
     
  37. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    This is where interfaces come in handy. A common example in this case is to create an "IDamageable" interface:
    Code (CSharp):
    1. public interface IDamageable {
    2.    void TakeDamage(float damage);
    3. }
    Then implement this interface in any script that you want to be able to take damage, like your player script, for instance:
    Code (CSharp):
    1. public class Player : MonoBehaviour, IDamageable {
    2.    public void TakeDamage(float damage) {
    3.       //etc..
    4.    }
    5. }
    Elsewhere, where you have some other script that deals the damage, all it would need to do is
    GetComponent<IDamageable>()
    , then call the
    TakeDamage
    method:
    Code (CSharp):
    1. public class SomeScriptThatDealsDamageOnCollision : MonoBehaviour {
    2.    void OnCollisionEnter(Collision collision) {
    3.       IDamageable damageable = collision.gameObject.GetComponent<IDamageable>();
    4.  
    5.       if(damageable != null) {
    6.          damageable.TakeDamage(10);
    7.       }
    8.    }
    9. }
    It doesn't need to know or care what the actual component is that it gets, just that it gets one that has the
    TakeDamage
    method.

    This setup is very modular as well. Maybe later down the line you want to change which objects can be damaged & which cannot; it's as easy as adding/removing the
    IDamageable
    interface in their scripts.
     
  38. neo-mashiro

    neo-mashiro

    Joined:
    Aug 7, 2020
    Posts:
    19
    Thank you, this is very helpful.

    Few hours ago I was thinking about a more universal way, to wrap the function into sth like a static function, but I was just stupid because it's not possible to reference an instance variable in a static context. You are right, I think interface is indeed the best way to do it.
     
  39. ChillCo

    ChillCo

    Joined:
    Dec 31, 2021
    Posts:
    1
    so wait i have a (possibly dumb sounding) question, is there a way to acess script code from scripts in the assets folder? or just assets generally? i had an idea about a game that manipulated assets and files but anyway what if i have a script that is supposed to pull the strings behind the actual game, and what if i dont want to attach that to a particular game object, simply for organization and bug reasons?
     
  40. deaa86_arch

    deaa86_arch

    Joined:
    Mar 1, 2022
    Posts:
    4
    This video shows how to call a method from another script:
     
  41. roopesh23

    roopesh23

    Joined:
    Jul 11, 2022
    Posts:
    6
    Thanks so much for this, it just saved me! I kept looking and making changes but nothing worked, thanks for this.
     
  42. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    29,854
    Referencing variables, fields, methods (anything non-static) in other script instances:

    https://forum.unity.com/threads/hel...-vars-in-another-script.1076825/#post-6944639

    https://forum.unity.com/threads/accessing-a-gameobject-in-different-scene.1103239/

    REMEMBER: it isn't always the best idea for everything to access everything else all over the place. For instance, it is BAD for the player to reach into an enemy and reduce his health.

    Instead there should be a function you call on the enemy to reduce his health. All the same rules apply for the above steps: the function must be public AND you need a reference to the class instance.

    That way the enemy (and only the enemy) has code to reduce his health and simultaneously do anything else, such as kill him or make him reel from the impact, and all that code is centralized in one place.