强化学习+Unity仿真(三):C#脚本编写(二)

创建C#脚本,包括如何手动控制智能体,智能体的观测空间、动作空间,强化学习的奖励函数等。
注:本文所有代码均来自于官方入门教程,仅作学习使用。


一、FlowerArea.cs

双击FlowerArea.cs脚本文件,在代码编辑器中打开脚本文件。清除掉FlowerArea类里原本的内容。

1.属性

在定义之前,首先应明确,在该任务场景中,花以一簇一簇的形式(FlowerCluster)随机分布在智能体可活动区域内,每簇中包含多株花(FlowerPlant),每株又包含多个FlowerBud,每个FlowerBud包含一个Flower(与上节中定义的Flower.cs绑定),每个Flower中包含一个花朵碰撞体和花蜜碰撞体和一些花蕊。如图所示。蜂鸟的喙与花蜜碰撞体发生碰撞时视为在采蜜。
在这里插入图片描述
该类代表蜂鸟的活动范围,有三个属性:区域的半径;包含区域内所有FlowerPlant的列表;包含区域内所有FlowerNectarCollider及其所属的Flower的字典;包含区域内所有Flower的列表。

	// The diameter of the area where the agent and flowers can be
    // used for observing relative distance from agent to flower
    public const float AreaDiameter = 20f;

    // The list of all flower plants in this flower area (flower plants have multiple flowers)
    private List<GameObject> flowerPlants;

    // A lookup dictionary for looking up a flower from a nectar collider
    private Dictionary<Collider, Flower> nectarFlowerDictionary;

    /// <summary>
    /// The list of all flowers in the flower area
    /// </summary>
    public List<Flower> Flowers { get; private set; }

2.方法

下面的方法实现重置智能体活动范围内的所有花。

 	/// <summary>
    /// Reset the flowers and flower plants
    /// </summary>
    public void ResetFlowers()
    {
        // Rotate each flower plant around the Y axis and subtly around X and Z
        foreach (GameObject flowerPlant in flowerPlants)
        {
            float xRotation = UnityEngine.Random.Range(-5f, 5f);
            float yRotation = UnityEngine.Random.Range(-180f, 180f);
            float zRotation = UnityEngine.Random.Range(-5f, 5f);
            flowerPlant.transform.localRotation = Quaternion.Euler(xRotation, yRotation, zRotation);
        }

        // Reset each flower
        foreach (Flower flower in Flowers)
        {
            flower.ResetFlower();
        }
    }

下面的方法实现查找FlowerNectarCollider所属的Flower。

	/// <summary>
    /// Gets the <see cref="Flower"/> that a nectar collider belongs to
    /// </summary>
    /// <param name="collider">The nectar collider</param>
    /// <returns>The matching flower</returns>
    public Flower GetFlowerFromNectar(Collider collider)
    {
        return nectarFlowerDictionary[collider];
    }

Awake 方法是 MonoBehaviour 类提供的一个回调方法,它在脚本实例被加载时执行,用于完成一些初始化的操作。

 /// <summary>
    /// Called when the area wakes up
    /// </summary>
    private void Awake()
    {
        // Initialize variables
        flowerPlants = new List<GameObject>();
        nectarFlowerDictionary = new Dictionary<Collider, Flower>();
        Flowers = new List<Flower>();

        // Find all flowers that are children of this GameObject/Transform
        FindChildFlowers(transform);
    }

下面的方法被上面的Awake方法调用,递归查找所有的FlowerPlant和Flower。同时在Assets/Hummingbird/Prefabs目录下双击FlowerPlant,在属性检查器里修改其标签为flower_plant

 	/// <summary>
    /// Recursively finds all flowers and flower plants that are children of a parent transform
    /// </summary>
    /// <param name="parent">The parent of the children to check</param>
    private void FindChildFlowers(Transform parent)
    {
        for (int i = 0; i < parent.childCount; i++)
        {
            Transform child = parent.GetChild(i);

            if (child.CompareTag("flower_plant"))
            {
                // Found a flower plant, add it to the flowerPlants list
                flowerPlants.Add(child.gameObject);

                // Look for flowers within the flower plant
                FindChildFlowers(child);
            }
            else
            {
                // Not a flower plant, look for a Flower component
                Flower flower = child.GetComponent<Flower>();
                if (flower != null)
                {
                    // Found a flower, add it to the Flowers list
                    Flowers.Add(flower);

                    // Add the nectar collider to the lookup dictionary
                    nectarFlowerDictionary.Add(flower.nectarCollider, flower);

                    // Note: there are no flowers that are children of other flowers
                }
                else
                {
                    // Flower component not found, so check children
                    FindChildFlowers(child);
                }
            }
        }
    }

3.绑定脚本

在Unity编辑器中将该脚本绑定到FloatingIsland上。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值