Unity ML Agents中CameraSensor无输入及组件获取报错问题
问题原因
两个报错均来自ML-Agents 2.0.1版本的API使用逻辑错误:
CameraSensor本身不是继承自MonoBehaviour的可挂载组件,无法通过GetComponent直接获取。它是CameraSensorComponent(可挂载的编辑器组件)在运行时生成的内部处理类,不对外提供组件获取接口。- 相机传感器未正确注册到Agent,且向量观测配置项与实际代码写入的观测数量不匹配,最终导致Agent收到的有效观测数为0,触发填充警告。
解决方案
1. 修正代码逻辑
删除代码中所有直接引用CameraSensor类型的字段和GetComponent<CameraSensor>()调用,不需要在业务代码里手动持有相机传感器实例,ML-Agents框架会自动处理已注册传感器的数据收集与传递。
修正后的基础代码如下:
using UnityEngine; using Unity.MLAgents; using Unity.MLAgents.Sensors; using UnityEngine.SceneManagement; using Unity.MLAgents.Actuators; public class MyAgent : Agent { Rigidbody2D rb2D; public bool space; public Vector3 targetPos; public void Start() { rb2D = GetComponent<Rigidbody2D>(); } // 如需传入速度、坐标类向量观测,重写该方法;无向量观测可完全删除该方法 public override void CollectObservations(VectorSensor sensor) { // 示例:写入自身速度、与目标的相对位置作为向量观测,数量要和编辑器配置对应 // sensor.AddObservation(rb2D.velocity); // sensor.AddObservation(targetPos - transform.position); } public override void OnActionReceived(ActionBuffers actions) { if (actions.DiscreteActions[1] == 1) { space = true; RaycastHit2D hit = Physics2D.Raycast(transform.position, new Vector2(0.1f, 1), 100000.0f, 1); targetPos = hit.point; } else { space = false; } } private void OnTriggerEnter2D(Collider2D collision) { if (collision.tag == "Obstacles") { AddReward(-50f); EndEpisode(); SceneManager.LoadScene(0); } else if (collision.tag == "Checkpoint") { AddReward(1f); } } private void FixedUpdate() { if (space == true) { if (targetPos.x > transform.position.x && rb2D.velocity.x < 20) { rb2D.velocity = new Vector2(rb2D.velocity.x + (0.05f * (20 - rb2D.velocity.x)), rb2D.velocity.y); } else if (rb2D.velocity.x < -20) { rb2D.velocity = new Vector2(rb2D.velocity.x - (0.015f * (20 - rb2D.velocity.x)), rb2D.velocity.y); } if (targetPos.y > transform.position.y && rb2D.velocity.y < 20) { rb2D.velocity = new Vector2(rb2D.velocity.x, rb2D.velocity.y + (0.025f * (20 - rb2D.velocity.y))); } else if (rb2D.velocity.y < -20) { rb2D.velocity = new Vector2(rb2D.velocity.x, rb2D.velocity.y - (0.025f * (20 - rb2D.velocity.y))); } } } }
2. 编辑器侧配置传感器
- 选中挂载
MyAgent脚本的游戏对象,在Inspector面板点击Add Component,搜索添加Camera Sensor组件(实际类型为CameraSensorComponent,是可直接挂载的MonoBehaviour组件) - 在新增的Camera Sensor组件配置页,将用于采集视觉观测的相机拖入
Camera字段,2D正交相机要勾选Orthographic选项避免画面变形 - 根据训练需求调整参数:84*84分辨率是训练速度和精度的常用平衡值,不需要彩色信息可选择Grayscale降低输入维度,动态场景可将
Observation Stacks设为3~4让模型感知物体运动趋势 - 找到同对象上的
Behavior Parameters组件,将Vector Observation下的Space Size值设为和CollectObservations方法中写入的观测数量完全一致:如果没有额外向量观测,该值直接设为0,即可消除观测数不匹配的警告。
3. 配置验证
运行场景后选中Agent对象,在Behavior Parameters组件面板点击Check Sensors按钮,配置正确时会在列表中显示已注册的CameraSensor,Console面板不会再抛出参数异常和观测数不匹配的警告。
注意事项
- 所有继承自
SensorComponent的传感器(包括相机传感器、射线传感器等)都不需要在业务代码中手动获取实例,只要挂载到Agent对象上,框架会自动完成注册和数据读取 - 视觉观测数据不需要手动写入
CollectObservations方法,框架会自动将相机渲染的纹理数据传递给模型 - 配置相机时注意调整Culling Mask,只保留需要模型识别的层,减少无效渲染的资源消耗,避免无关画面干扰模型训练
内容的提问来源于stack exchange,提问作者Ian Weed
相关产品推荐
相关产品推荐

