First off, newbie disclaimer: Started self-teaching myself Unity and C# in February, so still learning my way around things, so please be gentle, lol! I’m using 2021.3.20f1, if that makes any difference.
I’m trying to use raycasting instead of OnMouseOver/Exit for my interactable objects, because from what I understand raycasting is better for VR, which is something I would like to explore down the line.
For the most part, I’ve got it working pretty well, but if there are two interactable objects near each other (eg: a light switch next to a door) or nested one inside the other (eg: a collectable object hidden within a drawer), the OnLoseFocus and OnInteract functions start to get glitchy.
For example, in the case of the light switch next to the door: say the light switch is to the left of the door, if the player is focusing on the light switch and then looks right (toward the door), the light switch will get stuck in “OnFocus” even after the player is not looking at either object. If the player looks right (away from the door, and therefore not at anything interactable), the light switch behaves as it should and transfers from “OnFocus” to “OnLoseFocus.”
Similar glitch occurs with the second case I mentioned (interactable object nested within another interactable object), except that it doesn’t matter which way you look, it just stays stuck in “OnFocus.”
How this manifests itself in the individual scripts varies from case-to-case. Sometimes if the object is set to be highlighted when in “OnFocus” the object will stay highlighted, other times if there is a UI message prompt reminding the player which key to press to interact the prompt will remain on screen until another prompt cancels it out, and then in other instances if it’s a collectable object and there’s a UI prompt letting the player know that they collected the object after “OnInteract,” that prompt will not delete itself after the 3 seconds I’ve set it to.
There doesn’t seem to be any consistency between these various glitches, but I’ve narrowed it down to the one constant for all of them being related to an interactable object being too close to another one, and the OnFocus function getting stuck - what I don’t know is how to go about fixing that!
I’m currently working on a compromise of using a mixture of raycasting and OnMouseOver, but would like to have it be more uniform, if I can (and I’m sure there must be a way). Here are the portions of my FPS controller that pertains to interaction (the whole FPS controller is roughly 900 lines of code, so I figured cut-and-paste would be more efficient in this instance):
public class FirstPersonController : MonoBehaviour
{
[Header("Interaction")]
[SerializeField] private Vector3 interactionRayPoint = default;
[SerializeField] private float interactionDistance = default;
[SerializeField] private LayerMask interactionLayer = default;
private Interactable currentInteractable;
void Update()
{
if (canInteract)
{
HandleInteractionCheck();
HandleInteractionInput();
}
ApplyFinalMovements();
}
}
private void HandleInteractionCheck()
{
if (Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint), out RaycastHit hit, interactionDistance))
{
if (hit.collider.gameObject.layer == 3 && (currentInteractable == null || hit.collider.gameObject.GetInstanceID() != currentInteractable.GetInstanceID()))
{
hit.collider.TryGetComponent(out currentInteractable);
if (currentInteractable)
currentInteractable.OnFocus();
}
}
else if (currentInteractable)
{
currentInteractable.OnLoseFocus();
currentInteractable = null;
}
}
private void HandleInteractionInput()
{
if (Input.GetKeyDown(interactKey) && currentInteractable != null && Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint), out RaycastHit hit, interactionDistance, interactionLayer))
{
currentInteractable.OnInteract();
}
}
}



