IEnumerator EatPlant(FoliageFoodSource plant) { while (!Physics.OverlapSphere(transform.position, 1f).Contains(plant.GetComponent <Collider>())) { navAgent.SetDestination(plant.transform.position); yield return(new WaitForSeconds(1f)); } while (Nutrition < maxNutrition && plant.remainingNutrition != 0) { if (plant.remainingNutrition < 0.01f) { Nutrition += plant.remainingNutrition; plant.remainingNutrition = 0; } else { Nutrition += 0.01f; plant.remainingNutrition -= 0.01f; yield return(null); } } plant.Release(); activity = CreatureActivity.Idle; yield break; }
public void Eat() { if (dietType == DietType.Carnivore) { CreatureDebug("EF: " + Sight.EdibleFood.Length + ", CFN: " + (Sight.ClosestFood == null)); } if ((Sight.EdibleFood.Length == 0 || Sight.ClosestFood == null) && (dietType == DietType.Carnivore ? (PreviousFood.Count == 0 || CreatureSight.Closest <GameObject>(this, PreviousFood.Keys.Select(f => f.gameObject).ToArray()) == null) : true)) { if (dietType == DietType.Carnivore) { CreatureDebug("can't find food (" + PreviousFood.Count + ")"); } Roam(4, 8); } else { if (dietType == DietType.Carnivore) { CreatureDebug("finding food"); } activity = CreatureActivity.Eating; if (dietType == DietType.Carnivore && PreviousFood.Count > 0) { if (dietType == DietType.Carnivore) { CreatureDebug("looking for past food (" + PreviousFood.Count + ")"); } FoodSource closestMeat = CreatureSight.Closest <FoodSource>(this, PreviousFood.Keys.Select(f => f.gameObject).ToArray()); navAgent.SetDestination(closestMeat.transform.position); closestMeat.Reserve(); StartCoroutine(EatMeat((MeatFoodSource)closestMeat)); } else { if (dietType == DietType.Carnivore) { CreatureDebug("looking for food"); } navAgent.SetDestination(Sight.ClosestFood.transform.position); Sight.ClosestFood.Reserve(); if (Sight.ClosestFood == null) { return; // in the hypothetical situation that the plant dies before the creature is able to move. } if (Sight.ClosestFood.type == FoodType.Foliage) { StartCoroutine(EatPlant((FoliageFoodSource)Sight.ClosestFood)); } else if (Sight.ClosestFood.type == FoodType.Meat) { StartCoroutine(EatMeat((MeatFoodSource)Sight.ClosestFood)); } } } }
private void Start() { DataCollector.main.BirthWrite(this); Nutrition = maxNutrition; Hydration = maxHydration; attractabilityThreshold = Mathf.Lerp(0.1f, 0.8f, genes[Genotype.Attractability]); activity = CreatureActivity.Idle; StartCoroutine(Live()); StartCoroutine(Idle()); }
public void StartMate(Creature partnerCreature) { if (partnerCreature == null) { return; } partner = partnerCreature; partnerCreature.partner = this; activity = CreatureActivity.Mating; partner.activity = CreatureActivity.Mating; navAgent.isStopped = true;; StartCoroutine(Mate()); }
public void Hydrate() { if (Sight.Water.Length == 0) { Roam(4, 8); } else { activity = CreatureActivity.Drinking; navAgent.SetDestination(Sight.ClosestWater.transform.position); StartCoroutine(Drink(Sight.ClosestWater)); } }
IEnumerator FollowCreature(Creature parent) { if (mother == null) { yield break; } while (!Physics.OverlapSphere(transform.position, 3f).Contains(mother.GetComponent <Collider>())) { navAgent.SetDestination(mother.transform.position); yield return(new WaitForSeconds(0.1f)); } activity = CreatureActivity.Idle; yield break; }
IEnumerator Drink(WaterBlock water) { while (!Physics.OverlapSphere(transform.position, 1f).Contains(water.GetComponent <Collider>())) { navAgent.SetDestination(water.transform.position); yield return(new WaitForSeconds(1f)); } while (Hydration < maxHydration) { Hydration += 0.03f; yield return(null); } activity = CreatureActivity.Idle; yield break; }
public IEnumerator Mate() { for (;;) { if (partner == null) { yield break; } if (Physics.OverlapSphere(transform.position, 1.5f).Contains(partner.GetComponent <Collider>())) { if (matingTimer.IsRunning == false) { matingTimer.Reset(); matingTimer.Start(); } else if (matingTimer.ElapsedMilliseconds > 3 * 1000) { activity = CreatureActivity.Idle; partner.activity = CreatureActivity.Idle; if (partner.gender == GenderType.Female) { partner.gestation.Reproduce(this); partner.children += partner.gestation.childCount; children += partner.gestation.childCount; } matingTimer.Reset(); matingTimer.Stop(); partner.ReproductiveUrge = 0f; partner.lastReproductionTry = Time.time; partner.lastReproduction = Time.time; ReproductiveUrge = 0f; lastReproductionTry = Time.time; lastReproduction = Time.time; yield break; } } else { matingTimer.Stop(); matingTimer.Reset(); } yield return(null); } }
IEnumerator Idle() { for (; ;) { if (transform.up.y < 0.99) { activity = CreatureActivity.Rotating; Quaternion q = Quaternion.FromToRotation(transform.up, Vector3.up) * transform.rotation; transform.rotation = Quaternion.Slerp(transform.rotation, q, quickSpeed * Mathf.Lerp(1f, 6f, ability[Genotype.Speed])); yield return(null); } else if (activity == CreatureActivity.Rotating) { activity = CreatureActivity.Idle; } if (partner != null && activity == CreatureActivity.Mating) { navAgent.SetDestination(partner.transform.position); } if (activity == CreatureActivity.Idle) { if (Hydration < maxHydration / 2) { Hydrate(); } else if (Nutrition < maxNutrition / 2) { Eat(); } else if (childGrowth <= 0.9f && mother != null && !Physics.OverlapSphere(transform.position, 4f).Contains(mother.GetComponent <Collider>())) { activity = CreatureActivity.Navigating; StartCoroutine(FollowCreature(mother)); } else if (ReproductiveUrge > 0.6 && Time.time > lastReproductionTry + Mathf.Lerp(45f, 1f, ReproductiveUrge) && childGrowth >= 1) { FindMate(); } else if (Time.time > lastRoam + Random.Range(1f, 1.3f)) { Roam(2, Mathf.FloorToInt(Mathf.Lerp(4, 12, ability[Genotype.Sight]))); } } yield return(null); } }
public void Roam(int minDistance, int maxDistance) { Vector3 roamVector; do { bool negativeX = (Random.Range(0, 2) == 1); bool negativeZ = (Random.Range(0, 2) == 1); float x = Random.Range(minDistance, maxDistance); float z = Random.Range(minDistance, maxDistance); roamVector = transform.position + new Vector3( negativeX ? -x : x, 0, negativeZ ? -z : z ); } while (Physics.OverlapCapsule(roamVector, roamVector - new Vector3(0, -1, 0), 0.1f).Where(collider => collider.GetComponent <WaterBlock>() != null).Count() > 0); activity = CreatureActivity.Roaming; navAgent.SetDestination(roamVector); }
private void Update() { if (Health < 0 && Nutrition == 0) { Die(DeathCause.Nutrition); } else if (Health < 0 && Hydration == 0) { Die(DeathCause.Hydration); } else if (Health < 0) { Die(DeathCause.Injury); } float remainingDistance = navAgent.remainingDistance; if ((remainingDistance != Mathf.Infinity && navAgent.pathStatus == NavMeshPathStatus.PathComplete && navAgent.remainingDistance == 0) && activity == CreatureActivity.Roaming) { lastRoam = Time.time; activity = CreatureActivity.Idle; } }
IEnumerator EatMeat(MeatFoodSource meat) { if (dietType == DietType.Carnivore) { CreatureDebug("starting meat"); } if (meat == null) { yield break; } chaseCoroutine = StartCoroutine(GoToObject(meat.gameObject)); chaseTimer.Reset(); chaseTimer.Start(); while (!Physics.OverlapSphere(transform.position, 1.5f).Contains(meat.GetComponent <Collider>())) { if (chaseTimer.ElapsedMilliseconds > 15000f) { chaseTimer.Stop(); chaseTimer.Reset(); yield break; } yield return(new WaitForSeconds(0.1f)); } if (meat.GetComponent <Creature>() != null) { Creature meatCreature = meat.GetComponent <Creature>(); if (dietType == DietType.Carnivore) { CreatureDebug("attacking " + meatCreature.ID + " (" + meatCreature.Health + ")"); } while (meatCreature.Health > Mathf.Lerp(0.2f, 2f, ability[Genotype.Strength]) * Mathf.Lerp(1.5f, 0.5f, meatCreature.ability[Genotype.Resistance])) { meatCreature.Health -= Mathf.Lerp(0.2f, 2f, ability[Genotype.Strength]) * Mathf.Lerp(1.5f, 0.5f, meatCreature.ability[Genotype.Resistance]); yield return(new WaitForSeconds(Mathf.Lerp(1.2f, 0.1f, ability[Genotype.Speed]))); } meat.GetComponent <Creature>().Die(DeathCause.Injury); if (dietType == DietType.Carnivore) { CreatureDebug("killed. meat time."); } } while (Nutrition < maxNutrition && meat.remainingNutrition != 0) { if (meat.remainingNutrition < 0.05f) { Nutrition += meat.remainingNutrition; meat.remainingNutrition = 0; } else { Nutrition += 0.05f; meat.remainingNutrition -= 0.05f; yield return(null); } } if (meat != null && meat.remainingNutrition != 0) { PreviousFood.Add(meat, Time.time); } activity = CreatureActivity.Idle; yield break; }