当前位置:   article > 正文

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

c#脚本编程

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


一、建立脚本文件

首先,在项目资源管理窗口Hummingbird文件夹下新建一个Scripts文件夹,在Scripts文件夹下新建三个C#脚本文件:Flower.cs,FlowerArea.cs,HummingbirdAgent.cs。
在这里插入图片描述
双击脚本文件,在代码编辑器中打开脚本文件。

二、Flower.cs脚本编写

双击打开脚本文件,显示如下。
在这里插入图片描述
将Flower类里的所有内容清空,按下面的步骤完善类的成员。

1.类的属性

首先,定义花的两种状态(有无花蜜)分别对应的颜色,其次定义了花及花蜜两个碰撞体,以及花的材质。

    [Tooltip("The color when the flower is full")]
    public Color fullFlowerColor = new Color(1f, 0f, .3f);

    [Tooltip("The color when the flower is empty")]
    public Color emptyFlowerColor = new Color(.5f, 0f, 1f);

    /// <summary>
    /// The trigger collider representing the nectar
    /// </summary>
    [HideInInspector]
    public Collider nectarCollider;

    // The solid collider representing the flower petals
    private Collider flowerCollider;

    //The flower's material
    private Material flowerMaterial;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

其中,[Tooltip(“The color when the flower is full”)] 是一个属性标签,用于给变量添加一个工具提示。通过将该标签放置在变量声明的上方,可以为该变量提供一段描述性的文本,作为在Unity编辑器中悬停在变量上时显示的提示信息。

而将[HideInInspector]标签放在变量声明的上方时,该变量将不会在Inspector面板中显示出来,无论该变量是公共的还是私有的。这样做可以保护变量的信息,并避免开发人员在编辑器中误操作或调整变量的值。

下面定义两个属性,分别为碰撞体nectarCollider的上方向和中心点坐标。当使用FlowerUpVector属性时,getter方法会通过nectarCollider.transform.up来获取nectarCollider对象的上方向向量,并将其作为返回值。FlowerCenterPosition属性同理。

 	/// <summary>
    /// A vector pointing straight out of the flower
    /// </summary>
    public Vector3 FlowerUpVector
    {
        get
        {
            return nectarCollider.transform.up;
        }
    }
    
    ///<summary>
    ///The center position of the nectar collider
    /// </summary>
    public Vector3 FlowerCenterPosition
    {
        get
        {
            return nectarCollider.transform.position;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

下面定义两个属性,花中花蜜的数量、是否有花蜜。NectarAmount是一个公共属性,其值可以在类外部进行读取,但只能在类内部进行写入。

	/// <summary>
    /// The amount of nectar remaining in the flower
    /// </summary>
    public float NectarAmount { get; private set; }
    /// <summary>
    /// Whether the flower has any nectar remaining
    /// </summary>
    public bool HasNectar
    {
        get
        {
            return NectarAmount > 0f;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

2.类的方法

定义如下方法,计算被采走的花蜜的数量并更新剩余花蜜数量,如果剩余花蜜为0则改变花和花蜜碰撞体为非激活状态,并改变花的颜色。

 	/// <summary>
    /// Attempts to remove nectar from the flower
    /// </summary>
    /// <param name="amount">The amount of nectar to remove</param>param>
    /// <returns>The actual amount successfully removed</returns>
    public float Feed(float amount)
    {
        //Track how much nectar was successfully taken(cannot take more than is available)
        float nectarTaken = Mathf.Clamp(amount, 0f, NectarAmount);

        //Subtract the nectar
        NectarAmount -= nectarTaken;

        if (NectarAmount <= 0)
        {
            //No nectar remaining
            NectarAmount = 0;

            //Disable the flower and nectar colliders
            flowerCollider.gameObject.SetActive(false);
            nectarCollider.gameObject.SetActive(false);

            //Change the flower color to indicate that it is empty
            flowerMaterial.SetColor("_BaseColor", emptyFlowerColor);
        }

        //Return the amount of nectar that was taken
        return nectarTaken;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

定义如下方法,实现重置花和花蜜的状态。

	/// <summary>
    /// Resets the flower
    /// </summary>
    public void ResetFlower()
    {
        //Refill the nectar
        NectarAmount = 1f;

        //Enable the flower and nectar colliders
        flowerCollider.gameObject.SetActive(true);
        nectarCollider.gameObject.SetActive(true);

        //Change the flower color to indicate that it is full
        flowerMaterial.SetColor("_BaseColor", fullFlowerColor);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

Awake 方法是 MonoBehaviour 类提供的一个回调方法,它在脚本实例被加载时执行,用于完成一些初始化的操作。在这里主要完成:
将当前游戏对象所使用的材质赋给flowerMaterial变量;
在当前游戏对象下找到名为 “FlowerCollider” 的子对象,并获取该子对象上的 Collider 组件。将获取到的 Collider 赋值给 flowerCollider 变量;
在当前游戏对象下找到名为 “FlowerNectarCollider” 的子对象,并获取该子对象上的 Collider 组件。将获取到的 Collider 赋值给 nectarCollider 变量。

    /// <summary>
    /// Called when the flower wakes up
    /// </summary>
    private void Awake()
    {
        //Find the flower's mesh render and get the main material
        MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
        flowerMaterial = meshRenderer.material;

        //Find flower and nectar colliders
        flowerCollider = transform.Find("FlowerCollider").GetComponent<Collider>();
        nectarCollider = transform.Find("FlowerNectarCollider").GetComponent<Collider>();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

三、脚本绑定

在Assets/Hummingbird/Prefabs目录下双击FlowerBlud,然后在层级窗口中选中Flower,在属性检查器里点击“Add Component”按钮,输入脚本名称后选中完成添加。属性检查器里多出如下所示选项卡。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/108404
推荐阅读
相关标签
  

闽ICP备14008679号