Checking for touching objects?

There’s a method I’ve been using for a couple years that has always bugged me, and lately I’ve been running into problems because of it. I’m really wondering if there is a better way.

What this basically comes down to is: is there a way that I can have an object check if/what objects are touching it at any given moment?

Here’s a practical example.
I’ve got a 2D sidescroller, and I’ve got special objects that the player interacts with when they press “up,” like switches on a wall or doors that they enter or other things. To function, the script on the switch/door needs to know when the player presses “up” when the player is touching it.
Normally, I would want to call this functionality within my player’s script. The player just pressed up, so we check if the player is touching any switches/doors/ladders/signs/etc. If so, then we call the script within that switch/etc. This runs efficiently because we only check those things when the button is pressed, and we can regulate what kind of objects take priority right within the player.

However, I know of no way for an object to check to see if any objects are touching it at any given moment. We have functions that get called when an object first touches another, every frame they touch, and when they stop touching. But not a function that gets called whenever I want to look for things that are touching. (Unless I already have an explicit reference to both objects, which I don’t.)

The only ways I know to achieve the functionality I need are all wasteful on resources.
I could check for objects within OnTriggerStay2D, but this would get called EVERY FRAME, so I would need to check every frame that an object is touching something. If I call this within the player, I’m wasting cycles every single frame that I’m touching anything from any direction. If I call this from the switch, then I still waste cycles checking every object that touches it to see if said object is the player, and when it is the player then I still have to check every single frame if the player is pressing the up button, which also necessitates having the player declare every frame if they are pressing the up button.

This is just so wasteful. It may work and it isn’t likely to drop frames, but it just adds to the load the game is running. There really ought to be a more efficient and direct way to look for this kind of stuff.
Am I missing something? This is just the method I resigned to years ago when I was still new to Unity. Is there a better way?

The only other method I can think of is even more inefficient, and that would be to have the player keep a list of all objects it is touching and then cycle through them when a specific action is called. That’s going to eat up more resources and open up more ways to get screwed up somehow.

Why not attach a script to whatever gameobject you’re looking for and then have a boolean turn to true whenever it touches the gameobject you want to? Then you would simply have the player fire a raycast at the gameobject then you get the boolean from the gameobject you want to know is touching another gameobject and do whatever you want when the player is looking at it if I’m understanding this correctly. You would do this using something like GetTouchBooleanScript getTouchBooleanScript = hit.gameobject.GetComponent().touchBoolean in an if statement.

The tools you need are all there, it’s just sometimes unity doesn’t have them built in like you point out and you have to get creative and know how the engine works properly. It doesn’t mean though that it’s impossible to do, just a bit tricky if you’ve never experimented with it before.