Unity ML-Agents 高级功能全解析:自定义通信、传感器、输入系统、推理部署与环境注册
人工智能强化学习深度学习机器学习游戏开发AI 应用【免费下载链接】ml-agentsThe Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement learning and imitation learning.项目地址https://gitcode.com/gh_mirrors/ml/ml-agents点击查看免费下载本指南面向已掌握 ML-Agents 基础训练流程的开发者系统梳理 Unity ML-Agents Toolkit 的九大高级能力自定义 Side Channel 双向通信、自定义 Grid Sensor、Input System 集成、Sentis 推理引擎、Hugging Face 模型仓库集成、Match-3 游戏集成、包级设置资产、Unity 环境注册表等。读完本文你将能独立实现 UnityC#与 Python 之间的任意自定义数据结构通信、扩展网格传感器采集自定义属性、让 Agent 复用既有输入系统代码以及一键将训练好的模型发布到 Hugging Face 供他人下载回放。本文以仓库中 Advanced-Features.md 为索引骨架逐模块结合com.unity.ml-agents/Runtime、ml-agents/mlagents与ml-agents-envs/mlagents_envs的源码实现展开说明涉及的相对路径均以仓库根目录为基准。高级功能总览ML-Agents 提供多项扩展核心能力的高级功能覆盖通信、感知、控制、推理、部署与工程化管理等多个维度。下表汇总各功能模块及其用途点击链接可跳转到对应详细文档功能说明自定义 Side Channel在 Unity 与 Python 之间创建自定义通信通道自定义 Grid Sensor构建面向空间数据的专用网格传感器Input System 集成将 ML-Agents 与 Unity 的 Input System 集成推理引擎Sentis部署训练好的模型进行实时推理Hugging Face 集成连接 Hugging Face 模型仓库与生态游戏集成面向特定游戏类型与机制如 Match-3的集成工具Match-3 集成面向三消棋盘游戏的抽象与工具棋盘、传感器、执行器ML-Agents 包设置配置作用于整个项目的高级包设置与偏好Unity 环境注册表以编程方式管理并注册 Unity 环境一、自定义 Side Channel搭建 Unity 与 Python 的专用数据通道1.1 为什么需要自定义 Side ChannelML-Agents 内置的EnvironmentParametersChannel环境参数只能承载字符串 → 浮点数这类简单键值对。当需要传输的数据结构过于复杂、或数据与具体 Agent 无关例如全局地图信息、外部控制器指令、自定义统计指标时侧通道Side Channel是官方推荐的扩展机制——它允许你在 C# 与 Python 之间传递任意自定义数据结构。从源码看Side Channel 本质上是绕过常规强化学习训练回路的旁路通信SideChannel.cs 的注释明确指出它提供独立于机器学习循环的数据收发机制且必须在 Unity 端与 Python 端各实现一套镜像类。1.2 双端实现要求一个可用的 Side Channel 必须同时以 Unity 类与 Python 类的形式存在且两端必须共享同一个通道 IDUnity 端继承SideChannel抽象类实现OnMessageReceived(IncomingMessage msg)方法按写入顺序读取数据并在构造函数中为ChannelId赋值一个 Guid。同一 ID 在通信期间只能注册一个通道。Python 端继承SideChannel抽象类实现on_message_received(self, msg: IncomingMessage) - None方法并在构造函数中通过super().__init__(channel_id)传入 UUID与 C# 端 Guid 完全一致。1.3 Unity 端数据写入、读取与注册发送数据C# → Python创建OutgoingMessage实例写入数据调用base.QueueMessageToSend(msg)将消息排队最后调用OutgoingMessage.Dispose()释放资源。QueueMessageToSend在 SideChannel.cs 中实现本质是将消息序列化为字节数组存入内部队列待下一模拟步由通信器统一发往 Python。注册通道调用SideChannelManager.RegisterSideChannel(sideChannel)。查看 SideChannelManager.cs 可知该方法会校验 ChannelId 是否已被注册重复注册会抛出UnityAgentsException并处理已缓存待投递的消息。OnDestroy时可用SideChannelManager.UnregisterSideChannel注销。序列化 API 对应表OutgoingMessage源码与IncomingMessage源码成对提供读写方法必须严格按写入顺序读取数据类型C# 写入C# 读取Python 写入Python 读取布尔WriteBooleanReadBooleanwrite_boolread_bool32 位整数WriteInt32ReadInt32write_int32read_int3232 位浮点WriteFloat32ReadFloat32write_float32read_float32字符串WriteStringReadStringwrite_stringread_string浮点列表WriteFloatListReadFloatListwrite_float32_listread_float32_list原始字节SetRawBytesGetRawBytesset_raw_bytes直接访问缓冲注意IncomingMessage.ReadBoolean/ReadInt32等支持默认值参数读取到消息末尾时返回默认值而非抛异常字符串采用 ASCII 编码长度前缀写入消息参见 IncomingMessage.cs 与 outgoing_message.py。1.4 Python 端实现与挂载Python 侧必须继承mlagents_envs.side_channel.side_channel.SideChannel源码它提供queue_message_to_send(msg)排队方法与channel_id属性。注册方式不是显式调用管理器而是在创建UnityEnvironment时把通道实例放进side_channels列表参数。仓库中 Colab_UnityEnvironment_3_SideChannel.ipynb 提供了交互式演练ml-agents-envs/tests/test_side_channel.py与 SamplerTests.cs 则覆盖了双端通道的收发测试可作为参考。1.5 完整示例交换 ASCII 字符串下面实现一个Python 发送字符串 → Unity 控制台打印Unity 错误日志 → Python 终端打印的双向通道。两端的通道 ID 必须一致。Unity C# 第一步——定义通道类监听 Python 消息并把 Unity 错误日志发给 Pythonusing UnityEngine; using Unity.MLAgents; using Unity.MLAgents.SideChannels; using System.Text; using System; public class StringLogSideChannel : SideChannel { public StringLogSideChannel() { ChannelId new Guid(621f0a70-4f87-11ea-a6bf-784f4387d1f7); } protected override void OnMessageReceived(IncomingMessage msg) { var receivedString msg.ReadString(); Debug.Log(From Python : receivedString); } public void SendDebugStatementToPython(string logString, string stackTrace, LogType type) { if (type LogType.Error) { var stringToSend type.ToString() : logString \n stackTrace; using (var msgOut new OutgoingMessage()) { msgOut.WriteString(stringToSend); QueueMessageToSend(msgOut); } } } }Unity C# 第二步——实例化并注册通道挂到场景中存活的 GameObject 上using UnityEngine; using Unity.MLAgents; public class RegisterStringLogSideChannel : MonoBehaviour { StringLogSideChannel stringChannel; public void Awake() { // 创建 Side Channel stringChannel new StringLogSideChannel(); // 将 Debug.Log 消息转发到通道 Application.logMessageReceived stringChannel.SendDebugStatementToPython; // 通过 SideChannelManager 注册 SideChannelManager.RegisterSideChannel(stringChannel); } public void OnDestroy() { // 注销 Debug.Log 回调 Application.logMessageReceived - stringChannel.SendDebugStatementToPython; if (Academy.IsInitialized) { SideChannelManager.UnregisterSideChannel(stringChannel); } } public void Update() { // 可选按下空格键在 Unity 中制造一条错误日志 if (Input.GetKeyDown(KeyCode.Space)) { Debug.LogError(This is a fake error. Space bar was pressed in Unity.); } } }Python 侧——镜像类与使用from mlagents_envs.environment import UnityEnvironment from mlagents_envs.side_channel.side_channel import ( SideChannel, IncomingMessage, OutgoingMessage, ) import numpy as np import uuid class StringLogChannel(SideChannel): def __init__(self) - None: super().__init__(uuid.UUID(621f0a70-4f87-11ea-a6bf-784f4387d1f7)) def on_message_received(self, msg: IncomingMessage) - None: # 必须实现该方法以接收来自 Unity 的消息 print(msg.read_string()) def send_string(self, data: str) - None: msg OutgoingMessage() msg.write_string(data) # 调用此方法排队待发送数据 super().queue_message_to_send(msg) # 创建通道并随 UnityEnvironment 一起启动 string_log StringLogChannel() env UnityEnvironment(side_channels[string_log]) env.reset() string_log.send_string(The environment was reset) group_name list(env.behavior_specs.keys())[0] # 获取第一个行为组名称 for i in range(1000): decision_steps, terminal_steps env.get_steps(group_name) string_log.send_string( fStep {i} occurred with {len(decision_steps)} deciding agents and f{len(terminal_steps)} terminal agents ) env.step() # 推进模拟 env.close()运行脚本并在提示时于 Unity 编辑器按下 PlayUnity 控制台会在每个 Python 步打印消息反之在 Unity 中按空格键终端会出现错误日志。二、自定义 Grid Sensor让网格感知携带自定义属性2.1 Grid Sensor 与自定义扩展Grid Sensor 提供俯视视角下的 2D 观测与 RayCast 相比它获得的是网格区域内无空洞的完整观测且不会被 Agent 周围的物体遮挡能提供更细粒度的视野代价是更高的计算资源消耗。其扩展点在于你可以从网格传感器基类派生在对象标签之外采集自定义属性如速度、角度、剩余生命值一并作为观测从而大幅提升 GridSensor 的灵活性。2.2 派生GridSensorBase定义传感器逻辑自定义传感器需要继承GridSensorBase源码它负责检测碰撞体、构建观测。按需覆写以下方法protected virtual int GetCellObservationSize()返回每个网格单元cell的观测维度默认为1。dataBuffer的大小即由此决定。protected virtual void GetObjectData(GameObject detectedObject, int tagIndex, float[] dataBuffer)由被检测对象构造观测。输入为检测到的 GameObject 及其标签索引0 起始观测写入dataBuffer。每个单元的数据最终会汇总发送给训练器。基类默认实现是dataBuffer[0] tagIndex 1即记录标签索引。protected virtual bool IsDataNormalized()返回观测值是否已归一化到 0~1。由于压缩观测PNG只支持归一化数据这决定你是否能启用压缩。若GetObjectData写入的所有值都在 (0, 1) 范围内返回true否则返回false默认false。关于归一化官方给出明确建议若数据天然有界但不在 (0, 1) 内先归一化再填入缓冲。例如旋转角度有界于 0~360可将角度x记录为x/360若数据无界位置、速度等则应设定合理的 min/max 用于归一化。若数据未归一化仍想用压缩加速训练务必先归一化后再启用压缩——GridSensorBase.cs 会在CompressionType设置为 PNG 但数据未归一化时打印警告并跳过压缩ValidateValues 则在压缩模式下校验每个值必须在 0~1 之间。protected internal virtual ProcessCollidersMethod GetProcessCollidersMethod()返回单元内碰撞体的处理方式定义当单元内检测到多个带标签对象时的传感器行为。目前提供两种枚举值行为适用场景ProcessCollidersMethod.ProcessClosestColliders默认只处理距 Agent 最近的碰撞体每个单元由单个对象表示通用单对象表示ProcessCollidersMethod.ProcessAllColliders处理所有检测到的碰撞体单元内数据具有可加性时如统计单元内对象数量。此时GetObjectData()收到的dataBuffer已包含同单元其他碰撞体的处理结果通常应做加减而非整体覆盖两种模式在底层ProcessDetectedObjectGridSensorBase.cs中分别以累加缓存单元数据与清空缓存单元数据两条路径实现。2.3 派生GridSensorComponent装配传感器自定义传感器还必须派生GridSensorComponent并覆写GetGridSensors()返回该组件要使用的网格传感器数组。这允许一个组件创建多个不同的自定义传感器也可以混入包内自带的传感器public class CustomGridSensorComponent : GridSensorComponent { protected override GridSensorBase[] GetGridSensors() { return new GridSensorBase[] { new CustomGridSensor(...) }; } }GridSensorComponent源码的默认实现返回一个OneHotGridSensor若GetGridSensors()返回空数组会抛出异常。组件还负责创建BoxOverlapChecker执行非分配式物理检测、按ObservationStacks决定是否用StackingSensor堆叠历史观测。2.4 包内自带的两种 Grid SensorOneHotGridSensor默认检测带标签对象观测为标签索引的 one-hot 表示源码GetCellObservationSize()detectableTags.LengthIsDataNormalized()true可压缩GetProcessCollidersMethod()ProcessClosestCollidersGetObjectData()protected override void GetObjectData(GameObject detectedObject, int tagIndex, float[] dataBuffer) { dataBuffer[tagIndex] 1; }CountingGridSensor统计单元内各标签对象数量是ProcessAllColliders的示例不可与数据压缩搭配使用源码GetCellObservationSize()detectableTags.LengthIsDataNormalized()falseGetProcessCollidersMethod()ProcessAllCollidersGetObjectData()protected override void GetObjectData(GameObject detectedObject, int tagIndex, float[] dataBuffer) { dataBuffer[tagIndex] 1; }对比两者的GetObjectDataOneHot 是赋值 1Counting 是累加 1恰好对应了两种ProcessCollidersMethod的设计意图。官方以这两个内置传感器为参考模板鼓励开发者仿照其结构编写自己的传感器需要更多自定义数据时可参考 GridSensorBase.cs 中读取Rigidbody.velocity写入缓冲的文档示例。三、Input System 集成让 Agent 复用既有输入处理代码3.1 机制概述ML-Agents 通过InputActuatorComponent与 Unity Input System 包集成InputActuatorComponent.cs。该组件基于IInputActionAssetProvider接口引用的InputActionAsset或玩家控制的 Agent 上挂载的PlayerInput组件为 Agent 建立动作空间。它的意义在于如果你已有处理输入的独立代码就无需再为 Agent 实现 Heuristic 函数——InputActuatorComponent会替你完成。训练与推理均可作用于由InputActionAsset定义动作空间的 Agent。官方示例场景位于Project/Assets/ML-Agents/Examples/PushBlockWithInput/含PushBlockActions.inputactions与 Prefabs、Scenes 等资源其实现用 C# 事件将信息从 Input System 传出。动手实现前可先通读该示例。3.2 快速上手步骤通过 Package Manager 为项目添加com.unity.inputsystem版本 1.1.0-preview.3 或更高。若尚未配置InputActionAsset请先创建一份使 Agent 可由 Input System 控制。在常规位置Agent 类外部的脚本处理 Input System 事件。在挂有PlayerInput与Agent组件的 GameObject 上添加InputSystemActuatorComponent。3.3 技术规范IInputActionAssetProvider接口InputActuatorComponent会在同一 GameObject 上搜索实现该接口的组件。若同一 GameObject 上有多个组件需要访问InputActionAsset处理事件它们必须共享IInputActionAssetProvider返回的同一InputActionAsset实例。InputActuatorComponent类它是 ML-Agents 与 Input System 之间的桥允许 ML-Agents基于来自IInputActionAssetProvider的InputActionAsset为 Agent 创建ActionSpec从训练进程或神经网络发送模拟输入让开发者把输入处理代码集中在一处。底层工作流可从 CreateActuators() 与 FindNeededComponents() 推断组件先查找IInputActionAssetProvider与PlayerInput、BehaviorParameters随后按PlayerInput.defaultActionMap中的每个动作创建InputActionActuator每个执行器通过IRLActionInputAdaptor源码定义ActionSpec生成、输入事件写入、Heuristic 写入三组转换与 Input System 通信同时注册一套名为MLAgentsLayout的虚拟输入布局并添加ml-agents控制方案与虚拟输入设备。在 Heuristic 模式下Input System 全权处理真实设备输入在训练/推理模式下绑定被切换到虚拟设备以接收来自神经网络的模拟输入见UpdateDeviceBindingInputActuatorComponent.cs。输入控件到适配器的映射集中在静态字典controlTypeToAdaptorTypeInputActuatorComponent.cs支持Vector2Control、ButtonControl、IntegerControl、AxisControl、DoubleControl五类。3.4 需求与已知限制需求使用InputActuatorComponent必须安装com.unity.inputsystem1.1.0-preview.3 或更高版本。已知限制InputControls的实现有限目前无法自定义InputActuatorComponent的动作空间。四、推理引擎Sentis在游戏中部署训练好的模型4.1 概览ML-Agents 允许在 Unity 游戏中直接使用预训练神经网络模型其底层依赖 Unity 的 Sentiscom.unity.ai.inference。Sentis 利用**计算着色器compute shaders**在 Unity 内运行神经网络。4.2 支持的设备与后端Sentis 支持所有 Unity 运行时平台。脚本后端独立构建Standalone下Sentis 使用IL2CPP 通常比 Mono 更快。编辑器限制在 Unity 编辑器中当 Editor Graphics Emulation 设置为 OpenGL(ES) 3.0 或 2.0 模拟时无法选择 GPU 设备使用 Sentis。构建期警告目标平台若包含不支持 Unity Compute Shaders 的 Graphics API可能出现非致命的构建期错误。当目标平台无法使用计算着色器时可退回使用CPU或GPUPixel两种 Sentis 后端完成推理。4.3 使用方法将模型文件拖入 Agent Inspector 面板的Model字段然后选择Inference DeviceCompute Shader、Burst或Pixel Shader之一。重要提示对大多数由 ML-Agents Toolkit 生成的模型CPU 推理Burst会比 GPU 推理Compute Shader / Pixel Shader更快。仅当使用 ResNet 视觉编码器或存在大量带视觉观测的 Agent 时才建议改用 GPU 推理。4.4 不支持的使用场景外部训练模型ML-Agents 只支持由 Unity 训练器创建的模型。模型加载依赖特定的常量与张量命名约定虽然可以自行构造符合约定的模型但 Unity 不提供额外辅助。相关约定可查阅 TensorNames.cs 与 SentisModelParamLoader.cs。若要对外部训练的模型做推理官方建议直接使用 Sentis 而非经由 ML-Agents。Unity 之外的模型推理官方不提供任何 Unity 之外的推理支持。训练产出的.onnx文件采用开放格式 ONNX如需转换格式或在其外部推理请参考 ONNX 生态的官方文档。五、Hugging Face 集成模型的上传、下载与浏览器回放5.1 能力概述Hugging Face Hub 是任何人都可以分享和下载模型的中枢平台ML-Agents 的集成允许托管Host训练好的模型下载Download社区训练好的模型在浏览器中直接观看Agent 表演。这两个 CLI 工具由 setup.py 注册为mlagents-push-to-hf与mlagents-load-from-hf控制台入口实现代码位于 ml-agents/mlagents/utils 目录。5.2 从 Hub 下载模型使用mlagents-load-from-hf需要两个参数--repo-id要下载的 Hugging Face 仓库名称--local-dir模型下载到本地的路径。示例下载ThomasSimonini/MLAgents-Pyramids到./downloadsmlagents-load-from-hf --repo-idThomasSimonini/MLAgents-Pyramids --local-dir./downloads从 load_from_hf.py 的实现可以看到下载实际委托给huggingface_hub.snapshot_download并且会以repo_id中的仓库名在local_dir下创建子目录例如下载到./downloads/MLAgents-Pyramids。5.3 上传模型到 Hub使用mlagents-push-to-hf需要四个参数--run-id训练运行的 run id--local-dir模型保存位置--repo-id要创建或更新的 Hugging Face 仓库名称格式恒为你的用户名/仓库名仓库不存在时会自动创建--commit-message由于 HF 仓库本质是 git 仓库必须提供提交信息。示例把 run-id 为SnowballTarget1的模型发布到ThomasSimonini/ppo-SnowballTargetmlagents-push-to-hf --run-idSnowballTarget1 --local-dir./results/SnowballTarget1 --repo-idThomasSimonini/ppo-SnowballTarget --commit-messageFirst Push上传并非简单拷贝push_to_hf.py 的package_to_hub流程包括——调用HfApi().create_repo(exist_okTrue)创建/复用仓库读取本地configuration.yaml生成config.json依据behaviors中的trainer_type与env_id自动生成模型卡README.md与元数据标签library_nameml-agents最后upload_folder上传整个 run-id 目录。另有--configfile-name参数可自定义配置文件名称默认configuration.yaml。5.4 在浏览器中观看 Agent 表演若环境来自 ML-Agents 官方环境可在浏览器直接观看 Agent 回放打开 Hugging Face 的 Unity 环境演示页选择环境 demo在列表中找到你的model_id选择.nn/.onnx文件点击 Watch the agent play 按钮观看 Agent 表演。六、游戏集成与 Match-3为三消类游戏提供训练抽象6.1 游戏集成概览ML-Agents 为一些常见游戏类型提供集成工具目前官方维护的是Match-3三消它提供三消棋盘与移动的抽象、观测棋盘状态的传感器以及将 Agent 动作翻译为游戏移动的执行器。C# 代码位于 Unity 包内com.unity.ml-agents示例场景在Project/Assets/ML-Agents/Examples/match3。注意按官方说明该示例三消游戏并非设计为人类可玩仅用于训练验证。6.2AbstractBoardML-Agents 与游戏的桥AbstractBoard源码是 ML-Agents 与你的游戏之间的桥接层让 ML-Agents 可以询问棋盘当前/最大尺寸行列数与潜在棋子类型数、查询格子颜色、判断格子是否为特殊棋子、询问某移动是否合法、请求游戏执行移动。这些由实现抽象方法完成public abstract BoardSize GetMaxBoardSize()返回游戏可用的最大BoardSize用于确定观测与传感器尺寸不要设得比实际需要更大。public virtual BoardSize GetCurrentBoardSize()返回当前棋盘尺寸每个字段必须小于等于GetMaxBoardSize()对应字段若棋盘尺寸恒定则无需覆写。当前尺寸小于最大尺寸时越界格子的GetCellType()/GetSpecialType()与越界移动的IsMoveValid()不会被调用越界移动会在传入前被过滤见 AbstractBoard.cs 的注释。public abstract int GetCellType(int row, int col)返回 (row, col) 处棋子的颜色取值应在 0 到BoardSize.NumCellTypes - 1含之间数值顺序无关紧要。public abstract int GetSpecialType(int row, int col)返回特殊棋子类型取值应在 0 到BoardSize.NumSpecialTypes含之间NumSpecialTypes可为 0表示同类型棋子等价。public abstract bool IsMoveValid(Move m)判断某个Move是否合法具体规则取决于你的游戏官方提供SimpleIsMoveValid()辅助方法处理无特殊、无不可移动棋子的基础三消规则。public abstract bool MakeMove(Move m)指示游戏执行该移动返回是否成功。训练期间偶尔仍会请求被判非法的移动——此时安全做法是不做任何事并请求下一个移动。6.3Move与BoardSize结构Move结构封装相邻两格的交换。Move.NumPotentialMoves(maxBoardSize)返回给定尺寸棋盘的全部潜在移动数两个构造函数public static Move FromMoveIndex(int moveIndex, BoardSize maxBoardSize)从 0 到NumPotentialMoves()循环即可遍历棋盘所有潜在移动public static Move FromPositionAndDirection(int row, int col, Direction dir, BoardSize maxBoardSize)由行、列、方向及棋盘尺寸构造移动。BoardSize描述棋盘尺寸包括潜在棋子类型数由GetMaxBoardSize()/GetCurrentBoardSize()返回含Rows、Columns、NumCellTypes、NumSpecialTypes四字段。6.4 传感器与执行器组件Match3Sensor/Match3SensorComponentMatch3Sensor通过AbstractBoard接口生成状态观测可选择向量Vector或视觉Visual观测——理论上视觉观测因与棋盘同为二维效果可能更好官方表示仍需更多实验验证。Match3SensorComponent在运行时生成Match3Sensor数量取决于配置须与你的Agent实现挂在同一 GameObject 上。从 Match3SensorComponent.cs 可见它默认创建一个格子类型传感器cells当NumSpecialTypes 0时额外创建特殊类型传感器specialObservationType可在 Vector 与 Visual 间选择。Match3Actuator/Match3ActuatorComponentMatch3Actuator把训练/推理动作转换为送往AbstractBoard.MakeMove()的Move并逐一用AbstractBoard.IsMoveValid校验潜在移动据此为 Agent 设置动作掩码action mask。Match3ActuatorComponent运行时生成一个Match3Actuator同样须与Agent同挂载。其ActionSpec为一个离散分支分支大小即Move.NumPotentialMoves(GetMaxBoardSize())Match3ActuatorComponent.cs可配置RandomSeed与ForceHeuristic测试用。6.5 搭建三消训练环境的步骤实现AbstractBoard的方法将棋盘逻辑接入 ML-Agents当 Agent 达成目标时给予奖励连续消除多个棋子、清除特定类型棋子等将Agent、AbstractBoard实现、Match3SensorComponent、Match3ActuatorComponent添加到同一个 GameObject需要 Agent 决策时调用Agent.RequestDecision()下一个Academy步会调用棋盘上的MakeMove()。6.6 动作空间索引细节动作索引与Human-Like Playtesting with Deep Learning论文的约定一致先枚举水平移动再枚举垂直移动。Match-3 中水平与垂直移动的枚举顺序示意用于理解离散动作分支与Move.FromMoveIndex的对应关系。七、ML-Agents 包设置项目级配置资产7.1 位置与作用ML-Agents Package Settings 包含作用于整个项目的设置可在编辑器中配置 ML-Agents 专属选项且编辑器与 Player运行时构建中均可使用。入口为Edit Project Settings... ML-Agents面板会列出所有可用设置及其默认值。从 MLAgentsSettings.cs 可以看到核心字段m_ConnectTrainer默认true是否连接训练器与m_EditorPort默认5004编辑器通信端口通过MLAgentsSettingsManager在运行时应用。7.2 创建自定义设置资产点击Create Settings Asset按钮或点击右上角齿轮选择New Settings Asset...即可创建设置资产。资产文件可放在项目Asset/目录下任意位置。创建后即可修改项目设置修改内容会保存在资产中。ML-Agents 项目设置面板可查看全部可用设置及默认值并通过按钮创建自定义设置资产。7.3 多场景下的多套设置一个项目可创建多份设置资产。点击右上角齿轮下拉菜单会列出所有可用设置资产供切换。典型用法是为不同场景准备不同设置例如分别创建训练与推理两套设置按当前运行内容切换使用。一个项目中的多份 ML-Agents 设置资产可在齿轮下拉菜单中切换例如训练与推理场景各一套。八、Unity 环境注册表 [实验性]免安装直接加载预构建环境8.1 概述Unity Environment Registry 是预构建 Unity 环境的数据库无需安装 Unity 编辑器即可轻松使用这些环境是快速上手 UnityEnvironment API 的捷径。其底层实现位于 ml-agents-envs/mlagents_envs/registry 目录。8.2 列出并加载注册表中的环境默认注册表随 官方示例环境 提供。注册表实现了Mapping映射因此可用方括号[ ]按标识符访问条目。列出默认注册表中的全部环境标识符from mlagents_envs.registry import default_registry environment_names list(default_registry.keys()) for name in environment_names: print(name)注册表条目的make()方法返回一个可直接使用的UnityEnvironment传入make()的所有参数都会转交给UnityEnvironment构造函数参数说明参见 Python-LLAPI。例如创建标识符为my-env的环境、重置、执行几步并关闭from mlagents_envs.registry import default_registry env default_registry[my-env].make() env.reset() for _ in range(10): env.step() env.close()从 unity_env_registry.py 的实现可见UnityEnvRegistry是标准Mapping条目为BaseRegistryEntry含identifier、expected_reward、description属性与抽象make()见 base_registry_entry.pydefault_registry已通过内置 manifest 预注册一批环境。8.3 创建并分享自己的注册表要分享你创建的环境需要为每个平台Linux、OSX 和/或 Windows构建 Unity 可执行文件将每个可执行文件放入zip压缩包将 zip 上传到你选择的托管平台创建包含环境描述与路径的yaml文件将yaml文件上线。yaml格式如下environments: - environment-identifier: expected_reward: expected-reward-float description: description-of-the-environment linux_url: url-to-the-linux-zip-folder darwin_url: url-to-the-osx-zip-folder win_url: url-to-the-windows-zip-folder additional_args: - an-optional-list-of-command-line-arguments-for-the-executable - ...你的用户随后即可用如下代码加载该环境from mlagents_envs.registry import UnityEnvRegistry registry UnityEnvRegistry() registry.register_from_yaml(url-or-path-to-your-yaml-file)其中url-or-path-to-your-yaml-file可以是 URL 或本地路径。unity_env_registry.py 显示register_from_yaml采用惰性注册条目仅在首次访问时才真正解析加载http开头的路径走远程 manifest 加载其余按本地文件处理。结语九大高级功能从不同维度把 ML-Agents 从标准训练闭环延展为可工程化落地的完整方案自定义 Side Channel 打通了任意数据的双向链路自定义 Grid Sensor 让感知不再局限于标签Input System 集成消除了人类控制与神经控制两套代码的割裂Sentis 让训练成果真正进入游戏运行时Hugging Face 集成打通了模型分发生态Match-3 抽象为品类化游戏提供了标准接口包设置与环境注册表则把工程配置与分发流程规范化。建议按需组合使用——例如自定义 Side Channel 自定义 Grid Sensor Sentis 推理即可覆盖多数真实游戏 AI 场景的感知、控制与部署闭环。赞分享人工智能强化学习深度学习机器学习游戏开发AI 应用【免费下载链接】ml-agentsThe Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement learning and imitation learning.项目地址https://gitcode.com/gh_mirrors/ml/ml-agents点击查看免费下载相关推荐Unity ML-Agents虚拟图书馆AI图书推荐系统Unity ML Agents虚拟图书馆AI图书推荐系统 引言当虚拟图书馆遇上强化学习 在数字化阅读时代用户每天面对海量图书资源却难以找到真正感兴趣的内容人工智能强化学习深度学习机器学习游戏开发AI 应用如何一次下齐 Stability AI 的 SDXL/SVD/SV4D 权重huggingface-cli、断点续传与首推验证完整清单如何一次下齐 Stability AI 的 SDXL/SVD/SV4D 权重huggingface cli、断点续传与首推验证完整清单 在 generativ人工智能深度学习媒体生成计算机视觉预训练大模型CLI11高级功能解析环境变量、依赖关系与自定义类型处理CLI11高级功能解析环境变量、依赖关系与自定义类型处理 CLI11作为C11及更高版本的高性能命令行解析库提供了丰富的功能集。本文将深入探讨CLI11CLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考