C# and Script Declaration

I’m currently working on a button/switch system where I have a GameObject that is the button/switch, which has a list of GameObjects that can be added to its script in order to trigger a script in those GameObjects on or off. My issue is that I need to access a public function of these objects that get triggered by the button. Unfortunately, C# requires me to declare what script I am using. What I want to do is have the code be able to run the same function that is in two different scripts.

Currently I’m storing the scripts in a list, and when the button is pressed, it goes through this list to do a ‘turn object on’ function. But, since I need to declare what type the script is, I can’t do this for two different types of ‘triggered objects’.

The only solution I can see is running a loop through every type of object that would be triggered, which seems pretty horrible. But, that would look like this:

void Start () {
		for(int i = 0; i < objects.Count; i++){
			switch (objects[i].gameObject.layer){
				case 1:
					MovingPlatform pScript = objects[i].GetComponent<MovingPlatform>();
					mPlatformScripts.Add(pScript);
					break;
				case 2:
					SwitchBlock sScript = objects[i].GetComponent<SwitchBlock>();
					sBlockScripts.Add(sScript);
					break;
                               case etc: ...
			}
		}
}

public void ButtonOn(){
	on = true;
	transform.position = onPos;
	for(int i = 0; i < mPlatformScripts.Count; i++){
		mPlatformScripts[i].TriggerOn();
	}
        for(int i = 0; i < sBlockScripts.Count; i++){
		sBlockScripts[i].TriggerOn();
	}
        for (etc...)
}

Any suggestions? Maybe an alternate method for this?

Use interfaces:

public class MovingPlatform : MonoBehaviour, ISwitchListener
{
	public void TriggerOn()
	{
		//do stuff
	}
}
public class SwitchBlock : MonoBehaviour, ISwitchListener
{
	public void TriggerOn()
	{
		//do stuff
	}
}

public interface ISwitchListener
{
	void TriggerOn();
}

//in your main script (the one you posted)
List<ISwitchListener> listenerScripts = new List<ISwitchListener>();

private void Start () 
{
	//actually, this part might have an easier way.  To be honest, I'm not sure if GetComponent<ISwitchListener> would work, but it'd be awesome if it did!  TRY! :smile:
	for(int i = 0; i < objects.Count; i++){
		switch (objects[i].gameObject.layer){
			case 1:
				MovingPlatform pScript = objects[i].GetComponent<MovingPlatform>();
				listenerScripts.Add(pScript);
				break;
			case 2:
				SwitchBlock sScript = objects[i].GetComponent<SwitchBlock>();
				listenerScripts.Add(sScript);
				break;
	               case etc: ...
		}
	}
}

public void ButtonOn()
{
	on = true;
	transform.position = onPos;
	
	foreach(ISwitchListener listener in this.listenerScripts)
	{
		listener.TriggerOn();
	}
}

You COULD also inherit from a different base class than MonoBehaviour, but this sounds more like a job for interfaces than subclassing.

Thanks. This is absolutely perfect for what I’m doing.

For others, further reading: Interfaces - define behavior for multiple types - C# | Microsoft Learn