You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust Bevy中如何实现鼠标双击检测 修复Local<Instant>报错

报错原因

两个报错的核心原因有两个:

  1. Local<T>是Bevy提供的系统局部状态包装器,本质是持有内部值的可变引用,不能直接将T类型实例赋值给Local变量本身,必须通过解引用修改内部存储的值,否则会触发类型不匹配错误。
  2. Bevy要求Local<T>的内部类型T必须实现Default trait,用于生成系统首次运行时的初始状态。标准库的Instant类型没有实现Default,因此无法直接作为Local的内部类型,这也是系统注册时提示IntoSystem trait 约束不满足的根源。
修复后的可运行代码

用Option<Instant>作为Local的内部类型即可,Option默认实现了Default(初始值为None),刚好对应初始状态无有效点击记录的场景:

use std::time::{Duration, Instant};
use bevy::prelude::*;

pub fn double_click_detect(
    mouse_button_input: Res<Input<MouseButton>>,
    mut last_click: Local<Option<Instant>>,
) {
    // 可根据需求调整双击判定的最大时间间隔
    const DOUBLE_CLICK_THRESHOLD: Duration = Duration::from_millis(300);

    if mouse_button_input.just_pressed(MouseButton::Left) {
        if let Some(prev_click_time) = *last_click {
            if prev_click_time.elapsed() < DOUBLE_CLICK_THRESHOLD {
                // 此处写入双击触发后的业务逻辑
                println!("左键双击触发");
                // 触发后重置状态,避免连续点击重复判定
                *last_click = None;
                return;
            }
        }
        // 记录本次点击的时间
        *last_click = Some(Instant::now());
    }
}

该系统可以直接注册到Bevy App中,不需要额外配置。

其他可选实现方案
  • 基于Resource实现:如果双击状态需要被多个系统读取/修改,可以将上次点击时间定义为Resource,在App启动时插入初始值即可,相比Local更适合跨系统共享状态。
  • 基于Bevy原生Timer实现:不需要手动调用elapsed()计算时间差,每次点击时重置Timer,若Timer未到设定的双击间隔就再次收到点击事件则判定为双击,逻辑更贴合Bevy的帧调度模型。

内容的提问来源于stack exchange,提问作者Pro Coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:42:19