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

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:

public class Destructible : MonoBehaviour {

    public GameObject wreck;
    public GameObject orig;
    void OnMouseDown()
    {
        boom ();
    }

    void Start()
    {
        orig = gameObject;
    }
    public void boom()
    {
        Instantiate (wreck, transform.position, transform.rotation);
        Destroy (orig);
    }
}

And using another script- laser, I want to destroy it.
public class Laser : MonoBehaviour {

    LineRenderer Line;
    private PlayerController player;
    public Destructible des;
    public float laserStrenght;
    void Start ()
    {
        Line = gameObject.GetComponent<LineRenderer> ();
        player = (PlayerController)FindObjectOfType(typeof(PlayerController));
        //des = (Destructible)FindObjectOfType (typeof(Destructible));
        Line.enabled = false; 
    }
 
    // Update is called once per frame
    void Update ()
    {
        if(Input.GetButtonDown("Fire1"));
        {
            StopCoroutine("FireLaser");
            StartCoroutine ("FireLaser");
        }
    }
    IEnumerator FireLaser()
    {
        Line.enabled = true;
        if(player.acceleration <=100)
        while (Input.GetButton("Fire1"))
        {
            Line.material.mainTextureOffset = new Vector2(0, Time.time*3);
            Ray ray = new Ray(transform.position, transform.forward);
            RaycastHit hit;
            Line.SetPosition(0, ray.origin);
            if(Physics.Raycast (ray, out hit, 100))
                Line.SetPosition (1, hit.point);
            if(hit.transform.gameObject.tag == "Destructable")
            {
                des.boom ();//<<<-------My problem ( I can use this function, but not variables local to that //gameObject
            }
            if(hit.rigidbody)
            {
                hit.rigidbody.AddForceAtPosition(transform.forward * laserStrenght, hit.point);
            }

            Line.SetPosition(1, ray.GetPoint(100));
            yield return null;
        }
                            Line.enabled = false;
    }
}

Also another side problem I have is this error:
NullReferenceException: Object reference not set to an instance of an object
Laser+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:)

code tags pls
Button on the left of the floppy disk Icon and than “Code”

1 Like

The “boom()” function is “des” script has to be public.
Type it like this:

public void boom()
{
//...Code here...
}
1 Like

try using GameObject.GetComponent to assign the Destructable script to des reference.

1 Like

Sorry, I am new to forum, thank you for a tip:)

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?

Hey, thank you for a fast reply, but it’s already public

gameObjectName.GetComponent<ScriptName>().gameObjectToEdit.variable...

For example:
If you want to change the name of it…

gameObjectName.GetComponent<ScriptName>().gameObjectToEdit.name = "New Name";
1 Like

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.

if(hit.transform.gameObject.tag == "Destructable")
            {
                gameObject.GetComponent<>(Destructible).boom();
            }

p.s. I want to use the script inside the current gameObject that I am using (the one that has Laser script attached).

if(hit.transform.gameObject.tag == "Destructable")
            {
                des = gameObject.GetComponent<Destructible>();
                 des.boom();
            }

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…

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!

public GameObject myObj;

void Start()
{
     myObj.GetComponent<Script>()...
}
1 Like

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

if(hit.transform.gameObject.tag == "Destructible")
            {
                gameObject.GetComponent<>(Destructible).gameObject.boom();
            }

if the script is on the gameObject then get it at start and use the reference to access boom in the if statement.

void Start()
    {
        des = gameObject.GetComponent<Desctructible> ();
    }

the gameObject doesnt hold the function it holds thet class thats holds the function.

1 Like

Yep, that’s what I reminded him about but I guess he did not see it.

1 Like

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.

    toDestroy= hit.transform.gameObject; 
            if(toDestroy.tag == "Destructible")
            {
                //toDestroy.GetComponent<Destructible>(); //ray casting gets object WITH all components?
                toDestroy.boom() //why doesnt it find the method boom()?
            }

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.

I noticed that one too:smile: Sadly it’s still smth wrong.

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:

toDestroy= hit.transform.gameObject;
            
if(toDestroy.tag == "Destructible")
{
       //toDestroy.GetComponent<Destructible>(); 
       toDestroy.GetComponent<Destructible>().boom();
}
1 Like

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.

1 Like