// Update is called once per frame void Update() { //Acquire player if spawned in if (gameManager.gameStarted) { //Acquire player if spawned in target = gameManager.playerDreadnaught; // Heursitic function here attackOrFlee = (Friends() * health) + hunger * (((speed * targetRadius) / 5000) + (health * healingFactor) / 10); if (attackOrFlee >= 1000) { droneBehaviour = DroneBehaviours.Attacking; } else if (attackOrFlee < 1000) { if (motherShip != null) { droneBehaviour = DroneBehaviours.Fleeing; } else { droneBehaviour = DroneBehaviours.Attacking; } } //droneBehaviour = DroneBehaviours.Attacking; } // //Move towards valid targets // if(target) // MoveTowardsTarget(target.transform.position); //Boid cohesion/segregation BoidBehaviour(); //Drone Behaviours - State Switching switch (droneBehaviour) { case DroneBehaviours.Scouting: Scouting(); break; case DroneBehaviours.Foraging: Forage(); break; case DroneBehaviours.EliteForaging: EliteForage(); break; case DroneBehaviours.Attacking: Attacking(); break; case DroneBehaviours.Fleeing: Fleeing(); break; } RegenHealth(); }
// Method used by elite foragers private void EliteForage() { // if no new objects - perform foraging duties if (!newResourceObject) { Forage(); // periodically check for better resources on the way if (Time.time > detectTimer) { newResourceObject = DetectNewResources(); detectTimer = Time.time + detectTime; } // If a new resource is found and the drone does not have any current cargo } else { if (cargo == 0) { // Compare this new resource against the original and check if knowledge about it is already with mothership if ((newResourceObject.GetComponent <Asteroid> ().resource < target.GetComponent <Asteroid> ().resource) || (motherShip.GetComponent <Mothership>().resourceObjects.Contains(newResourceObject))) { newResourceObject = null; } else { // if new resource is better - become scout and report back droneBehaviour = DroneBehaviours.Scouting; } } } }
// Drone FSM Behaviour - Fleeing private void Fleeing() { //Calculate target's velocity (without using RB) tarVel = (target.transform.position - tarPrevPos) / Time.deltaTime; tarPrevPos = target.transform.position; //Calculate intercept position (p = t + r * d * v) and multiply it by -1 to get the flee vector fleePos = (target.transform.position + distanceRatio * Vector3.Distance(transform.position, target.transform.position) * tarVel) * -1.0f; //Flee if mothership alive, else attack instead if (Vector3.Distance(transform.position, target.transform.position) > (targetRadius * 5.0f)) { if (motherShip) { if (Vector3.Distance(transform.position, motherShip.transform.position) > (targetRadius)) { MoveTowardsTarget(motherShip.transform.position); Debug.DrawLine(transform.position, motherShip.transform.position, Color.green); } } else { droneBehaviour = DroneBehaviours.Attacking; } } else { MoveTowardsTarget(fleePos); Debug.DrawLine(transform.position, fleePos, Color.yellow); } }
private void Repair() { if (health < maxHealth) { health += repairRate * Time.deltaTime; Debug.Log("Repair"); } if (health > maxHealth) { health = maxHealth; if (gameManager.gameStarted) { attackOrFlee = health * Friends(); if (attackOrFlee >= 1000) { droneBehaviour = DroneBehaviours.Attacking; } else if (attackOrFlee < 1000) { droneBehaviour = DroneBehaviours.Fleeing; } } } }
//Same as normal because local area search did not work correctly, cleaned up code for presentation private void EliteForaging(Asteroid target) { //Move toward target MoveTowardsTarget(target.transform.position); //Determine the distance from target Debug.DrawLine(transform.position, target.transform.position, Color.red); Vector3 heading = target.transform.position - transform.position; float distance = heading.magnitude; //if in range, harvest what you can, then return if (distance <= targetRadius) { if (resourceTarget.resource > 10) { currentLoad = resourceCapacity; resourceTarget.resource -= currentLoad; } else { currentLoad = currentLoad + resourceTarget.resource; resourceTarget.resource = 0; } droneBehaviour = DroneBehaviours.ReturningResources; } }
// Update is called once per frame void Update() { //Acquire player if spawned in if (gameManager.gameStarted) { target = gameManager.playerDreadnaught; if (droneBehaviour == DroneBehaviours.Attacking || droneBehaviour == DroneBehaviours.Fleeing) { attackOrFlee = health * Friends(); if (attackOrFlee >= 1000) { droneBehaviour = DroneBehaviours.Attacking; } else if (attackOrFlee < 1000) { droneBehaviour = DroneBehaviours.Fleeing; } } } //Move towards valid targets else if (target) { MoveTowardsTarget(target.transform.position); } BoidBehaviour(); switch (droneBehaviour) { case DroneBehaviours.Scouting: Scouting(); break; case DroneBehaviours.Attacking: Attacking(); break; case DroneBehaviours.Fleeing: Fleeing(); break; case DroneBehaviours.Idle: Repair(); Roam(); return; case DroneBehaviours.Foraging: Forage(); return; case DroneBehaviours.Return: Return(); return; } }
public void StartForaging(bool elite) { droneBehaviour = DroneBehaviours.Foraging; target = motherShip.GetComponent <Mothership>().FindResourceInRange(maxRange, gameObject); currentResource = target.GetComponent <Asteroid>().resource; forageTarget = target; this.elite = elite; }
//Drone FSM Behaviour - Scouting private void Scouting() { //If no new resource object found if (!newResourceObject) { //If close to scoutPosition, randomize new position to investigate within gamespace around mothership if (Vector3.Distance(transform.position, scoutPosition) < detectionRadius && Time.time > scoutTimer) { //Generate new random position Vector3 position; position.x = motherShip.transform.position.x + Random.Range(-1500, 1500); position.y = motherShip.transform.position.y + Random.Range(-400, 400); position.z = motherShip.transform.position.z + Random.Range(-1500, 1500); scoutPosition = position; //Update scoutTimer scoutTimer = Time.time + scoutTime; } else { MoveTowardsTarget(scoutPosition); Debug.DrawLine(transform.position, scoutPosition, Color.yellow); } //Every few seconds, check for new resources if (Time.time > detectTimer) { newResourceObject = DetectNewResources(); detectTimer = Time.time + detectTime; } } //Resource found, head back to Mothership else { target = motherShip; //In range of mothership, relay information and reset to drone again if (Vector3.Distance(transform.position, motherShip.transform.position) < targetRadius) { motherShip.GetComponent <Mothership> ().drones.Add(this.gameObject); motherShip.GetComponent <Mothership> ().scouts.Remove(this.gameObject); motherShip.GetComponent <Mothership> ().resourceObjects.Add(newResourceObject); newResourceVal = 0; newResourceObject = null; droneBehaviour = DroneBehaviours.Idle; } else { Debug.DrawLine(transform.position, target.transform.position, Color.green); MoveTowardsTarget(target.transform.position); } } }
// Method used by drones selected as foragers (and to an extent elite foragers) private void Forage() { // On begining journey to asteroid if (target == null) { target = motherShip; } // If the drone has not reached the asteroid yet. move towards it if (target != motherShip) { if (Vector3.Distance(transform.position, target.transform.position) > targetRadius) { MoveTowardsTarget(target.transform.position); Debug.DrawLine(transform.position, target.transform.position, Color.blue); // upon reaching the asteroid - take some of its resource as cargo } else { cargo = 10; target.GetComponent <Asteroid> ().resource -= 10; if (target.GetComponent <Asteroid> ().resource < 0) { cargo = cargo + target.GetComponent <Asteroid> ().resource; motherShip.GetComponent <Mothership> ().resourceObjects.Remove(target); } // Set the target as the mothership to return with gathered resources target = motherShip; } } else { if (Vector3.Distance(transform.position, target.transform.position) > targetRadius) { MoveTowardsTarget(target.transform.position); Debug.DrawLine(transform.position, target.transform.position, Color.green); } else { // A safety check to ensure the drones can only deposit positive values of cargo in case of errors if (cargo > 0) { motherShip.GetComponent <Mothership> ().resourcesCollected += cargo; } // reset all parameters and return to idle state cargo = 0; motherShip.GetComponent <Mothership>().drones.Add(this.gameObject); motherShip.GetComponent <Mothership>().foragers.Remove(this.gameObject); droneBehaviour = DroneBehaviours.Idle; } } }
//state for returning the resources it collected to the mothership private void ReturningResources() { //Move till you get to the mothership, then reset cargo, add it to mothership if (Vector3.Distance(transform.position, motherShip.transform.position) < targetRadius) { motherShip.GetComponent <Mothership>().collectedResources += currentLoad; currentLoad = 0; droneBehaviour = DroneBehaviours.Idle; } else { MoveTowardsTarget(motherShip.transform.position); } }
public void Scouting() { if (!newResourceObject) { if (Vector3.Distance(transform.position, scoutPosition) < detectionRadius && Time.time > scoutTimer) { Vector3 position; position.x = motherShip.transform.position.x + UnityEngine.Random.Range(-maxRange, maxRange); position.y = motherShip.transform.position.y + UnityEngine.Random.Range(-400, 400); position.z = motherShip.transform.position.z + UnityEngine.Random.Range(-maxRange, maxRange); scoutPosition = position; scoutTimer = Time.time + scoutTime; } else { MoveTowardsTarget(scoutPosition); Debug.DrawLine(transform.position, scoutPosition, Color.yellow); } if (Time.time > detectTimer) { newResourceObject = DetectNewResources(); detectTimer = Time.time + detectTime; } } else { target = motherShip; Debug.DrawLine(transform.position, target.transform.position, Color.green); if (Vector3.Distance(transform.position, target.transform.position) < targetRadius) { motherShip.GetComponent <Mothership>().drones.Add(gameObject); motherShip.GetComponent <Mothership>().scouts.Remove(gameObject); motherShip.GetComponent <Mothership>().resourceObjects.Add(newResourceObject); newResourceVal = 0; newResourceObject = null; droneBehaviour = DroneBehaviours.Idle; } } }
private void Fleeing() { fleePos = transform.position - distanceRatio * Vector3.Distance(transform.position, target.transform.position) * (transform.forward * speed); fleePos.y = fleePos.y + 10; Debug.DrawLine(transform.position, fleePos, Color.red); if (Vector3.Distance(transform.position, target.transform.position) < targetRadius) { MoveTowardsTarget(fleePos); } else { if (Vector3.Distance(transform.position, motherShip.transform.position) < targetRadius) { droneBehaviour = DroneBehaviours.Idle; } else { MoveTowardsTarget(motherShip.transform.position); } } }
// Update is called once per frame void Update() { //Acquire player if spawned in if (gameManager.gameStarted) { //Altered slightly to look for health of itself and if the mothership is dead target = gameManager.playerDreadnaught; attackOrFlee = health * Friends(); Debug.Log(attackOrFlee.ToString()); if (attackOrFlee >= 1200) { droneBehaviour = DroneBehaviours.Attacking; } else if (attackOrFlee < 1200 || health < maxHealth / 2) { droneBehaviour = DroneBehaviours.Fleeing; } else if (!motherShip) { droneBehaviour = DroneBehaviours.Attacking; } } //Move towards valid targets if (target) { MoveTowardsTarget(target.transform.position); } //Boid cohesion/segregation BoidBehaviour(); //Drone Behaviours - State Switching switch (droneBehaviour) { case DroneBehaviours.Scouting: Scouting(); break; case DroneBehaviours.Idle: Idle(); break; case DroneBehaviours.Foraging: Foraging(resourceTarget); break; case DroneBehaviours.EliteForaging: EliteForaging(resourceTarget); break; case DroneBehaviours.ReturningResources: ReturningResources(); break; case DroneBehaviours.Attacking: Attacking(); break; case DroneBehaviours.Fleeing: Fleeing(); break; } }
public void Forage() { if (elite) { Debug.DrawLine(transform.position, target.transform.position, Color.magenta); if (Vector3.Distance(transform.position, roamPos) < targetRadius && Time.time < scoutTimer && target != motherShip) { Vector3 pos = motherShip.transform.position; pos.x += UnityEngine.Random.Range(-targetRadius * 2, targetRadius * 2); pos.y += UnityEngine.Random.Range(-targetRadius * 2, targetRadius * 2); pos.z += UnityEngine.Random.Range(-targetRadius * 2, targetRadius * 2); roamPos = pos; MoveTowardsTarget(roamPos); if (!newResourceObject) { if (Time.time > detectTimer) { newResourceObject = DetectNewResources(); if (newResourceObject && newResourceObject.GetComponent <Asteroid>().resource <= currentResource) { newResourceObject = null; } detectTimer = Time.time + detectTime; } } } if (newResourceObject) { Debug.DrawLine(transform.position, target.transform.position, Color.black); if (Vector3.Distance(transform.position, target.transform.position) < targetRadius) { motherShip.GetComponent <Mothership>().drones.Add(gameObject); motherShip.GetComponent <Mothership>().scouts.Remove(gameObject); motherShip.GetComponent <Mothership>().resourceObjects.Add(newResourceObject); newResourceVal = 0; newResourceObject = null; droneBehaviour = DroneBehaviours.Idle; } } } else { Debug.DrawLine(transform.position, target.transform.position, Color.cyan); } if (Vector3.Distance(target.transform.position, transform.position) < targetRadius) { scoutTimer = Time.deltaTime + scoutTime; Asteroid a = forageTarget.GetComponent <Asteroid>(); float previous = a.resource; if (carrying + forageRate * Time.deltaTime < capacity) { a.DrainResource(forageRate * Time.deltaTime); } else { a.DrainResource(capacity - carrying); } carrying += previous - a.resource; if (a.resource <= 0 || (elite && newResourceObject)) { if (Vector3.Distance(transform.position, motherShip.transform.position) > targetRadius) { if (target != motherShip) { target = motherShip; } } else { motherShip.GetComponent <Mothership>().resourceObjects.Remove(forageTarget); motherShip.GetComponent <Mothership>().harvested += carrying; carrying = 0; droneBehaviour = DroneBehaviours.Idle; if (elite) { motherShip.GetComponent <Mothership>().eliteForagers.Remove(gameObject); } else { motherShip.GetComponent <Mothership>().foragers.Remove(gameObject); } motherShip.GetComponent <Mothership>().drones.Add(gameObject); } } else if (carrying >= capacity) { if (Vector3.Distance(transform.position, motherShip.transform.position) > targetRadius) { target = motherShip; } else { motherShip.GetComponent <Mothership>().harvested += carrying; carrying = 0; target = forageTarget; } } } }