How do I access the script of an unknown gameobject?

So basically what I want to do is this:

 if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out rayHit, Mathf.Infinity, unitLayer))
            {
                Collider unitSelected = rayHit.collider;
                unitSelected.GetComponent<Script>().selected = !unitSelected.GetComponent<Script>().selected;
            }

But obviously I can’t just put ‘Script’ in Getcomponent<>(). All scripts in UnitLayer are different but all have the ‘selected’ field.

Hi!

This can be achieved through inheritance! Basically you can start by defining some base class that will have any functionality that is shared between these classes:

public abstract class BaseUnit : MonoBehaviour
{
    public bool IsSelected;
    public float MaxHealth;
    public float CurrentHealth;

    public virtual void TakeDamage()
    {
        if (CurrentHealth <= 0)
        {
            Destroy(this.gameObject);
        }
    }
}

And then have your other scripts inherit from this base class, instead of from MonoBehaviour:

public class FriendlyUnit : BaseUnit
{
    public GameObject GameOverScreen;
    public override void TakeDamage()
    {
        base.TakeDamage();
        if (CurrentHealth <= 0)
        {
            GameOverScreen.SetActive(true);
        }
    }
}
public class EnemyUnit : BaseUnit
{
    public float EvilnessFactor;
        
    //...
}

Notice that you can add unique fields and methods to both of these classes.

You can even override how a method might work if you put the virtual keyword in the base class. In this scenario, a game over screen might appear when you’re out of health, but crucially, this screen will not appear when an enemy is killed.

public class Goomba : EnemyUnit
{
    public override void TakeDamage()
    {
        //This enemy always gets one-shot
        Destroy(this.gameObject);
    }
}

You can even derive from one of those classes and preserve the same symmetries. Here the goomba skips the rest of the damage calulation and just dies.
Here is how you might implement it, including if you want to grab for example a variable unique to the enemy:

public class UnitController : MonoBehaviour
{
    private void Update()
    {
        RaycastHit rayHit;
        if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out rayHit, Mathf.Infinity))
        {
            //GetComponent will look not just for the BaseUnit class, but also any derived classes, like FriendlyUnit, EnemyUnit and Goomba
            BaseUnit unit = rayHit.collider.GetComponent<BaseUnit>();

            unit.IsSelected = !unit.IsSelected;

            unit.TakeDamage();

            if(unit is EnemyUnit)
            {
                (unit as EnemyUnit).EvilnessFactor = 5;
            }
        }
    }
}

Hope this helps :smiley:

Hello!

Thats not possible, as scripts are classes.

But, Why you would do that? You should know what you want to get… DId you created different objects that have “similar properties” in different scipts?? Bad idea.

What you can do is to check all kinds, for example, lets imagine this misterious script can be only one of this scripts:

ScriptA
ScriptB
ScriptC
...

Then, you need to

if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out rayHit, Mathf.Infinity, unitLayer))
             {
                 Collider unitSelected = rayHit.collider;
                 if (unitSelected.GetComponent<ScriptA>!= null) Do something with scriptA
                 else if (unitSelected.GetComponent<ScriptB>!= null) Do something with scriptB
                 else if (unitSelected.GetComponent<ScriptC>!= null) Do something with scriptC
                 ... 
             }

Bye!!