Given a scenario where an farmer agent walks around a meadow that is randomly generated with
a farmer, horse, pig, chicken and various obstacles like trees and boulders. does the following
scripts look okay? If not what may i need to change?
farmeragent.cs using System.Collections; using System.Collections.Generic; using UnityEngine;
using UnityEngine.AI; using Unity.MLAgents; using Unity.MLAgents.Actuators; using
Unity.MLAgents.Sensors; public class FarmerAgent : Agent { public GameObject horse; public
GameObject pig; public GameObject chicken; public GameObject foodPrefab; public Transform
foodDropPoint; public NavMeshAgent navMeshAgent; private bool isHorseFed; private bool
isPigFed; private bool isChickenFed; private List<GameObject> foodObjects = new
List<GameObject>(); private void Start() { navMeshAgent = GetComponent<NavMeshAgent>(); }
public override void OnEpisodeBegin() { isHorseFed = false; isPigFed = false; isChickenFed =
false; // Reset animal hunger horse.GetComponent<AnimalAgent>().isFed = false;
pig.GetComponent<AnimalAgent>().isFed = false; chicken.GetComponent<AnimalAgent>().isFed
= false; // Destroy all food objects foreach (GameObject foodObject in foodObjects) {
Destroy(foodObject); } // Spawn new food objects for (int i = 0; i < 3; i++) { Vector3 randomPosition
= new Vector3(Random.Range(-5f, 5f), 0f, Random.Range(-5f, 5f)); GameObject foodObject =
Instantiate(foodPrefab, randomPosition + foodDropPoint.position, Quaternion.identity);
foodObjects.Add(foodObject); } // Move farmer to random position Vector3 farmerPosition = new
Vector3(Random.Range(-4f, 4f), 0f, Random.Range(-4f, 4f));
navMeshAgent.Warp(farmerPosition); } public override void CollectObservations(VectorSensor
sensor) { // Is each animal fed? sensor.AddObservation(isHorseFed);
sensor.AddObservation(isPigFed); sensor.AddObservation(isChickenFed); } public override void
OnActionReceived(ActionBuffers actions) { Vector3 position = transform.position; Vector3 forward
= transform.forward; float moveSpeed = 0f; float turnSpeed = 0f; int action =
actions.DiscreteActions[0]; switch (action) { case 0: // Move forward moveSpeed = 1f; break; case
1: // Move backward moveSpeed = -1f; break; case 2: // Turn left turnSpeed = -1f; break; case 3: //
Turn right turnSpeed = 1f; break; case 4: // Drop apple for horse DropFood(horse,
FoodType.Apple); break; case 5: // Drop truffle for pig DropFood(pig, FoodType.Truffle); break;
case 6: // Drop corn for chicken DropFood(chicken, FoodType.Corn); break; default: break; } //
Apply movement and rotation transform.Translate(moveSpeed * Time.deltaTime *
transform.forward, Space.World); transform.Rotate(0f, turnSpeed * Time.deltaTime * 100f, 0f); //
Update perception sensors horseSensor.UpdateSensor(); pigSensor.UpdateSensor();
chickenSensor.UpdateSensor(); } private void DropFood(GameObject animal, FoodType
foodType) { if (animal == null) { return; } Vector3 dropPosition = animal.transform.position +
Vector3.up; GameObject foodObject.
Given a scenario where an farmer agent walks around a meadow.pdf
1. Given a scenario where an farmer agent walks around a meadow that is randomly generated with
a farmer, horse, pig, chicken and various obstacles like trees and boulders. does the following
scripts look okay? If not what may i need to change?
farmeragent.cs using System.Collections; using System.Collections.Generic; using UnityEngine;
using UnityEngine.AI; using Unity.MLAgents; using Unity.MLAgents.Actuators; using
Unity.MLAgents.Sensors; public class FarmerAgent : Agent { public GameObject horse; public
GameObject pig; public GameObject chicken; public GameObject foodPrefab; public Transform
foodDropPoint; public NavMeshAgent navMeshAgent; private bool isHorseFed; private bool
isPigFed; private bool isChickenFed; private List<GameObject> foodObjects = new
List<GameObject>(); private void Start() { navMeshAgent = GetComponent<NavMeshAgent>(); }
public override void OnEpisodeBegin() { isHorseFed = false; isPigFed = false; isChickenFed =
false; // Reset animal hunger horse.GetComponent<AnimalAgent>().isFed = false;
pig.GetComponent<AnimalAgent>().isFed = false; chicken.GetComponent<AnimalAgent>().isFed
= false; // Destroy all food objects foreach (GameObject foodObject in foodObjects) {
Destroy(foodObject); } // Spawn new food objects for (int i = 0; i < 3; i++) { Vector3 randomPosition
= new Vector3(Random.Range(-5f, 5f), 0f, Random.Range(-5f, 5f)); GameObject foodObject =
Instantiate(foodPrefab, randomPosition + foodDropPoint.position, Quaternion.identity);
foodObjects.Add(foodObject); } // Move farmer to random position Vector3 farmerPosition = new
Vector3(Random.Range(-4f, 4f), 0f, Random.Range(-4f, 4f));
navMeshAgent.Warp(farmerPosition); } public override void CollectObservations(VectorSensor
sensor) { // Is each animal fed? sensor.AddObservation(isHorseFed);
sensor.AddObservation(isPigFed); sensor.AddObservation(isChickenFed); } public override void
OnActionReceived(ActionBuffers actions) { Vector3 position = transform.position; Vector3 forward
= transform.forward; float moveSpeed = 0f; float turnSpeed = 0f; int action =
actions.DiscreteActions[0]; switch (action) { case 0: // Move forward moveSpeed = 1f; break; case
1: // Move backward moveSpeed = -1f; break; case 2: // Turn left turnSpeed = -1f; break; case 3: //
Turn right turnSpeed = 1f; break; case 4: // Drop apple for horse DropFood(horse,
FoodType.Apple); break; case 5: // Drop truffle for pig DropFood(pig, FoodType.Truffle); break;
case 6: // Drop corn for chicken DropFood(chicken, FoodType.Corn); break; default: break; } //
Apply movement and rotation transform.Translate(moveSpeed * Time.deltaTime *
transform.forward, Space.World); transform.Rotate(0f, turnSpeed * Time.deltaTime * 100f, 0f); //
Update perception sensors horseSensor.UpdateSensor(); pigSensor.UpdateSensor();
chickenSensor.UpdateSensor(); } private void DropFood(GameObject animal, FoodType
foodType) { if (animal == null) { return; } Vector3 dropPosition = animal.transform.position +
Vector3.up; GameObject foodObject = Instantiate(foodPrefab, dropPosition, Quaternion.identity);
foodObject.GetComponent<Food>().foodType = foodType;
foodObject.GetComponent<Food>().targetAnimal = animal; } private void ResetFlags() {
isHorseFed = false; isPigFed = false; isChickenFed = false; } private void OnDrawGizmos() { if
(showPerceptionGizmos) { horseSensor.OnDrawGizmos(); pigSensor.OnDrawGizmos();
chickenSensor.OnDrawGizmos(); } } }
Animalagent.cs using System.Collections; using System.Collections.Generic; using UnityEngine;
using UnityEngine.AI; public class AnimalAgent : Agent { public enum FoodType { Apple, Truffle,
2. Worm } public FoodType preferredFood; public bool isFed = false; private NavMeshAgent
navMeshAgent; private Transform targetTransform; private void Awake() { navMeshAgent =
GetComponent<NavMeshAgent>(); } public override void AgentReset() { isFed = false; } public
override void CollectObservations() { // No observations needed for the animal agents } public
override void AgentAction(float[] vectorAction, string textAction) { // No actions needed for the
animal agents } public void SetTarget(Transform target) { targetTransform = target;
MoveToTarget(targetTransform.position); } private void MoveToTarget(Vector3 targetPosition) {
navMeshAgent.SetDestination(targetPosition); } private void OnTriggerEnter(Collider other) { if
(other.CompareTag("Food")) { Food food = other.GetComponent<Food>(); if (food.foodType ==
preferredFood && !isFed) { isFed = true; AddReward(1.0f); } else { AddReward(-1.0f); }
food.Consume(); } else if (other.CompareTag("Wall") || other.CompareTag("Obstacle")) {
AddReward(-0.1f); } } }
meadowarea.cs using System.Collections.Generic; using UnityEngine; using Unity.MLAgents;
using Unity.MLAgents.Sensors; public class MeadowArea : MonoBehaviour { public GameObject
treePrefab; public GameObject rockPrefab; public GameObject foodPrefab; public int numTrees;
public int numRocks; public int numFood; public List<AnimalAgent> animalAgents; public
FarmerAgent farmerAgent; public float rangeX = 20f; public float rangeZ = 20f; private
List<GameObject> trees; private List<GameObject> rocks; private List<GameObject> food; public
void ResetArea() { PlaceObjects(numTrees, treePrefab, trees); PlaceObjects(numRocks,
rockPrefab, rocks); PlaceObjects(numFood, foodPrefab, food); farmerAgent.transform.position =
GetRandomSpawnPos(); farmerAgent.transform.rotation = Quaternion.Euler(0f,
Random.Range(0, 360), 0f); foreach (var animalAgent in animalAgents) {
animalAgent.transform.position = GetRandomSpawnPos(); animalAgent.transform.rotation =
Quaternion.Euler(0f, Random.Range(0, 360), 0f); } } private void Awake() { trees = new
List<GameObject>(); rocks = new List<GameObject>(); food = new List<GameObject>();
SpawnAgents(); } private void SpawnAgents() { foreach (var animalAgent in animalAgents) {
animalAgent.SetMeadowArea(this); animalAgent.transform.position = GetRandomSpawnPos();
animalAgent.transform.rotation = Quaternion.Euler(0f, Random.Range(0, 360), 0f);
animalAgent.gameObject.SetActive(true); } farmerAgent.SetMeadowArea(this);
farmerAgent.transform.position = GetRandomSpawnPos(); farmerAgent.transform.rotation =
Quaternion.Euler(0f, Random.Range(0, 360), 0f); farmerAgent.gameObject.SetActive(true); }
private void PlaceObjects(int numObjects, GameObject prefab, List<GameObject> objectList) { for
(int i = 0; i < numObjects; i++) { GameObject spawnedObject = Instantiate(prefab,
GetRandomSpawnPos(), Quaternion.identity); objectList.Add(spawnedObject); } } private Vector3
GetRandomSpawnPos() { float xPos = Random.Range(-rangeX, rangeX); float zPos =
Random.Range(-rangeZ, rangeZ); Vector3 randomPos = new Vector3(xPos, 0f, zPos); return
randomPos; } private void OnTriggerEnter(Collider other) { if (other.CompareTag("Food")) {
food.Remove(other.gameObject); Destroy(other.gameObject); } } private void
OnDrawGizmosSelected() { Gizmos.color = Color.yellow;
Gizmos.DrawWireCube(transform.position, new Vector3(rangeX * 2f, 0f, rangeZ * 2f)); } }
fooditem.cs using System.Collections; using System.Collections.Generic; using UnityEngine;
using Unity.MLAgents; public class FoodItem : MonoBehaviour { public Food foodType; }