Activate event on key press?

I’ve been trying to figure out how to get something to happen on a key press (like the typical “Press E to use” in games) but only have something happen when faced with the object I want to be used in stead of the event happening anywhere I press the button. So for reference, currently I have a plant that gets picked when pressing “E”. I also want to use “E” to activate a bed and sleep (currently just makes the screen black with a UII image). I have been using Raycast for these things so pressing “e” only works on the objects with the correct scripts. The problem occurs when trying to use “E” for multiple things. It doesn’t work and I assume it’s because of how raycasting works. I know there must be some way to activate objects and events using a better method…but how does one do that?

The two scripts I’m using:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField] Camera FPCamera;
    [SerializeField] float range = 5f;

    WildPlants plantTarget;
    Sleep sleepTarget;

    void Start()
    {
        plantTarget = GetComponent<WildPlants>();
        sleepTarget = GetComponent<Sleep>();
    }

    void Update()
    {
        PressUseKey();
    }

    public void PressUseKey()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            RaycastHit hit;
            var raycastThing = Physics.Raycast(FPCamera.transform.position, FPCamera.transform.forward, out hit, range);
            if (raycastThing)
            {                
                WildPlants plantTarget = hit.transform.GetComponent<WildPlants>();
                if (plantTarget == null) { return; }
                plantTarget.ProcessPlantPicking();
            }            
            else { return; }
        }
        /*if (Input.GetKeyDown(KeyCode.E))
        {
            RaycastHit hit;
            if (Physics.Raycast(FPCamera.transform.position, FPCamera.transform.forward, out hit, range))
            {                
                Sleep sleepTarget = hit.transform.GetComponent<Sleep>();                
                if (sleepTarget == null) { return; }                
                sleepTarget.Fade();
                print("does it work?");
            }
            else { return; }
        }*/
    }
}

And:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WildPlants : MonoBehaviour
{
    [SerializeField] float growthRate = 5f;
    [SerializeField] GameObject grownPlant;
    [SerializeField] GameObject pickedPlant;
    [SerializeField] Collider emptyCollider;

    [SerializeField] bool isPicked = false;

    Renderer cubeRenderer;    

    void Start()
    {
        emptyCollider = GetComponent<Collider>();
        cubeRenderer = grownPlant.GetComponent<Renderer>();       
        isPicked = false;
        cubeRenderer.material.SetColor("_Color", Color.green);       
    }
    
    void Update()
    {
        
    }    
    
    public void ProcessPlantPicking()
    {
        if (isPicked == false)
        {
            StartCoroutine(PlantIsPicked());            
            print("Plant put in inventory");
        }
        else if (isPicked == true)
        {
            return;
        }        
    }

    IEnumerator PlantIsPicked()
    {
        //cubeRenderer.material.SetColor("_Color", Color.red);         
        grownPlant.SetActive(false);
        emptyCollider.enabled = false;
        pickedPlant.SetActive(true);
        yield return new WaitForSecondsRealtime(growthRate);
        isPicked = false;
        emptyCollider.enabled = true;
        grownPlant.SetActive(true);
        pickedPlant.SetActive(false);        
    }    
}

Raycasting is what you’ll need know what object to press. You can probably just put a single forward raycast in every frame if you want the ‘press E’ prompt to appear.

You can have one script that tests every possible script, but that’s not efficient at all, and is almost guaranteed to lead to spaghetti code. You’d be better off either using an interface with the Interact method in it, and then each object’s script will use that interface. That way, you can just check if what you’re pointing at is has the interface, and just call the Interact method if it does.

Use interfaces. I will show you general idea, and then you will be able to built your system upon it. So, at first create interface. I called it IInteractable and it has one method - DoSomething. You can put it in any script you like - I put it just below your Player class in Player script. It means that every class which want to implement the IInteractable interface is forced to create DoSomething method. So, I make your WildPlants and Sleep classes implement it. Finally, when you press E you search for IInteractable component. As WildPlants and Sleep implement this interface, Unity will invoke proper method from proper class.
Player script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField] Camera FPCamera;
	[SerializeField] float range = 100f;
	
	void Update()
	{
		if (Input.GetKeyDown(KeyCode.E))
		{
			RaycastHit hit;
			var raycastThing = Physics.Raycast(FPCamera.transform.position, FPCamera.transform.forward, out hit, range);
			
			if (raycastThing)
			{
				IInteractable interactable = hit.transform.GetComponent<IInteractable>();
				
				if (interactable!=null)
					interactable.DoSomething();
			}
		}
	}
}

public interface IInteractable
{
	void DoSomething();
}

WildPlants script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WildPlants : MonoBehaviour, IInteractable
{
	public void DoSomething()
	{
		Debug.Log("WildPlants");
	}

}

Sleep script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sleep : MonoBehaviour, IInteractable
{
	public void DoSomething()
	{
		Debug.Log("Sleep");
	}
}

I compared with other scripts to make sure I at least typed it all correctly and it does appear I have. I have named the methods the generic stuff you had in your example just for testing
What am I missing here?

Player

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    [SerializeField] Camera FPCamera;
    [SerializeField] float range = 5f;

    WildPlants plantTarget;
    Sleep sleepTarget;

    void Start()
    {
        plantTarget = GetComponent<WildPlants>();
        sleepTarget = GetComponent<Sleep>();
    }

    void Update()
    {
        PressUseKey();
    }

    public interface Interactables
    {
        void DoSomething();
    }

    public void PressUseKey()
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            RaycastHit hit;
            var raycastThing = Physics.Raycast(FPCamera.transform.position, FPCamera.transform.forward, out hit, range);
            if (raycastThing)
            {
                Interactables interactable = hit.transform.GetComponent<Interactables>();

                if (interactable != null)
                interactable.DoSomething();
            }
            else { return; }
        }
        /*if (Input.GetKeyDown(KeyCode.E))
        {
            RaycastHit hit;
            if (Physics.Raycast(FPCamera.transform.position, FPCamera.transform.forward, out hit, range))
            {                
                Sleep sleepTarget = hit.transform.GetComponent<Sleep>();                
                if (sleepTarget == null) { return; }                
                sleepTarget.Fade();
                print("does it work?");
            }
            else { return; }
        }*/

    }

    
}

WildPlants

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WildPlants : MonoBehaviour, Interactables
{
    [SerializeField] float growthRate = 5f;
    [SerializeField] GameObject grownPlant;
    [SerializeField] GameObject pickedPlant;
    [SerializeField] Collider emptyCollider;

    [SerializeField] bool isPicked = false;

    Renderer cubeRenderer;    

    void Start()
    {
        emptyCollider = GetComponent<Collider>();
        cubeRenderer = grownPlant.GetComponent<Renderer>();       
        isPicked = false;
        cubeRenderer.material.SetColor("_Color", Color.green);       
    }

    void Update()
    {

    }    

    public void DoSomething()
    {
        Debug.Log("WildPlants");
    }
    
    public void ProcessPlantPicking()
    {
        if (isPicked == false)
        {
            StartCoroutine(PlantIsPicked());            
            print("Plant put in inventory");
        }
        else if (isPicked == true)
        {
            return;
        }        
    }

    IEnumerator PlantIsPicked()
    {
        //cubeRenderer.material.SetColor("_Color", Color.red);         
        grownPlant.SetActive(false);
        emptyCollider.enabled = false;
        pickedPlant.SetActive(true);
        yield return new WaitForSecondsRealtime(growthRate);
        isPicked = false;
        emptyCollider.enabled = true;
        grownPlant.SetActive(true);
        pickedPlant.SetActive(false);        
    }    
}