public void StopFollowing() { followerWait = true; leaderWaits = false; estimateNewLeaderPos = Vector3.zero; leader = null; }
private void OnTriggerEnter(Collider other) { // We are only interested in interactions between ants if (other.tag != Naming.Ants.Tag) { return; } otherAnt = other.gameObject.GetComponent <AntManager>(); // Recruitment cannot take place if either ant is already part of a tandem run or social carry if (ant.IsTandemRunning() || ant.IsTransporting() || otherAnt.IsTandemRunning() || otherAnt.IsTransporting()) { return; } // This script is from the perspective of the recruiter, so only recruiting or reversing ants continue if (ant.state == BehaviourState.Reversing) { ReversingSenses(); } else if (ant.state == BehaviourState.Recruiting) { RecruiterSenses(); } }
// Calculate the current quorum total within this nest (the total number of ants within the nest) public int GetQuorum() { int id = simulation.GetNestID(this); int total = GameObject.Find("P" + id).transform.childCount; Transform a = GameObject.Find("A" + id).transform; for (int i = 0; i < a.childCount; i++) { AntManager assessor = a.GetChild(i).GetComponent <AntManager>(); // If the assessor is currently in this nest count them towards the total if (assessor.currentNest == this) { total += 1; } } Transform r = GameObject.Find("R" + id).transform; for (int i = 0; i < r.childCount; i++) { AntManager recruiter = r.GetChild(i).GetComponent <AntManager>(); // If the recruiter is currently waiting in this nest count them towards the total if (recruiter.currentNest == this) { total += 1; } } // The ant doesn't count itself towards the total return(total - 1); }
//follow the leader ant public void Follow(AntManager leader) { //start following leader towards nest ChangeState(BehaviourState.Following); this.leader = leader; followerWait = true; }
public void InflictDamage(float damage) { health -= damage; if (health <= 0) { antGameObject.SetActive(false); AntManager.RemoveAnt(); } }
private Vector3 lastContactPosition; // The last position where the leader and follower were in contact // Initialisation of parameters void Start() { //Time.timeScale = 10f; ant = transform.GetComponent <AntManager>(); TurnAnt(RandomGenerator.Instance.Range(0, 360)); nextTurnTime = simulation.TotalElapsedSimulatedTime("s") + maxTimeBetweenTurns; lastTurn = transform.position; }
/// <summary> /// Invoke async /// </summary> /// <param name="context"></param> /// <param name="accessor"></param> /// <returns></returns> public async Task InvokeAsync(HttpContext context, IRequestedLanguageTagAccessor accessor) { //Set current LanguageTag in LanguageTagCoreManager. //If the value is null, empty or whitespace, will be used 'DefaultLocaleStr' - 'en_US'. var languageTag = AntManager.Get(context, accessor); LanguageTagCoreManager.UpdateTag(languageTag); await _next(context); }
// //switches ants allegiance to this nest and sends them back to their old one to recruit some more private void RecruitToNest(NestManager nest) { recruitmentStage = RecruitmentStage.GoingToOldNest; myNest = nest; CheckQuorum(nest); waitOldNestTime = (int)Times.v[Times.RecruitTryTime]; leader = null; //? BUGFIX == random case where an assessor -> recruiter but still had leader set to something, so caused a null exception ChangeState(BehaviourState.Recruiting); }
void OnTriggerExit(Collider other) { //if other isn't an ant or an ants collider has intersected with nest collider in an area that isn't the entrance then ignore if (other.tag != Naming.Ants.Tag /*//?|| (door != null && Vector3.Distance(other.transform.position, door.transform.position) > AntScales.Distances.DoorEntry)*/) { return; } AntManager ant = other.transform.GetComponent <AntManager>(); //if ant is passive and somehow reaches edge of nest then turn around, otherwise let the ant know it has left the nest ant.LeftNest(); }
void OnTriggerEnter(Collider other) { //if other isn't an ant or an ants collider has intersected with nest collider in an area that isn't the entrance then ignore if (other.tag != Naming.Ants.Tag /*|| (door != null && Vector3.Distance(other.transform.position, door.transform.position) > AntScales.Distances.DoorEntry)*/) { return; } //let the ant know it has entered the nest AntManager ant = other.transform.GetComponent <AntManager>(); ant.EnteredNest(this); }
private bool StateChanged(AntManager ant) { if (!_stateHistory.ContainsKey(ant.AntId)) { _stateHistory.Add(ant.AntId, ant.state); return(true); } if (_stateHistory[ant.AntId] != ant.state) { _stateHistory[ant.AntId] = ant.state; return(true); } return(false); }
public void ReverseLead(AntManager follower) { // Reset the leader giving up time leaderGiveUpTime = 2; // 2 is roughly the lowest LGUT possible (LGUT when tandem duration is 0s cannot be calculated since Log(0) = -inf // Set the tandem variables (for recording tandem run data) tandemStartTime = simulation.TotalElapsedSimulatedTime("s"); tandemDistance = 0f; forwardRun = false; // Reverse run prevLeaderPosition = transform.position; //let following ant know that you're leading it this.follower = follower; this.follower.Follow(this); recruitmentStage = RecruitmentStage.GoingToOldNest; }
private void Awake() { if (main == null) { main = this; } else { Destroy(this); } antList = new List <Ant>(); queenAnts = new List <Ant>(); soliderAnts = new List <Ant>(); gardenerAnts = new List <Ant>(); excavatorAnts = new List <Ant>(); trashHandlerAnts = new List <Ant>(); foragerAnts = new List <Ant>(); }
//returns true if there is a line of sight between this ant and the given other ant public bool LineOfSight(AntManager otherAnt) { float distance = 2f; //? These were unchanged so I divided both by 10 if (leader != null) { distance = 2f; } //? was 0.45f before RaycastHit hit; if (Physics.Raycast(transform.position, otherAnt.transform.position - transform.position, out hit, distance)) { // The collider hit will be the mesh, and the mesh parent is the ant object if (hit.collider.transform.parent == otherAnt.transform) { return(true); } } return(false); }
//follow the leader ant public void Follow(AntManager leader) { //start following leader towards nest ChangeState(State.Following); this.newToOld = false; this.leader = leader; //we want to turn to follow the leader now move.ChangeDirection(); }
private void SpawnColony(Transform ants) { var antPrefab = Resources.Load(Naming.Resources.AntPrefab) as GameObject; Transform passive = MakeObject("P0", ants).transform; NestInfo.Add(new NestInfo(initialNest.NestManager(), 0, true, MakeObject(Naming.Ants.BehavourState.Assessing + "0", ants), MakeObject(Naming.Ants.BehavourState.Recruiting + "0", ants), passive.gameObject, MakeObject(Naming.Ants.BehavourState.Reversing + "0", ants) )); // Local variables for ant setup //find size of square to spawn ants into float sqrt = Mathf.Ceil(Mathf.Sqrt(Settings.ColonySize.Value)); //? int spawnedAnts = 0; int spawnedAntScouts = 0; //just spawns ants in square around wherever this is placed while (spawnedAnts < Settings.ColonySize.Value) { int column = 0; while ((column == 0 || spawnedAnts % sqrt != 0) && spawnedAnts < Settings.ColonySize.Value) { float row = Mathf.Floor(spawnedAnts / sqrt); Vector3 pos = initialNest.transform.position; //? pos.x -= 1; pos.z -= 1; GameObject newAnt = Instantiate(antPrefab, pos + (new Vector3(row, 0, column) * Length.v[Length.Spawning]), Quaternion.identity); newAnt.transform.position += new Vector3(0, newAnt.GetComponent <CapsuleCollider>().radius * 2, 0); newAnt.name = CreateAntId(Settings.ColonySize.Value, spawnedAnts); newAnt.AntMovement().simulation = this; AntManager newAM = newAnt.AntManager(); Ants.Add(newAM); newAM.AntId = spawnedAnts; newAM.myNest = initialNest.NestManager(); // why is there 2 of this here? is it meant to be old nest or something // newAM.myNest = initialNest; newAM.simulation = this; newAM.inNest = true; newAM.quorumThreshold = Settings.QuorumThreshold.Value; newAnt.transform.parent = passive; if (spawnedAnts < Settings.ColonySize.Value * Settings.ProportionActive.Value || Settings.ColonySize.Value <= 1 || _spawnOnlyScouts) { newAM.state = BehaviourState.Inactive; newAM.passive = false; newAnt.GetComponentInChildren <Renderer>().material.color = AntColours.States.Inactive; Transform senses = newAnt.transform.Find(Naming.Ants.SensesArea); (senses.GetComponent <SphereCollider>()).enabled = true; (senses.GetComponent <SphereCollider>()).radius = Length.v[Length.SensesCollider]; (senses.GetComponent <AntSenses>()).enabled = true; if (spawnedAntScouts < InitialScouts || Settings.ColonySize.Value <= 1 || _spawnOnlyScouts) { newAM.nextAssessment = TotalElapsedSimulatedTime("s") + RandomGenerator.Instance.Range(0.5f, 1f) * Times.v[Times.MaxAssessmentWait]; spawnedAntScouts++; } else { newAM.nextAssessment = 0; } } else { // Passive ant newAM.passive = true; newAnt.GetComponentInChildren <Renderer>().material.color = AntColours.States.InactivePassive; } column++; spawnedAnts++; } } }
void Start() { ant = transform.parent.GetComponent <AntManager>(); }
// Update is called once per frame void Update() { // Loop through all players for (int i = 0; i < players.Count; i++) { Player player = players[i]; if (player.SelectedNest == null) { player.SelectNest(NestManager.Nests[i]); } // Cycle selected nest if (Input.GetKeyDown(player.CycleSelectedNestKey)) { // Change selected nest Nest newSelectedNest = player.SelectedNest; var allNests = NestManager.Nests; bool foundCurrentSelectedNestIndex = false; bool foundNewSelectedNest = false; for (int nestIndex = 0; !foundNewSelectedNest; nestIndex = (nestIndex + 1) % allNests.Count) { Nest currentNest = allNests[nestIndex]; if (foundCurrentSelectedNestIndex && currentNest.Player == player) { newSelectedNest = currentNest; foundNewSelectedNest = true; } if (currentNest == player.SelectedNest) { foundCurrentSelectedNestIndex = true; } } // Change appearance of selected nest player.SelectedNest.changeToDeselected(); newSelectedNest.changeToSelected(); player.SelectNest(newSelectedNest); } // Build nest int newNestCost = Nest.foodCost; if (Input.GetKeyDown(player.BuildNestKey) && player.FoodAcquired >= Nest.foodCost) { player.IncrementFoodAcquired(-newNestCost); AntManager.BuildNest(player); } // Spawn worker ants int workerAntCost = WorkerAnt.FoodCost; if (Input.GetKeyDown(player.SpawnWorkerAntKey) && player.FoodAcquired >= workerAntCost) { player.IncrementFoodAcquired(-workerAntCost); AntManager.SpawnWorkerAnt(player); } // Spawn warrior ants int warriorAntCost = WarriorAnt.FoodCost; if (Input.GetKeyDown(player.SpawnWarriorAntKey) && player.FoodAcquired >= warriorAntCost) { player.IncrementFoodAcquired(-warriorAntCost); AntManager.SpawnWarriorAnt(player); } } }
// Since distance is calculated from the centre of each ant, separation is the distance - half the body length of both ants (so - 1x bodylength) private float AntSeparation(AntManager other) { return(Vector3.Distance(transform.position, other.transform.position) - Length.v[Length.BodyLength]); }
public void StopFollowing() { this.leader = null; }
//makes this ant pick up 'otherAnt' and carry them back to preffered nest public void PickUp(AntManager otherAnt) { otherAnt.PickedUp(transform); recruitmentStage = RecruitmentStage.GoingToNewNest; }
// Use this for initialization void Start() { this.simManager = (SimulationManager)GameObject.Find("OldNest").GetComponent("SimulationManager"); this.ant = (AntManager) transform.GetComponent("AntManager"); this.cont = (CharacterController)transform.GetComponent("CharacterController"); this.lastTurn = transform.position; this.dir = Random.Range(0, 360); this.nextDirChange_time = Time.timeSinceLevelLoad + maxDirChange_time; this.rg = new RandomGenerator(); this.pheromoneParent = GameObject.Find("Pheromones").transform; this.nextPheromoneCheck = Time.timeSinceLevelLoad; //passive ants laying in centre of nests makes ants gravitate towards nest centers to much if(!this.ant.passive && this.usePheromones) InvokeRepeating("LayPheromone", 0, pheromoneFrequency); }
//tell this ant to lead 'follower' to preffered nest public void Lead(AntManager follower) { this.follower = follower; //let following ant know that you're leading it this.follower.Follow(this); this.newToOld = false; //turn this ant around to face towards chosen nest transform.LookAt(this.myNest.transform); }
//makes this ant pick up 'otherAnt' and carry them back to preffered nest public void PickUp(AntManager otherAnt) { otherAnt.PickedUp(transform); this.newToOld = false; transform.LookAt(this.myNest.transform); }
public void BindAntManager(AntManager antManager) { this.antManager = antManager; }
// Start is called before the first frame update void Start() { instance = this; }
public void Tick() { PerceivedTicks++; // Decrement Counters only if 1 second of simulated time has elapsed if (Mathf.Approximately(simulation.TotalElapsedSimulatedTime("ms") % 1000, 0)) { DecrementCounters(); } /* //? This part has been added new. Some may be useful (recruitmentStage) * if (state == BehaviourState.Recruiting && recruitmentStage == RecruitmentStage.WaitingInNewNest) * { * //CheckQuorum(myNest); //? * * // Check if ant is giving up recruiting * if (simulation.TickManager.TotalElapsedSimulatedSeconds - _recruitmentWaitStartSeconds >= AntScales.Times.RecruiterWaitSeconds) * { * recruitmentStage = RecruitmentStage.GoingToOldNest; * } * }*/ /*//? Test removing this, I changed the triggerExit code and nest wall thickness & movement code so hopefully it's fixed * //BUGFIX: sometimes assessors leave nest without triggering OnExit in NestManager * if (state == BehaviourState.Assessing && Vector3.Distance(nestToAssess.transform.position, transform.position) > * Mathf.Sqrt(Mathf.Pow(nestToAssess.transform.localScale.x, 2) + Mathf.Pow(nestToAssess.transform.localScale.z, 2))) * LeftNest();*/ //BUGFIX: occasionally when followers enter a nest there EnteredNest function doesn't get called, this forces that if (state == BehaviourState.Following && Vector3.Distance(LeadersNest().transform.position, transform.position) < LeadersNest().transform.localScale.x / 2f) { EnteredNest(LeadersNest().NestManager()); } //makes Inactive and !passive ants assess nest that they are in every so often if (!passive && state == BehaviourState.Inactive && nextAssessment > 0 && simulation.TotalElapsedSimulatedTime("s") >= nextAssessment) { AssessNest(myNest); nextAssessment = simulation.TotalElapsedSimulatedTime("s") + RandomGenerator.Instance.Range(0.5f, 1f) * Times.v[Times.MaxAssessmentWait]; } //if an ant is carrying another and is within x distance of their nest's centre then drop the ant if (carryPosition.childCount > 0 && Vector3.Distance(myNest.transform.position, transform.position) < Length.v[Length.RecruitingNestMiddle]) { AntManager carriedAnt = carryPosition.Find(Naming.Ants.Tag).GetComponent <AntManager>(); carriedAnt.Dropped(myNest); /*//? This if will always equate to true? * // drop social carry "follower" calculate total timesteps for social carry * if (socialCarrying == true) * { * carryingTimeSteps = -1 * (carryingTimeSteps - timeStep); * } * // get end position of social carry * Vector3 endPos = transform.position; * // calculate total distance and speed of social carry * float TRDistance = Vector3.Distance(endPos, startPos); //? These seem to no longer be used * float TRSpeed = TRDistance / carryingTimeSteps; * // update history with social carry and social carry speed //? This no longer happens * if (socialCarrying == true) * { * socialCarrying = false; * }*/ // If RTRs are enabled attempt to find an ant to lead, else just continue to recruit as normal if (simulation.Settings.AntsReverseTandemRun.Value) { Reverse(myNest); } else { RecruitToNest(myNest); } } //BUGFIX: Sometimes new to old is incorrectly set for recruiters - unclear why as of yet. if (state == BehaviourState.Recruiting && follower != null && currentNest == oldNest) { recruitmentStage = RecruitmentStage.GoingToNewNest; } move.Tick(); //? Moved this to the end }