I have an interactable script that I have a couple variations of (doors/drawers, collectibles, etc.) To quickly break it down, when the player focuses on an object that they can interact with, a UI graphic prompt pops up and reminds them of the interact key, and the object highlights. Some objects can only be used/opened once, so I have a toggled bool to turn them off once they have been interacted with.
Standard stuff, and I’ve got it 99% working - however, the one thing I can’t quite get working is that if the object IS NOT a one-use object, I want the prompts and highlights to be deactivated after it’s been used, until the player looks away and looks at it again. If the object IS set to one-use, then it works perfectly.
In theory, I thought that toggling the object’s “inReach” bool to false and deactivating the prompts and highlights after interaction would achieve that - which it does…for one single frame, and then the prompts and highlights return to active. Is there something I’m missing?
Here’s the code for the “usable” iteration of the script - mainly used for sink faucets, buttons, etc - I chose this one as an example as it’s rather simpler than, for example, the doors and light switches iterations. Working in version 2021.3.20f1.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UsableInteractable : Interactable
{
[Header("Animation Options")]
public Animator ANI;
public GameObject useText;
public bool oneUse = false;
[Header("Highlight Options")]
public GameObject normalObject;
public GameObject highlightedObject;
private bool used;
private bool inReach;
void Start()
{
useText.SetActive(false);
ANI.SetBool("inUse", false);
normalObject.SetActive(true);
highlightedObject.SetActive(false);
used = false;
inReach = false;
}
public override void OnFocus()
{
if (!used)
{
inReach = true;
useText.SetActive(true);
normalObject.SetActive(false);
highlightedObject.SetActive(true);
}
else if (oneUse && used)
{
inReach = true;
useText.SetActive(false);
normalObject.SetActive(true);
highlightedObject.SetActive(false);
}
else if (!oneUse && used)
{
inReach = true;
useText.SetActive(true);
normalObject.SetActive(false);
highlightedObject.SetActive(true);
}
}
public override void OnInteract()
{
if (inReach)
{
UseFunction();
}
}
public override void OnLoseFocus()
{
inReach = false;
useText.SetActive(false);
normalObject.SetActive(true);
highlightedObject.SetActive(false);
}
void UseFunction()
{
if (!used && inReach && Input.GetButtonDown("Interact"))
{
ANI.SetBool("inUse", true);
useText.SetActive(false);
normalObject.SetActive(true);
highlightedObject.SetActive(false);
if (gameObject.tag == "Usable/Toilet")
{
FMODUnity.RuntimeManager.PlayOneShot("event:/SFX/Usables/ToiletHandle");
}
else if (gameObject.tag == "Usable/Sink")
{
FMODUnity.RuntimeManager.PlayOneShot("event:/SFX/Usables/FaucetSqueak");
}
else if (gameObject.tag == "Usable/Elevator1")
{
FMODUnity.RuntimeManager.PlayOneShot("event:/SFX/Usables/Elevator1");
}
used = true;
inReach = false;
}
else if (!oneUse && used && inReach && Input.GetButtonDown("Interact"))
{
ANI.SetBool("inUse", true);
useText.SetActive(false);
normalObject.SetActive(true);
highlightedObject.SetActive(false);
if (gameObject.tag == "Usable/Toilet")
{
FMODUnity.RuntimeManager.PlayOneShot("event:/SFX/Usables/ToiletHandle");
}
else if (gameObject.tag == "Usable/Sink")
{
FMODUnity.RuntimeManager.PlayOneShot("event:/SFX/Usables/FaucetSqueak");
}
else if (gameObject.tag == "Usable/Elevator1")
{
FMODUnity.RuntimeManager.PlayOneShot("event:/SFX/Usables/Elevator1");
}
used = true;
inReach = false;
}
else if (oneUse && used && inReach && Input.GetButtonDown("Interact"))
{
ANI.SetBool("inUse", false);
useText.SetActive(false);
normalObject.SetActive(true);
highlightedObject.SetActive(false);
used = true;
inReach = false;
}
}
}