Inheritance is one way (as Mr-Men said), using SendMessage is another. SendMessage uses Unity’s messaging system and is more suited for component based design. So you simply create two scripts. The first one has an OnTriggerStay2D method where you can check if a certain key is pressed while the player is inside that trigger. If so you simply send a message to “Interact”. Another script can simply implement an “Interact” method which will be called automatically.
public class TriggerActivator : MonoBehaviour
{
public KeyCode key = KeyCode.E;
public string activationTag = "Player";
void OnTriggerStay2D(Collider2D aOther)
{
if (aOther.gameObject.CompareTag(activationTag) && Input.GetKeyDown(key))
SendMessage("OnInteract",aOther.gameObject, SendMessageOptions.DontRequireReceiver);
}
}
This script, when attached to an object in the scene will send an “OnInteract” message to other scripts on the same object. So if you attach another script like this:
public class AmmoContainer : MonoBehaviour
{
public void OnInteract(GameObject aOther)
{
Debug.Log("object '"+aOther.name+"' has interacted with this AmmoContainer at " + transform.position);
}
}
Usually the passed gameobject will be the player object since by default we check for the tag “Player”.
Another way is to reverse the logic which is often the better way. So you would have the TriggerActivator on the player object and have it send a message to objects the player collides with. For this you would have to change the class slightly and of course attach it to the player instead of the actual object:
public class TriggerActivator : MonoBehaviour
{
public KeyCode key = KeyCode.E;
void OnTriggerStay2D(Collider2D aOther)
{
if (Input.GetKeyDown(key))
aOther.gameObject.SendMessage("OnInteract",gameObject, SendMessageOptions.DontRequireReceiver);
}
}
This has the advantage that you only need one instance of the TriggerActivator on the player. Every time you press the button “e” it will simply send a message to all objects that are current touching / overlapping with the player.
Instead of “messages” you could also use interfaces. Using interfaces has the advantage that you can’t misspell the “message name”. However it would require to use GetComponent on the target object to aquire that interface.
Example:
public interface IInteractable
{
void Interact(GameObject aOther);
}
public class TriggerActivator : MonoBehaviour
{
public KeyCode key = KeyCode.E;
void OnTriggerStay2D(Collider2D aOther)
{
if (Input.GetKeyDown(key))
{
var interactable = aOther.GetComponent<IInteratable>();
if (interactable != null)
interactable.Interact(gameObject);
}
}
}
A script on the other object can now implement that interface:
public class AmmoContainer : MonoBehaviour, IInteractable
{
public void Interact(GameObject aOther)
{
Debug.Log("object '"+aOther.name+"' has interacted with this AmmoContainer at " + transform.position);
}
}
This will automatically call the Interact method on any class that implements that interface.