Unity-ML-Agents-Food Collector环境-FoodCollectorSettings.cs

Recording Statistics:https://github.com/Unity-Technologies/ml-agents/blob/release_19/docs/Learning-Environment-Design.md#recording-statistics

环境链接:https://github.com/Unity-Technologies/ml-agents/tree/release_19/Project/Assets/ML-Agents/Examples/FoodCollector

官方链接:https://github.com/Unity-Technologies/ml-agents/blob/release_19/Project/Assets/ML-Agents/Examples/FoodCollector/Scripts/FoodCollectorSettings.cs

https://github.com/Unity-Technologies/ml-agents/blob/release_19/docs/ML-Agents-Overview.md#additional-features

目录

1.FoodCollectorSettings.cs

1.1 FoodCollectorSettings类

1.1.1 using UnityEngine.UI

1.1.2 public Text scoreText

1.1.3 StatsRecorder m_Recorder

1.2 Awake()函数

1.2.1 Academy.Instance.OnEnvironmentReset += EnvironmentReset

1.2.2 m_Recorder = Academy.Instance.StatsRecorder

1.3 EnvironmentReset()

1.3.1 foreach (var fa in listArea)

1.4 ClearObjects()

1.5 Update()

1.5.1 scoreText.text = $"Score: {totalScore}"

1.5.2 m_Recorder.Add("TotalScore", totalScore)


1.FoodCollectorSettings.cs

using UnityEngine;
using UnityEngine.UI;
using Unity.MLAgents;

public class FoodCollectorSettings : MonoBehaviour
{
    [HideInInspector]
    public GameObject[] agents;  // 所有代理的 GameObject 数组
    [HideInInspector]
    public FoodCollectorArea[] listArea;  // 所有 FoodCollectorArea 的数组

    public int totalScore;  // 总得分
    public Text scoreText;  // 显示得分的 UI Text 对象

    StatsRecorder m_Recorder;  // 记录环境统计信息的 StatsRecorder 对象

    public void Awake()
    {
        // 注册 OnEnvironmentReset 方法,当环境被重置时执行
        Academy.Instance.OnEnvironmentReset += EnvironmentReset;
        m_Recorder = Academy.Instance.StatsRecorder;  // 获取 StatsRecorder 对象
    }

    void EnvironmentReset()
    {
        // 清除所有标签为 "food" 的 GameObject
        ClearObjects(GameObject.FindGameObjectsWithTag("food"));
        // 清除所有标签为 "badFood" 的 GameObject
        ClearObjects(GameObject.FindGameObjectsWithTag("badFood"));

        // 获取所有标签为 "agent" 的 GameObject 并存入 agents 数组
        agents = GameObject.FindGameObjectsWithTag("agent");
        // 获取所有 FoodCollectorArea 并存入 listArea 数组,重置每个 FoodCollectorArea 的食物
        listArea = FindObjectsOfType<FoodCollectorArea>();
        foreach (var fa in listArea)
        {
            fa.ResetFoodArea(agents);
        }

        totalScore = 0;  // 总得分清零
    }

    void ClearObjects(GameObject[] objects)
    {
        // 遍历所有 GameObject,销毁它们
        foreach (var food in objects)
        {
            Destroy(food);
        }
    }

    public void Update()
    {
        scoreText.text = $"Score: {totalScore}";  // 显示总得分

        // 每 100 帧发送环境统计信息到 SideChannel,这些值将被平均每 summary_frequency 步,因此不需要每次 Update() 调用都发送
        if ((Time.frameCount % 100) == 0)
        {
            m_Recorder.Add("TotalScore", totalScore);
        }
    }
}

这段代码是一个Unity脚本,它是FoodCollector场景中的游戏管理器,负责管理游戏的各种设置和重置环境。在FoodCollector游戏中,玩家需要控制代理来收集食物,避开毒物,以获得更高的分数。

在脚本中,有以下的功能:

  • agentslistArea 数组:用于存储场景中的所有代理和食物区域(即游戏中的区域,包含食物和毒物)。
  • totalScorescoreText:用于存储当前分数和在UI中显示分数的文本。
  • m_Recorder:用于记录游戏中的统计信息,这些信息可以通过TensorBoard可视化分析。
  • Awake() 函数:在游戏对象唤醒时,为 OnEnvironmentReset 事件添加事件处理程序,并初始化统计信息记录器。
  • EnvironmentReset() 函数:用于重置游戏环境,清除场景中的食物和毒物,重新设置食物区域,并重置分数。
  • ClearObjects() 函数:用于清除场景中指定标签的所有游戏对象。
  • Update() 函数:每帧更新UI中的分数显示,并定期将分数统计信息记录到 m_Recorder

1.1 FoodCollectorSettings类

using UnityEngine.UI;

public class FoodCollectorSettings : MonoBehaviour
{

    public int totalScore;  // 总得分
    public Text scoreText;  // 显示得分的 UI Text 对象

    StatsRecorder m_Recorder;

}

1.1.1 using UnityEngine.UI

using UnityEngine.UI;

UnityEngine.UI 是 Unity 引擎中用于实现 UI 界面的命名空间,包括了常见的 UI 元素类,例如 TextButtonImage 等。在使用这些类之前,需要先添加引用:using UnityEngine.UI;,这样可以避免每次使用时都需要输入完整的命名空间。

1.1.2 public Text scoreText

public Text scoreText;

这行代码定义了一个名为scoreText的公共变量,其类型为Text。在Unity中,Text是用于显示文本的组件。定义公共变量可以让其他脚本访问和修改该变量。这个变量通常用于在游戏界面上显示游戏分数等信息。

1.1.3 StatsRecorder m_Recorder

StatsRecorder m_Recorder; 

StatsRecorder是ML-Agents中的一个类,它用于记录模拟器的统计数据。在这个代码段中,m_Recorder是一个StatsRecorder类型的变量,它被赋值为Academy.Instance.StatsRecorder。这意味着该变量指向ML-Agents中全局的统计记录器实例,可以使用它来记录模拟器中的数据,比如训练期间的分数,完成的任务数等等。

1.2 Awake()函数

    public void Awake()
    {
        // 注册 OnEnvironmentReset 方法,当环境被重置时执行
        Academy.Instance.OnEnvironmentReset += EnvironmentReset;
        m_Recorder = Academy.Instance.StatsRecorder;  // 获取 StatsRecorder 对象
    }

Awake() 是 MonoBehaviour 的一个生命周期函数,用于在场景中创建一个物体时进行初始化。当场景中创建一个包含 FoodCollectorSettings 脚本的游戏对象时,Awake() 函数会被调用一次

在这个函数中,首先调用 Academy.Instance.OnEnvironmentReset += EnvironmentReset; 语句,将 EnvironmentReset() 函数注册到了 OnEnvironmentReset 事件中,这个事件是在每个Episode(训练周期)开始时触发的。这样,当Agent开始一个新的训练周期时,EnvironmentReset() 函数就会被调用,用于重置场景状态和数据。

接着,使用 Academy.Instance.StatsRecorder 获取了一个名为 m_RecorderStatsRecorder 对象,该对象用于在训练过程中收集统计信息,例如每个Episode的得分情况,用于在训练过程中监控智能体的学习效果。这样在后续的代码中就可以使用 m_Recorder 对象来收集并发送统计信息。

1.2.1 Academy.Instance.OnEnvironmentReset += EnvironmentReset

  Academy.Instance.OnEnvironmentReset += EnvironmentReset;

这行代码用于将 EnvironmentReset 方法添加到 Academy 实例的 OnEnvironmentReset 事件中OnEnvironmentReset 事件在每次环境重置时触发。在本例中,当环境重置时,EnvironmentReset 方法被调用。因此,通过这行代码,当环境重置时,可以确保 EnvironmentReset 方法被自动调用。

1.2.2 m_Recorder = Academy.Instance.StatsRecorder

 m_Recorder = Academy.Instance.StatsRecorder; 

这行代码的作用是将ML-Agents Academy实例的统计记录器(StatsRecorder)存储到类成员变量m_Recorder中,以便在后续代码中使用StatsRecorder负责收集训练期间的统计信息(例如训练损失、奖励等),并将其发送到TensorBoard中进行可视化分析。通过将m_Recorder成员变量设置为Academy.Instance.StatsRecorder,可以轻松地记录并发送任何自定义的统计信息。

1.3 EnvironmentReset()

    void EnvironmentReset()
    {
        // 清除所有标签为 "food" 的 GameObject
        ClearObjects(GameObject.FindGameObjectsWithTag("food"));
        // 清除所有标签为 "badFood" 的 GameObject
        ClearObjects(GameObject.FindGameObjectsWithTag("badFood"));

        // 获取所有标签为 "agent" 的 GameObject 并存入 agents 数组
        agents = GameObject.FindGameObjectsWithTag("agent");
        // 获取所有 FoodCollectorArea 并存入 listArea 数组,重置每个 FoodCollectorArea 的食物
        listArea = FindObjectsOfType<FoodCollectorArea>();
        foreach (var fa in listArea)
        {
            fa.ResetFoodArea(agents);
        }

        totalScore = 0;  // 总得分清零
    }

EnvironmentReset 函数在每次环境重置时被调用,它的作用是:

①清除之前生成的所有标签为 "food" 的游戏对象和标签为 "badFood" 的游戏对象。

②获取所有标签为 "agent" 的游戏对象,并将它们存入 agents 数组。

③获取所有的 FoodCollectorArea 组件,将它们存入 listArea 数组,并重置每个 FoodCollectorArea 中的食物。

④将 totalScore 清零,准备开始新的一轮游戏。

1.3.1 foreach (var fa in listArea)

        foreach (var fa in listArea)
        {
            fa.ResetFoodArea(agents);
        }

这段代码的作用是对每个 FoodCollectorArea 进行重置操作。在重置过程中,每个 FoodCollectorArea 的食物需要重新生成并放置在特定的位置,这些位置是与所有 agent 相关的。因此,需要传递 agents 数组作为参数,使每个 FoodCollectorArea 的食物与所有 agent 有关。这个过程中会调用 FoodCollectorArea 类中的 ResetFoodArea 方法来完成具体的重置操作。

1.4 ClearObjects()

    void ClearObjects(GameObject[] objects)
    {
        // 遍历所有 GameObject,销毁它们
        foreach (var food in objects)
        {
            Destroy(food);
        }
    }

这个函数的作用是清除所有传入数组 objects 中的 GameObject 对象。它首先遍历数组中的每个 GameObject,然后使用 Destroy() 函数销毁它们。在这段代码中,它被用来清除所有标签为 "food" 和 "badFood" 的 GameObject,因为这些 GameObject 会在环境重置时被重新生成。

1.5 Update()

    public void Update()
    {
        scoreText.text = $"Score: {totalScore}";  // 显示总得分

        // 每 100 帧发送环境统计信息到 SideChannel,这些值将被平均每 summary_frequency 步,因此不需要每次 Update() 调用都发送
        if ((Time.frameCount % 100) == 0)
        {
            m_Recorder.Add("TotalScore", totalScore);
        }
    }

这段代码是在游戏每一帧更新时调用的,它的主要作用是更新显示总得分的文本和将总得分发送给 StatsRecorder,以便将其记录在 TensorBoard 中。

首先,它将 totalScore 显示在 UI 中,以字符串 "Score: " 为前缀。

然后,它检查帧数是否为 100 的倍数,如果是,则将当前总得分值 totalScore 通过 StatsRecorder 发送到 TensorBoard 中。StatsRecorder 是一个用于记录环境统计信息的类,可以记录一些代理的学习进度、环境统计信息等。发送环境统计信息到 SideChannel,这些值将被平均每 summary_frequency 步,因此不需要每次 Update() 调用都发送,减轻了资源消耗。

问:这些统计信息可以通过 StatsRecorder 对象的 Add() 方法添加到 SideChannel 中,以便在 TensorBoard 中进行可视化和分析?SideChannel ?

这些统计信息可以通过 StatsRecorder 对象的 Add() 方法添加到 SideChannel 中。SideChannel 是 Unity ML-Agents 用于在训练期间传输数据的可选通道,它们提供了一种机制来共享和访问来自环境、代理和其他来源的数据。SideChannel 通常用于跟踪和分析训练期间的统计信息,例如训练代理的总回报或每个代理的动作分布等。StatsRecorder 是一种方便的 SideChannel,它可以用于记录任意数量的统计信息,并将它们发送到 TensorBoard 中进行分析和可视化。

1.5.1 scoreText.text = $"Score: {totalScore}"

scoreText.text = $"Score: {totalScore}"; 

这行代码将总得分 totalScore 显示在 UI 元素 scoreText 上,其中 $"Score: {totalScore}" 是一个字符串插值表达式,将字符串 "Score: " 和 totalScore 的值插入其中,形成最终的文本字符串。通过将该文本赋值给 scoreText.text 属性,更新 UI 元素上的文本显示。如果当前 totalScore 的值为 10,那么最终的文本字符串会是 "Score: 10"。

1.5.2 m_Recorder.Add("TotalScore", totalScore)

m_Recorder.Add("TotalScore", totalScore)

这句代码将当前的总得分值 totalScore 添加到 StatsRecorder 对象的 TotalScore 统计信息中。这些统计信息可以通过 StatsRecorder 对象的 Add() 方法添加到 SideChannel 中,以便在 TensorBoard 中进行可视化和分析。在这里,每隔 100 帧发送一次环境统计信息,以减少发送的数据量,提高效率。

问 :"TotalScore" ?

"TotalScore" 是指将被记录到 TensorBoard 中的数据的名称。在这个例子中,我们将记录每个环境重置后的总分数。通过将名称设置为"TotalScore",我们可以轻松地在 TensorBoard 中找到此数据并进行分析和比较。当然,您可以将其设置为任何您喜欢的名称,只要在后续分析过程中使用相应的名称即可。

问:m_Recorder ?

m_Recorder 是一个 StatsRecorder 类型的变量,它是 Unity ML-Agents 中的一个工具,用于记录和保存模型的统计信息,例如奖励、损失、成功率等等。可以通过它将这些统计信息发送到 TensorBoard 中进行可视化分析。在这段代码中,使用 m_Recorder.Add() 方法将当前的总得分 totalScore 记录下来,并指定了它在 TensorBoard 中的名称为 "TotalScore",以便在 TensorBoard 中进行查看和分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天寒心亦热

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值