/** * Set the tints for all parts of the fish * * @param genome FishGenome The genome that will determine what tints are applied */ private void SetTints(FishGenome genome) { // Temporary colors to indicate sex and size Color color1 = genome.IsMale() ? Color.blue : Color.magenta; Color color2; if (genome[FishGenome.GeneType.Size].dadGene != genome[FishGenome.GeneType.Size].momGene) { color2 = Color.yellow; } else if (genome[FishGenome.GeneType.Size].momGene == FishGenome.B) { color2 = Color.red; } else { color2 = Color.green; } rend.material.SetColor("_Color", color1); rend.material.SetColor("_Color2", color2); //rend.material.SetColor("_Color3", GetAColor()); //rend.material.SetColor("_Color4", GetAColor()); }
/** * Set the size of the fish's bones * * @param genome FishGenome The genome that will determine how the bones are sized */ private void ResizeBones(FishGenome genome) { for (int i = 0; i < bones.Length - 1; i += 1) { var a = Random.Range(0.5f, 1.5f); bones [i].localScale = new Vector3(a, a, a); } }
/** * Set the genome of the fish */ public void SetGenome(FishGenome genome) { this.genome = genome; // if the appearance script can be found, set the appearance based on the genome if (fishAppearance != null) { fishAppearance.SetAppearance(genome); } }
/** * Constructor for situations where we want to create a genome from two parent genomes * * @param momGenome FishGenePair The genome from the mother * @param dadGenome FishGenePair the genome from the father */ public FishGenome(FishGenome momGenome, FishGenome dadGenome) { for (int index = 0; index < Length; index++) { FishGenePair newPair = new FishGenePair(); newPair.momGene = Random.Range(0, 2) == 1 ? momGenome[index].momGene : momGenome[index].dadGene; newPair.dadGene = Random.Range(0, 2) == 1 ? dadGenome[index].momGene : dadGenome[index].dadGene; genePairList[index] = newPair; } }
/** * Determine which fish prefab should be used given a fish's genome * * @param genome FishGenome The genome that determines which prefab we should use */ public GameObject GetFishPrefab(FishGenome genome) { // gameobject we will return at end GameObject toReturn; // get the size gene for the fish FishGenePair sizeGenePair = genome[FishGenome.GeneType.Size]; // different prefabs for each sex if (genome.IsMale()) { // different prefabs for each male size if (sizeGenePair.momGene == FishGenome.b && sizeGenePair.dadGene == FishGenome.b) { toReturn = smallMale; } else if (sizeGenePair.momGene == FishGenome.B && sizeGenePair.dadGene == FishGenome.B) { toReturn = largeMale; } else { toReturn = mediumMale; } } else { // different prefabs for each female size if (sizeGenePair.momGene == FishGenome.b && sizeGenePair.dadGene == FishGenome.b) { toReturn = smallFemale; } else if (sizeGenePair.momGene == FishGenome.B && sizeGenePair.dadGene == FishGenome.B) { toReturn = largeFemale; } else { toReturn = mediumFemale; } } return(toReturn); }
/* * Loads the game state of the turn in the list of saves to revert the game to */ public static void LoadGame() { // The turn number from the Pause Menu UI slider that we want to revert the game to int turn = (int)GameManager.Instance.pauseMenu.turnSlider.value; // List counters for each kind of tower we are loading in int currentAngler = 0; int currentRanger = 0; int currentSealion = 0; int currentTower = 0; // Clear all the existing towers foreach (TowerBase tower in GameManager.Instance.GetTowerList()) { Destroy(tower.transform.parent.gameObject); } // Grab the save from turn - 1 as we start at turn 0, but the pause menu slider starts at 1 Save loadSave = saves[turn - 1]; // Loop through each saved tower and load them back into the scene appropriately foreach (int towerType in loadSave.towerTypes) { // NOTE: This can also be accomplished with a Swicth statement, but this seems more readable for little loss of performance // Angler if (towerType == 0) { GameObject angler = Instantiate(GameManager.Instance.GetTowerPrefabs()[0]); AnglerTower towerScript = angler.GetComponent <AnglerTower>(); angler.transform.position = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]); angler.transform.rotation = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]); towerScript.turnPlaced = loadSave.anglerPlaced[currentAngler]; towerScript.fishCaught = loadSave.caughtFish[currentAngler]; towerScript.smallCatchRate = loadSave.anglerCatchRates[currentAngler][0]; towerScript.mediumCatchRate = loadSave.anglerCatchRates[currentAngler][1]; towerScript.largeCatchRate = loadSave.anglerCatchRates[currentAngler][2]; currentTower++; currentAngler++; } // Ranger else if (towerType == 1) { GameObject ranger = Instantiate(GameManager.Instance.GetTowerPrefabs()[1]); RangerTower towerScript = ranger.GetComponent <RangerTower>(); ranger.transform.position = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]); ranger.transform.rotation = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]); towerScript.turnPlaced = loadSave.rangerPlaced[currentRanger]; towerScript.slowdownEffectSmall = loadSave.rangerRegulateRates[currentRanger][0]; towerScript.slowdownEffectMedium = loadSave.rangerRegulateRates[currentRanger][1]; towerScript.slowdownEffectLarge = loadSave.rangerRegulateRates[currentRanger][2]; currentTower++; currentRanger++; } // Sealion else if (towerType == 4) { GameObject sealion = Instantiate(GameManager.Instance.GetTowerPrefabs()[4]); SealionTower towerScript = sealion.GetComponent <SealionTower>(); sealion.transform.position = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]); sealion.transform.rotation = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]); towerScript.turnPlaced = loadSave.sealionAppeared[currentSealion]; towerScript.maleCatchRate = loadSave.sealionCatchRates[currentSealion][0]; towerScript.femaleCatchRate = loadSave.sealionCatchRates[currentSealion][1]; currentTower++; currentSealion++; } // Dam else if (towerType == 2) { GameObject dam = Instantiate(GameManager.Instance.GetTowerPrefabs()[2]); Dam towerScript = dam.GetComponent <Dam>(); dam.transform.position = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]); dam.transform.rotation = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]); towerScript.turnPlaced = loadSave.damPlaced; currentTower++; } // Ladder else if (towerType == 3) { GameObject ladder = Instantiate(GameManager.Instance.GetTowerPrefabs()[3]); DamLadder towerScript = ladder.GetComponent <DamLadder>(); ladder.transform.position = new Vector3(loadSave.towerPositions[currentTower][0], loadSave.towerPositions[currentTower][1], loadSave.towerPositions[currentTower][2]); ladder.transform.rotation = Quaternion.Euler(loadSave.towerRotations[currentTower][0], loadSave.towerRotations[currentTower][1], loadSave.towerRotations[currentTower][2]); towerScript.turnPlaced = loadSave.ladderType; currentTower++; } } // Load in the generation of fish from this turn List <FishGenome> revertGeneration = new List <FishGenome>(); /* * This is lengthy. The gist is we COULD just grab the list via GetFish in FishSchool, but then the save * would not be potentially serializable if we want that in the future. So instead, we are reconstructing the * appropriate generation based on the counts of small, medium, and large fish (both male and female) we saved * at the place stage of that turn. */ // Small Male Fish FishGenePair[] SMgenes = new FishGenePair[FishGenome.Length]; FishGenePair sexPair; sexPair.momGene = FishGenome.X; sexPair.dadGene = FishGenome.Y; FishGenePair sizePair; sizePair.momGene = FishGenome.b; sizePair.dadGene = FishGenome.b; SMgenes[(int)FishGenome.GeneType.Sex] = sexPair; SMgenes[(int)FishGenome.GeneType.Size] = sizePair; FishGenome smallMGenome = new FishGenome(SMgenes); for (int i = 0; i < loadSave.smallMale; i++) { revertGeneration.Add(smallMGenome); } // Medium Male Fish FishGenePair[] MMgenes = new FishGenePair[FishGenome.Length]; sizePair.momGene = FishGenome.b; sizePair.dadGene = FishGenome.B; MMgenes[(int)FishGenome.GeneType.Sex] = sexPair; MMgenes[(int)FishGenome.GeneType.Size] = sizePair; FishGenome mediumMGenome = new FishGenome(MMgenes); for (int i = 0; i < loadSave.mediumMale; i++) { revertGeneration.Add(mediumMGenome); } // Large Male Fish FishGenePair[] LMgenes = new FishGenePair[FishGenome.Length]; sizePair.momGene = FishGenome.B; sizePair.dadGene = FishGenome.B; LMgenes[(int)FishGenome.GeneType.Sex] = sexPair; LMgenes[(int)FishGenome.GeneType.Size] = sizePair; FishGenome largeMGenome = new FishGenome(LMgenes); for (int i = 0; i < loadSave.largeMale; i++) { revertGeneration.Add(largeMGenome); } // Small Female Fish FishGenePair[] SFgenes = new FishGenePair[FishGenome.Length]; sexPair.dadGene = FishGenome.X; SFgenes[(int)FishGenome.GeneType.Sex] = sexPair; sizePair.momGene = FishGenome.b; sizePair.dadGene = FishGenome.b; SFgenes[(int)FishGenome.GeneType.Size] = sizePair; FishGenome smallFGenome = new FishGenome(SFgenes); for (int i = 0; i < loadSave.smallFemale; i++) { revertGeneration.Add(smallFGenome); } // Medium Female Fish FishGenePair[] MFgenes = new FishGenePair[FishGenome.Length]; sizePair.momGene = FishGenome.B; sizePair.dadGene = FishGenome.b; MFgenes[(int)FishGenome.GeneType.Sex] = sexPair; MFgenes[(int)FishGenome.GeneType.Size] = sizePair; FishGenome mediumFGenome = new FishGenome(MFgenes); for (int i = 0; i < loadSave.mediumFemale; i++) { revertGeneration.Add(mediumFGenome); } // Large Female Fish FishGenePair[] LFgenes = new FishGenePair[FishGenome.Length]; sizePair.momGene = FishGenome.B; sizePair.dadGene = FishGenome.B; LFgenes[(int)FishGenome.GeneType.Sex] = sexPair; LFgenes[(int)FishGenome.GeneType.Size] = sizePair; FishGenome largeFGenome = new FishGenome(LFgenes); for (int i = 0; i < loadSave.largeFemale; i++) { revertGeneration.Add(largeFGenome); } FishGenomeUtilities.Shuffle(revertGeneration); GameManager.Instance.school.nextGenerationGenomes = revertGeneration; // Remove future turns we reverted over and set the UI slider in the pause menu appropriately GameManager.Instance.pauseMenu.turnSlider.maxValue = turn; GameManager.Instance.pauseMenu.turnSlider.value = turn; GameManager.Instance.Turn = turn; GameManager.Instance.SetState(new PlaceState()); currentSaveIndex = turn; }
/** * Set the apperanace of the fish * * @param genome FishGenome The genome that will determine appearance */ public void SetAppearance(FishGenome genome) { SetTints(genome); // ResizeBones(genome); // setBlendWeights(genome); }
/** * Set the fish's blend shape weights * * @param genome FishGenome The genome that will determine how the blend shape weights are set */ private void setBlendWeights(FishGenome genome) { blendRenderer.SetBlendShapeWeight(0, Random.Range(0f, 100f)); }
/** * Create a new, random generation of fish for the initial group of salmon * * @param generationSize int The number of fish that should be in this generation * @param lockSexRatio bool True if we want to lock to half males, half females (or as close as is possible), false if we want random * @param lockSizeRatio bool True if we want to lock to set ratios of sizes, false if we want random */ public static List <FishGenome> MakeNewGeneration(int generationSize, bool lockSexRatio, bool lockSizeRatio) { // create a list to hold the new genomes List <FishGenome> newGeneration = new List <FishGenome>(); for (int i = 0; i < generationSize; i++) { FishGenePair[] genes = new FishGenePair[FishGenome.Length]; // figure out the sex gene pair FishGenePair sexPair; // the mom gene will always be an x sexPair.momGene = FishGenome.X; // how we determine the dad gene depends on whether we want equal number of males and females or if we want it to be random if (lockSexRatio) { // want to lock sex ratio, so odd fish will be one sex and even fish will be the other sexPair.dadGene = i % 2 == 0 ? FishGenome.X : FishGenome.Y; } else { // dad gene determined by pseudorandom chance sexPair.dadGene = Random.Range(0, 2) == 0 ? FishGenome.X : FishGenome.Y; } // add the sex gene to our list of genomes genes[(int)FishGenome.GeneType.Sex] = sexPair; // figure out the size gene pair FishGenePair sizePair; // how we determine the size genes is dependant on whether we want to lock to specific ratios or do random // if we're locking values, we use i % 4 to get 25% big, 50% medium, 25% small // if we aren't just do a random value int value = lockSizeRatio ? i % 4 : Random.Range(0, 4); switch (value) { case 0: default: sizePair.momGene = FishGenome.B; sizePair.dadGene = FishGenome.B; break; case 1: sizePair.momGene = FishGenome.B; sizePair.dadGene = FishGenome.b; break; case 2: sizePair.momGene = FishGenome.b; sizePair.dadGene = FishGenome.B; break; case 3: sizePair.momGene = FishGenome.b; sizePair.dadGene = FishGenome.b; break; } // add the size gene to our list of genomes genes[(int)FishGenome.GeneType.Size] = sizePair; // create a genome out of our genes and add it to the list FishGenome genome = new FishGenome(genes); newGeneration.Add(genome); } return(newGeneration); }