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

[Answered]Accessing a script from another script and using it's gameObject variable

Discussion in 'Scripting' started by AlmantusK, Oct 7, 2015.

  1. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    Hello, I am pretty new to Unity and I was having a problem of using one script from another. I know how to use functions and simple public variables (like float, vectors, ints and so on) in one script from another, but I don't know how to get public variables, that are other game objects. In my case, I want to simulate an object destruction on rayCast hit, thus I want to replace one object with another.
    I have this code on my destructable object:
    Code (csharp):
    1.  
    2. public class Destructible : MonoBehaviour {
    3.  
    4.     public GameObject wreck;
    5.     public GameObject orig;
    6.     void OnMouseDown()
    7.     {
    8.         boom ();
    9.     }
    10.  
    11.     void Start()
    12.     {
    13.         orig = gameObject;
    14.     }
    15.     public void boom()
    16.     {
    17.         Instantiate (wreck, transform.position, transform.rotation);
    18.         Destroy (orig);
    19.     }
    20. }
    21.  
    And using another script- laser, I want to destroy it.
    public class Laser : MonoBehaviour {
    Code (csharp):
    1.  
    2.     LineRenderer Line;
    3.     private PlayerController player;
    4.     public Destructible des;
    5.     public float laserStrenght;
    6.     void Start ()
    7.     {
    8.         Line = gameObject.GetComponent<LineRenderer> ();
    9.         player = (PlayerController)FindObjectOfType(typeof(PlayerController));
    10.         //des = (Destructible)FindObjectOfType (typeof(Destructible));
    11.         Line.enabled = false;
    12.     }
    13.  
    14.     // Update is called once per frame
    15.     void Update ()
    16.     {
    17.         if(Input.GetButtonDown("Fire1"));
    18.         {
    19.             StopCoroutine("FireLaser");
    20.             StartCoroutine ("FireLaser");
    21.         }
    22.     }
    23.     IEnumerator FireLaser()
    24.     {
    25.         Line.enabled = true;
    26.         if(player.acceleration <=100)
    27.         while (Input.GetButton("Fire1"))
    28.         {
    29.             Line.material.mainTextureOffset = new Vector2(0, Time.time*3);
    30.             Ray ray = new Ray(transform.position, transform.forward);
    31.             RaycastHit hit;
    32.             Line.SetPosition(0, ray.origin);
    33.             if(Physics.Raycast (ray, out hit, 100))
    34.                 Line.SetPosition (1, hit.point);
    35.             if(hit.transform.gameObject.tag == "Destructable")
    36.             {
    37.                 des.boom ();//<<<-------My problem ( I can use this function, but not variables local to that //gameObject
    38.             }
    39.             if(hit.rigidbody)
    40.             {
    41.                 hit.rigidbody.AddForceAtPosition(transform.forward * laserStrenght, hit.point);
    42.             }
    43.  
    44.             Line.SetPosition(1, ray.GetPoint(100));
    45.             yield return null;
    46.         }
    47.                             Line.enabled = false;
    48.     }
    49. }
    50.  
    Also another side problem I have is this error:
    NullReferenceException: Object reference not set to an instance of an object
    Laser+<FireLaser>c__Iterator0.MoveNext () (at Assets/Scripts/Laser.cs:39)
    UnityEngine.MonoBehaviour:StartCoroutine(String)
    Laser:Update() (at Assets/Scripts/Laser.cs:24)
    "
    It happens each time I leave box collider with my laser (lineRenderer).
    I am looking forward to all the help and thank you for your attention:)
     
    Last edited: Oct 7, 2015
  2. martinmr

    martinmr

    Joined:
    Mar 25, 2015
    Posts:
    325
    code tags pls
    Button on the left of the floppy disk Icon and than "Code"
     
    AlmantusK likes this.
  3. Sykoo

    Sykoo

    Joined:
    Jul 25, 2014
    Posts:
    1,394
    The "boom()" function is "des" script has to be public.
    Type it like this:
    Code (CSharp):
    1. public void boom()
    2. {
    3. //...Code here...
    4. }
     
    AlmantusK likes this.
  4. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    try using GameObject.GetComponent to assign the Destructable script to des reference.
     
    AlmantusK likes this.
  5. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    Sorry, I am new to forum, thank you for a tip:)
     
  6. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    Hey, thank you for a tip, but the script is already attached to my gameObject. Will assigning the component get the public variable locally assigned to that specific object?
     
  7. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    Hey, thank you for a fast reply, but it's already public
     
  8. Sykoo

    Sykoo

    Joined:
    Jul 25, 2014
    Posts:
    1,394
    Code (CSharp):
    1. gameObjectName.GetComponent<ScriptName>().gameObjectToEdit.variable...
    For example:
    If you want to change the name of it...
    Code (CSharp):
    1. gameObjectName.GetComponent<ScriptName>().gameObjectToEdit.name = "New Name";
     
    AlmantusK likes this.
  9. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    I try to make this work, so that when my casted ray hits the tagged game object, it does a script attached to it. But it still doesn't work. Seems to be wrong syntax I guess.
    Code (CSharp):
    1.  
    2. if(hit.transform.gameObject.tag == "Destructable")
    3.             {
    4.                 gameObject.GetComponent<>(Destructible).boom();
    5.             }
    6.  
     
  10. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    p.s. I want to use the script inside the current gameObject that I am using (the one that has Laser script attached).
     
  11. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    Code (CSharp):
    1. if(hit.transform.gameObject.tag == "Destructable")
    2.             {
    3.                 des = gameObject.GetComponent<Destructible>();
    4.                  des.boom();
    5.             }
     
  12. Sykoo

    Sykoo

    Joined:
    Jul 25, 2014
    Posts:
    1,394
    Are you aware that your script name is not the same as the tag?
    The tag is called Destructable, whilst scipt is Destructible. Copy the script name Destructible then paste it into the tag instead to make sure it's typed right.

    Edit:
    The script you want to use, called Destructible, is it attached to the gameobject you're coding on right now? Where you check for rays? Because...
    Code (CSharp):
    1. gameObject.GetComponent...
    ...takes the component from current gameobject! If you have another gameobject you need to reach the script at, you should create a new variable, attach that gameobject to it and then call the variable when you are getting the component!
    Code (CSharp):
    1. public GameObject myObj;
    2.  
    3. void Start()
    4. {
    5.      myObj.GetComponent<Script>()...
    6. }
     
    AlmantusK likes this.
  13. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    I changed the tag to Destructible, both in code and in object itself. Still same error: Assets/Scripts/Laser.cs(41,57): error CS1031: Type expected
    Code (CSharp):
    1.  
    2. if(hit.transform.gameObject.tag == "Destructible")
    3.             {
    4.                 gameObject.GetComponent<>(Destructible).gameObject.boom();
    5.             }
    6.  
     
  14. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    if the script is on the gameObject then get it at start and use the reference to access boom in the if statement.
     
  15. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    Code (CSharp):
    1. void Start()
    2.     {
    3.         des = gameObject.GetComponent<Desctructible> ();
    4.     }
    the gameObject doesnt hold the function it holds thet class thats holds the function.
     
    AlmantusK likes this.
  16. Sykoo

    Sykoo

    Joined:
    Jul 25, 2014
    Posts:
    1,394
    Yep, that's what I reminded him about but I guess he did not see it.
     
    AlmantusK likes this.
  17. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    Now I realised 2 things- hit.transform.gameObject is the object that gets hit by a ray AND has already Destructible script attached to it. But it is not visible for me to use if I get only the object.
    Code (CSharp):
    1.  
    2.     toDestroy= hit.transform.gameObject;
    3.             if(toDestroy.tag == "Destructible")
    4.             {
    5.                 //toDestroy.GetComponent<Destructible>(); //ray casting gets object WITH all components?
    6.                 toDestroy.boom() //why doesnt it find the method boom()?
    7.             }
    8.  
    So my question is: do I still need to get component to make it visible for me (to use methods) or do I do smth else? If I get component it still didn't find the boom() method.
    p.s. Sorry for inexperienced and unprofesional questions and bad english.
     
  18. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    I noticed that one too:D Sadly it's still smth wrong.
     
  19. Sykoo

    Sykoo

    Joined:
    Jul 25, 2014
    Posts:
    1,394
    Make the object "invisible" instead of disabling it, because a disabled gameobject's components won't work (naturally).
    Just disable the mesh renderer and collider etc. to make it invisible.

    EDIT:
    You're still not getting component through the code you posted!
    It should be:
    Code (CSharp):
    1.  
    2. toDestroy= hit.transform.gameObject;
    3.            
    4. if(toDestroy.tag == "Destructible")
    5. {
    6.        //toDestroy.GetComponent<Destructible>();
    7.        toDestroy.GetComponent<Destructible>().boom();
    8. }
    9.  
     
    AlmantusK likes this.
  20. Craig8726

    Craig8726

    Joined:
    Jul 5, 2013
    Posts:
    79
    dont worry we were all beginners once.
    you cant access a function directly form a gameObject you need reference to the script component the function is on.
     
    AlmantusK likes this.
  21. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    OMG it works:D Thank you all very much, especially Sykoo and Crag8726 for being patient and helping a noob in need of help:) You guys are the best!
     
  22. Sykoo

    Sykoo

    Joined:
    Jul 25, 2014
    Posts:
    1,394
    Haha glad too see it works! :)
    No problem at all, don't ever hesitate to ask for help here! If you can't seem to find out an answer, you can always PM me here on the forum too!
     
    AlmantusK likes this.
  23. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    Oh and another little thing, not really a big issue but still. Each time when my line renderer leaves the mesh of and object, but still touches box collider, I get a strange error and it sticks to the colider place (intersection with mesh) and moves away only when I leave collider (otherwise it just sticks to the place).
    ----
    By the end of this reply I realised what was the issue. After I leave box collider it has no object anymore, so when I try to access it and set it, it find null. So I just put it in if statement, to set and check the tag only when I hit another object.
     
  24. AlmantusK

    AlmantusK

    Joined:
    Oct 7, 2015
    Posts:
    30
    I am very happy to be a part of this community:) Thank you again!
     
    Sykoo likes this.
  25. Sykoo

    Sykoo

    Joined:
    Jul 25, 2014
    Posts:
    1,394
    You can also have a local gameobject variable (extra one), to set it to be the gameobject you're triggering with by ray. So as soon as...
    Code (CSharp):
    1. //Checks if gameobject exists (enter the name)
    2. if(toDestroy)
    3.     extraObj = otherGameObject;
    4.  
    5.