在我的 Unity 项目中,我创建了一个角色控制脚本,其中包括一个带有光线投射的方法,用于检查玩家当前是否正在查看可交互对象。玩家应该与之交互的所有对象都被分配了一个“可交互”层。
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;
}
}
此外,我向可交互对象添加了一个带有 OnFocus() 和 OnLoseFocus() 方法的脚本,该脚本在聚焦时将画布的 UI TMP_Text 对象更改为字符串消息。
例如,根据门的状态,将 UI 文本更改为“打开”或“关闭”。
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);
}
}
问题:这几乎可以按预期工作,但有时失去焦点时 UI 文本不会清晰。文本保留在屏幕上,就好像玩家仍在看着该对象一样,尽管清除文本本身的方法似乎确实有效。
我自己无法想出解决方法,因为我不久前才开始游戏开发,也无法在网上找到有关此特定问题的任何有用资源。
也许有人可以帮我解决这个问题?我很乐意根据要求提供更多详细信息。非常感谢您的帮助。
索取信息
场景中的盒子碰撞器:https://imgur.com/a/0NK0xd1
解决方案
我设法通过在 HandleInteractionCheck 中添加一个检查来找到此问题的解决方案,以检查何时满足第二个 if 语句的条件,但 currentInteractable 不为空。
如果检查为 true,则在
hit.collider.TryGetComponent(out currentInteractable);
之前调用 OnLoseFocus 方法。
更新后的方法如下所示:
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;
}
}