Skip to content

[uv][pocoui] macOS 安装与 UnityPoco 远程连接 #41

@nzcv

Description

@nzcv

[uv][pocoui] macOS 安装与 UnityPoco 远程连接

在 macOS arm64 上用 uv 安装 pocoui 并运行 Unity 自动化脚本时,遇到依赖解析失败、win32api 缺失、以及 NoDeviceError 等问题。以下为排查结论与推荐写法。

1. uv add pocoui 失败:pywin32 无 macOS wheel

现象

uv add pocoui
# error: Distribution `pywin32==312` can't be installed because it doesn't have a source distribution or wheel for the current platform
# hint: You're on macOS (`macosx_15_0_arm64`), but `pywin32` only has wheels for: win32, win_amd64, win_arm64

原因

pocouiairtestrequires_dist 里声明了 pywin32pywinauto,但没有平台标记。这两个包只有 Windows wheel,uv 在 macOS 上解析会直接失败。

修复

pyproject.toml 里用 tool.uv.dependency-metadata 覆盖 airtest 的元数据,给 Windows-only 依赖加上 sys_platform == 'win32'

[[tool.uv.dependency-metadata]]
name = "airtest"
version = "1.4.3"
requires-dist = [
    "Jinja2>=2.8",
    "Pillow>=3.4.0",
    "requests>=2.11.1",
    "six<=1.16.0,>=1.9.0",
    "mss==6.1.0",
    "numpy<2.0",
    "opencv-contrib-python<=4.6.0.66,>=4.4.0.46",
    "facebook-wda==1.5.0",
    "pywinauto==0.6.3; sys_platform == 'win32'",
    "filelock",
    "ffmpeg-python",
    "tidevice",
    "psutil",
    "packaging",
    "pywin32; sys_platform == 'win32'",
]

然后:

uv add pocoui

Windows 上仍会正常安装 pywin32 / pywinauto;macOS 上跳过即可。


2. uv run tmp.py 失败:ModuleNotFoundError: win32api

现象

poco = UnityPoco('192.168.1.6', 5001)

报错栈指向 UnityEditorWindow()connect_device("Windows://...")import win32api

原因

UnityPoco 构造函数签名是:

def __init__(self, addr=DEFAULT_ADDR, unity_editor=False, connect_default_device=True, device=None, **options):

错误写法把 5001 传给了第二个参数 unity_editor5001 为 truthy,于是走了 Unity Editor on Windows 分支,在 macOS 上必然失败。

修复

地址必须是一个 (ip, port) 元组

poco = UnityPoco(('192.168.1.6', 5001))

3. uv run tmp.py 失败:NoDeviceError: 'No devices added.'

现象

修正地址写法后:

poco = UnityPoco(('192.168.1.6', 5001))
# airtest.core.error.NoDeviceError: 'No devices added.'

原因

UnityPoco.__init__ 在非 editor 模式下会执行:

dev = device or current_device()

current_device() 在没有已连接 airtest 设备时直接抛异常,而不是返回 None

但底层 StdPoco 在传入非 localhostip 时,会跳过整个 device 分支,仅通过 TCP 连接 (ip, port) 获取 UI 树。也就是说:对纯网络远程 Unity 游戏,airtest device 在连接阶段并非必需,却被 UnityPoco 提前检查了。

输入路径的区别

模式 输入实现 是否需要 airtest device
默认 use_airtest_input=True AirtestInput 是(touch()get_current_resolution() 等)
use_airtest_input=False StdInput 否(通过 RPC 调用 Click / Swipe 等)

若游戏在远端、脚本在 macOS 上只通过 Poco SDK 协议操控 UI,应使用 SDK 侧输入(RPC),而不是 airtest 本地触控。

推荐写法(远程 Unity,无本地 Android/iOS 设备)

from poco.drivers.unity3d import UnityPoco

poco = UnityPoco(
    ('192.168.1.6', 5001),
    connect_default_device=False,
    use_airtest_input=False,
)
poco("Canvas").click()

说明:

  • connect_default_device=False:避免 fallback 到 connect_device("Android:///")
  • use_airtest_input=False:点击走 StdInput,经 TCP RPC 发到游戏端
  • 仍需显式传入 device=... 或 patch 掉 current_device() 调用,因为 UnityPoco 当前实现会在构造时访问 current_device()

若本地有 Android 设备且游戏跑在手机上,更常见的写法是:

from airtest.core.api import connect_device
from poco.drivers.unity3d import UnityPoco

dev = connect_device("Android:///")
poco = UnityPoco((ip, 5001), device=dev)

4. API 速查

# 错误:5001 被当成 unity_editor=True
UnityPoco('192.168.1.6', 5001)

# 正确:addr 是 (ip, port) 元组
UnityPoco(('192.168.1.6', 5001))

# Unity Editor(仅 Windows)
UnityPoco(('localhost', 5001), unity_editor=True)

# 默认无参:尝试连默认 Android 设备 + localhost:5001
UnityPoco()

推荐组合

  1. macOS 安装依赖pyproject.toml 里加 tool.uv.dependency-metadata 覆盖 airtest 的 Windows-only 依赖。
  2. 远程 Unity 自动化UnityPoco(('ip', port), connect_default_device=False, use_airtest_input=False),并确保构造时不触发 current_device()(传 device 或按需 wrapper)。
  3. 本地 Android Unity:先 connect_device("Android:///"),再 UnityPoco((ip, 5001), device=dev)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions