实现步骤
在Unity中实现一个功能,当鼠标或触摸超过一定时间没有操作时,自动返回待机界面。
检测输入
首先,我需要检测用户的输入,无论是鼠标还是触摸。Unity的Input系统可以检测到鼠标和触摸事件,比如Input.GetAxis(“Mouse X”)或者Input.touchCount。
- 鼠标移动:通过 Input.GetAxis 检测光标移动。
- 鼠标点击:检测左键(0)、右键(1)按下。
- 触摸事件:识别触摸开始(Began)和移动(Moved),忽略静止(Stationary)。
// 检测鼠标或触摸输入
private bool IsInputDetected()
{
// 鼠标移动检测
if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0)
{
return true;
}
// 鼠标点击检测
if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1))
{
return true;
}
// 触摸检测
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved)
{
return true;
}
}
return false;
}
计时器
当有输入的时候,我需要重置一个计时器。如果没有输入,计时器就会一直累加,直到超过设定的超时时间,比如30秒,这时候就触发返回待机界面的动作。
- 设置超时时间:在Inspector面板中调整 timeoutDuration(默认为30秒)。
void Update()
{
if (IsInputDetected())
{
currentIdleTime = 0f; // 检测到输入,重置计时
}
else
{
currentIdleTime += Time.deltaTime; // 无输入,累计时间
if (currentIdleTime >= timeoutDuration)
{
// 超时触发返回待机
}
}
}
返回待机界面
- 待机界面:根据项目需求选择加载场景或激活UI:
- 场景切换:确保待机场景(如StandbyScene)在Build Settings中。
- UI激活:取消注释UI相关代码,并在Inspector中绑定对应的UI对象。
// 返回待机界面
private void ReturnToStandby()
{
// 示例:重新加载待机场景,替换为你的逻辑
SceneManager.LoadScene("StandbyScene");
// 或激活UI元素
// standbyUI.SetActive(true);
}
完整代码
using UnityEngine;
using UnityEngine.SceneManagement;
public class IdleDetector : MonoBehaviour
{
[SerializeField] private float timeoutDuration = 30f; // 超时时间(秒)
private float currentIdleTime;
void Update()
{
if (IsInputDetected())
{
currentIdleTime = 0f; // 检测到输入,重置计时
}
else
{
currentIdleTime += Time.deltaTime; // 无输入,累计时间
if (currentIdleTime >= timeoutDuration)
{
ReturnToStandby(); // 超时触发返回待机
}
}
}
// 检测鼠标或触摸输入
private bool IsInputDetected()
{
// 鼠标移动检测
if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0)
{
return true;
}
// 鼠标点击检测
if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1))
{
return true;
}
// 触摸检测
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved)
{
return true;
}
}
return false;
}
// 返回待机界面
private void ReturnToStandby()
{
// 示例:重新加载待机场景,替换为你的逻辑
SceneManager.LoadScene("StandbyScene");
// 或激活UI元素
// standbyUI.SetActive(true);
}
}
优化
- 在非活动界面暂停检测,减少不必要的计算。
- 用UnityEvent实现超时触发
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Events;
public class IdleDetector : MonoBehaviour
{
[SerializeField] private float timeoutDuration = 30f; // 超时时间(秒)
private float currentIdleTime;
[SerializeField] private bool isDetector = false;
[SerializeField] private UnityEvent onIdleEvent;
//启用检测
public void SetDetectorState(bool state)
{
isDetector = state;
}
//重置时间
private void ResetTimer()
{
currentIdleTime = 0f;
}
void Update()
{
if(!isDetector)
return;
if (IsInputDetected())
{
ResetTimer();// 检测到输入,重置计时
}
else
{
currentIdleTime += Time.deltaTime; // 无输入,累计时间
if (currentIdleTime >= timeoutDuration)
{
onIdleEvent?.Invoke();
ResetTimer();// 如果需要持续检测,可以重置计时器
}
}
}
// 检测鼠标或触摸输入
private bool IsInputDetected()
{
// 鼠标移动检测
if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0)
{
return true;
}
// 鼠标点击检测
if (Input.GetMouseButtonDown(0) || Input.GetMouseButtonDown(1))
{
return true;
}
// 触摸检测
if (Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved)
{
return true;
}
}
return false;
}
}
测试
- 挂载脚本:将脚本挂载到场景中一个持久存在的对象(如空对象 IdleDetector)。