Airtest无法真正识别游戏内动态UI,仅依赖图像匹配实现任务自动化。touch()易失效因分辨率、缩放、渲染延迟等导致坐标失准;应手动坐标点击、关闭系统动画、轮询状态图判断完成;UI变更需重截图调阈值。

Airtest 本身不支持直接识别游戏内动态渲染的 UI 元素(比如 Unity/Unreal 游戏的 Canvas 或 3D 界面),它只能靠图像匹配,所以“任务自动化”本质是“图像点击流 + 坐标等待 + 状态轮询”,不是真正意义上的 UI 自动化。
为什么 touch() 点击经常失效或点偏?
手机分辨率、游戏 UI 缩放、横竖屏切换、引擎渲染延迟都会让截图坐标失准。Airtest 的 touch() 默认基于模板图中心点匹配,一旦游戏有轻微位移、UI 动画、或屏幕有半透明遮罩,匹配就会失败或偏移。
- 始终用
auto_setup(__file__)初始化,并显式指定devices=["Android://127.0.0.1:5037/xxx"],避免多设备时默认连接错设备 - 截图必须在目标设备、相同分辨率、关闭所有系统动画(设置 → 开发者选项 → 动画缩放设为“关闭”)下截取
- 优先用
touch((x, y), duration=0.1)手动坐标点击,而非touch(Template(...));坐标可先用adb shell input tap x y验证 - 加
sleep(0.5)在每次touch()后,防止操作过快导致游戏未响应
怎么判断“任务已完成”而不是硬等固定时间?
硬写 sleep(3) 极不可靠——网络波动、手机负载高、动画帧率低都会让实际耗时飘移。Airtest 没有原生事件监听,只能靠轮询图像状态。
- 准备两张关键状态图:
Template("task_done_btn.png", threshold=0.8)(完成按钮出现)和Template("loading_icon.png", threshold=0.7)(加载中图标) - 用
exists()轮询,配合超时控制,例如:for _ in range(60):<br> if exists(Template("task_done_btn.png")):<br> touch(Template("task_done_btn.png"))<br> break<br> if not exists(Template("loading_icon.png")):<br> sleep(1)<br> else:<br> sleep(0.3) -
threshold值建议从 0.7 开始试,Unity 游戏 UI 抗锯齿强,阈值太低易误匹配;太高则漏检
如何应对游戏更新后脚本大面积挂掉?
图像匹配脚本对 UI 变更极度敏感:按钮换位置、字体变色、背景加动效、甚至安卓系统级导航栏变化,都可能导致 exists() 返回 False。
立即学习“Python免费学习笔记(深入)”;
- 把所有
Template路径统一放在./tpl/目录,用变量管理:TPL_TASK_BTN = Template(r"tpl/task_btn.png"),方便批量替换 - 截图时关闭游戏内所有特效(粒子、光晕、动态阴影),只保留最简 UI 层;用
airtest-screenshot工具截,别用手机自带截图 - 在关键步骤后加断言日志:
assert exists(TPL_TASK_BTN), "任务按钮未出现,可能游戏已更新",便于快速定位失效点 - 不要依赖单张图做全流程判断,例如“任务列表页”可用多个锚点图组合验证:
exists(A) and exists(B) and not exists(C)
图像匹配的稳定性上限就摆在那里,再精细的参数也扛不住游戏引擎层的 UI 重绘。真要长期维护,得接受“每次版本更新都要重截 3–5 张图 + 调阈值”的事实,别幻想一劳永逸。



















