Public variable containing script

I have a script that shoots a laser and when it hits a certain object it gets a script and sets a bool to true, so that script knows it’s being hit by the laser.

However I am using the laser in multiple stages and so each object should react differently and therefore have different scripts, so I need something like this:

Public Script objectScript;
Public GameObject object;

void Update ()
{
    object.GetComponent<objectScript> ().LaserHitting = true;
}

Firstly, let me make sure I understand what you’re asking: You have a laser object, and several other objects, and you want each of these other objects to react differently when the laser hits them?

Of the many ways to do this, one way would be to use the OnCollisionEnter message for the objects being hit, and check if the other object that collided with it is a laser object (for example, by calling GetComponent<Laser> != null, or checking the collider’s physics layer ID if lasers have a physics layer all to themselves).

So it would be something like

public class Squirrel : MonoBehaviour
{
	void OnCollisionEnter(Collision collision)
	{
		// if the object that collided with this has a Laser component
		if (collision.gameObject.GetComponent<Laser> != null)
		{
			this.doWhatTheSquirrelDoesWhenHitByALaser();
		}
	}
}

There are several ways to accomplish that. First of all changing a public variable on another script is bad design. Strict OOP doesn’t know something like public fields / variable. Interactions with other classes should always be done through methods.

First approach is using an interface. You can define an interface with some specific methods which every class that implements that interface has to provide. Your laser can simple search for that interface and GetComponent will return the first class that implements that interface:

public interface ILaserTargetable
{
    void HitByLaser();
}

public class SomeScript : MonoBehaviour, ILaserTargetable
{
    // ...
    public void HitByLaser()
    {
        // do something
    }
}

// in your laser class you can do:

ILaserTargetable target = hitObject.GetComponent<ILaserTargetable>();
if (target != null)
{
    // we found a class that implements "ILaserTargetable", so call HitByLaser:
    target.HitByLaser();
}

Another solution is to use Unity’s SendMessage. This is the most easiest way. In your laser script you can simply call SendMessage on the target gameobject and specify the name of method that should be called as string. Now the script on the object that you hit just need to implement that method:

public class SomeScript : MonoBehaviour
{
    public void HitByLaser()
    {
        // do something
    }
}

// in your laser class you can do:

hitObject.SendMessage("HitByLaser");

Note that SendMessage will throw an error if there is no script on the hitObject that has a method with that name. However you can pass “SendMessageOptions.DontRequireReceiver” as additional parameter. This will just send off the message and if there’s a script with a method with the specified name, that method will be called, if not nothing will happen.

SendMessage has a slight overhead. So it’s not recommended to use it every frame. However for most hit event propergation there’s no problem.

Instead of an interface one could also use a baseclass from which all your other script are derived from. However since Unity encourages object composition through components instead of class inheritance, this is not very flexible and i wouldn’t recommend it. Inheritance only makes sense when large amount of those scripts are basically the same and just small parts are different.