UI Text not clearing after focus loss on interactable item

54 Views Asked by At

In my Unity project, I created a character control script, which includes a method with a ray cast to check, if the player is currently looking at an interactable object. All objects that the player should interact with are assigned an 'Interactable' layer.

private void HandleInteractionCheck()
{
    int layerMask = 1 << 6;

    if (Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint), out RaycastHit hit, interactionDistance, layerMask))
    {
        if (hit.collider.gameObject.layer == 6 && (currentInteractable == null || hit.collider.gameObject.GetInstanceID() != currentInteractable.GetInstanceID()))
        {
            hit.collider.TryGetComponent(out currentInteractable);

            if (currentInteractable != null)
            {
                currentInteractable.OnFocus();
            }
        }
    } else if (currentInteractable)
    {
        currentInteractable.OnLoseFocus();
        currentInteractable = null;
    }
}

Additionally, I add a script with a OnFocus() and OnLoseFocus() method to the interactable objects, which, on focusing, change the UI TMP_Text object of my canvas to a string message.

This one, for example, changes the UI text to either "Open" or "Close", depending on the state of a door.

public class ActionText : Interactable
{
    [Header("Item Parameters")]
    [SerializeField] private TMP_Text interactionText;
    [SerializeField] private Image knob;

    private opencloseDoor openCloseScript; // <-- the script, which handles opening and closing doors

    private void Start()
    {
        openCloseScript = GetComponent<opencloseDoor>();
    }

    public override void OnFocus()
    {
        interactionText.text = openCloseScript.open ? "Close " + gameObject.name : "Open " + gameObject.name;
        knob.rectTransform.sizeDelta = new Vector2(50, 50);
    }

    public override void OnInteract()
    {
        print("INTERACTED WITH " + gameObject.name);
    }

    public override void OnLoseFocus()
    {
        interactionText.text = string.Empty;
        knob.rectTransform.sizeDelta = new Vector2(15, 15);
    }
}

Problem: This almost works as desired, but sometimes the UI text does not clear when losing focus. The text stays on the screen, as if the player was still looking at the object, although the method of clearing the text itself does appear to work.

This is a demonstration video of the problem

I could not come up with a workaround myself, since I started game development only a short while ago, nor could I find any helpful resources on this specific problem online.

Maybe someone can help me out with this one? I'll gladly provide more details upon request. Help would be much appreciated.


Requested information

Box colliders in the scene:

enter image description here

1

There are 1 best solutions below

0
skaptilian On

Solution

I have managed to find a solution for this problem by adding a check in the HandleInteractionCheck for when the conditions of the second if statement ARE met, but the currentInteractable is not null.

If the check is true, the OnLoseFocus method is called, before hit.collider.TryGetComponent(out currentInteractable);.

The updated method now looks as follows:

private void HandleInteractionCheck()
{
    int layerMask = 1 << 6;

    if (Physics.Raycast(playerCamera.ViewportPointToRay(interactionRayPoint), out RaycastHit hit, interactionDistance, layerMask))
    {
        if (hit.collider.gameObject.layer == 6 && (currentInteractable == null || hit.collider.gameObject.GetInstanceID() != currentInteractable.gameObject.GetInstanceID()))
        {
            if (currentInteractable != null)
                currentInteractable.OnLoseFocus();

            hit.collider.TryGetComponent(out currentInteractable);

            if (currentInteractable)
                currentInteractable.OnFocus();
        }
    } else if (currentInteractable)
    {
        currentInteractable.OnLoseFocus();
        currentInteractable = null;
    }
}