赞
踩
创建C#脚本,包括如何手动控制智能体,智能体的观测空间、动作空间,强化学习的奖励函数等。
注:本文所有代码均来自于官方入门教程,仅作学习使用。
首先,在项目资源管理窗口Hummingbird文件夹下新建一个Scripts文件夹,在Scripts文件夹下新建三个C#脚本文件:Flower.cs,FlowerArea.cs,HummingbirdAgent.cs。
双击脚本文件,在代码编辑器中打开脚本文件。
双击打开脚本文件,显示如下。
将Flower类里的所有内容清空,按下面的步骤完善类的成员。
首先,定义花的两种状态(有无花蜜)分别对应的颜色,其次定义了花及花蜜两个碰撞体,以及花的材质。
[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;
其中,[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; } }
下面定义两个属性,花中花蜜的数量、是否有花蜜。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;
}
}
定义如下方法,计算被采走的花蜜的数量并更新剩余花蜜数量,如果剩余花蜜为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; }
定义如下方法,实现重置花和花蜜的状态。
/// <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);
}
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>();
}
在Assets/Hummingbird/Prefabs目录下双击FlowerBlud,然后在层级窗口中选中Flower,在属性检查器里点击“Add Component”按钮,输入脚本名称后选中完成添加。属性检查器里多出如下所示选项卡。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。