private IEnumerator FindMatchesAndCollapse(GameObject hitGo2) { bool matchPerformed = false; shapes.Swap(hitGo, hitGo2); // move the swapped ones hitGo.transform.DOMove(hitGo2.transform.position, Constants.SwapAnimationDuration); hitGo2.transform.DOMove(hitGo.transform.position, Constants.SwapAnimationDuration); yield return(new WaitForSeconds(Constants.SwapAnimationDuration)); BonusType hitGoBonus = hitGo.GetComponent <Shape>().Bonus; BonusType hitGo2Bonus = hitGo2.GetComponent <Shape>().Bonus; // check if one of the two objects was combined with an ultimate if ((hitGo2Bonus == BonusType.Ultimate) && (hitGoBonus != BonusType.Ultimate) && (hitGoBonus != BonusType.None)) { DuplicateCandy(hitGo); } if ((hitGoBonus == BonusType.Ultimate) && (hitGo2Bonus != BonusType.Ultimate) && (hitGo2Bonus != BonusType.None)) { DuplicateCandy(hitGo2); } List <MatchesInfo> matchesInfos = new List <MatchesInfo>(); // get the matches via the helper methods matchesInfos.Add(shapes.GetMatches(hitGo, hitGo2)); matchesInfos.Add(shapes.GetMatches(hitGo2, hitGo)); var totalMatches = matchesInfos[0].MatchedCandy.Union(matchesInfos[1].MatchedCandy).Distinct(); // if user's swap didn't create at least a 3-match, undo their swap if (totalMatches.Count() < Constants.MinimumMatches) { hitGo.transform.DOMove(hitGo2.transform.position, Constants.SwapAnimationDuration); hitGo2.transform.DOMove(hitGo.transform.position, Constants.SwapAnimationDuration); yield return(new WaitForSeconds(Constants.SwapAnimationDuration)); shapes.UndoSwap(); } else { // user performed a match, no need to show the hints anymore matchPerformed = true; StopCheckForPotentialMatches(); } // decide if a bonus shall be added to one of the 2 user matches foreach (var item in matchesInfos) { if (item.Matches >= Constants.MinimumMatchesForBonus) { item.CreateBonus = true; } } int timesRun = 0; while (totalMatches.Count() >= Constants.MinimumMatches) { // boolean array to not create score for the same match more than onces bool[,] matchScoreCounted = new bool[Constants.Rows, Constants.Columns]; for (int i = 0; i < Constants.Rows; i++) { for (int j = 0; j < Constants.Columns; j++) { matchScoreCounted[i, j] = false; } } // increase score foreach (var item in matchesInfos) { if (item.DestroyedByBonus == true) { bool countScore = true; foreach (var go in item.MatchedCandy) { if (matchScoreCounted[go.GetComponent <Shape>().Row, go.GetComponent <Shape>().Column] == true) { countScore = false; } } if (countScore == true) { foreach (var go in item.MatchedCandy) { matchScoreCounted[go.GetComponent <Shape>().Row, go.GetComponent <Shape>().Column] = true; Vector3 position = Camera.main.WorldToScreenPoint(go.transform.position); IncreaseScoreAndCreatePopUp(Constants.BonusMatchScore, position); } } } else if (item.Matches == 3) { CheckForScoreAndIncrease(item, ref matchScoreCounted, Constants.Match3Score, timesRun); } else if (item.Matches == 4) { CheckForScoreAndIncrease(item, ref matchScoreCounted, Constants.Match4Score, timesRun); } else if (item.Matches >= 5) { CheckForScoreAndIncrease(item, ref matchScoreCounted, Constants.Match5Score, timesRun); } } soundManager.PlayCrinkle(); foreach (var item in totalMatches) { shapes.Remove(item); RemoveFromScene(item); } // check if there are any bonus objects to create foreach (var item in matchesInfos) { if (item.CreateBonus == true) { CreateBonus(item.OriginGameObject, item); item.CreateBonus = false; } } // get the columns that we had a collapse var columns = totalMatches.Select(go => go.GetComponent <Shape>().Column).Distinct(); // the order the 2 methods below get called is important! // collapse the ones gone var collapsedCandyInfo = shapes.Collapse(columns); // create new ones var newCandyInfo = CreateNewCandyInSpecificColumns(columns); // wait until explosion animation has finished yield return(new WaitForSeconds(Constants.ExplosionDuration)); yield return(new WaitForSeconds(Constants.DelayAfterExplosion)); MoveAndAnimate(newCandyInfo.AlteredCandy); MoveAndAnimate(collapsedCandyInfo.AlteredCandy); // will wait for both of the above animations yield return(new WaitForSeconds(Constants.MoveAnimationMinDuration)); // search if there are matches with the collapsed objects and then new objects matchesInfos = new List <MatchesInfo>(); matchesInfos.AddRange(shapes.GetMatchesInfos(collapsedCandyInfo.AlteredCandy)); matchesInfos.AddRange(shapes.GetMatchesInfos(newCandyInfo.AlteredCandy)); // boolean array to not create boni for the same match more than onces bool[,] bonusCreated = new bool[Constants.Rows, Constants.Columns]; for (int i = 0; i < Constants.Rows; i++) { for (int j = 0; j < Constants.Columns; j++) { bonusCreated[i, j] = false; } } // loop throw all found matches List <GameObject> matches = new List <GameObject>(); foreach (var item in matchesInfos) { // check if bonus should be created if (item.Matches >= Constants.MinimumMatchesForBonus) { bool bonus = true; foreach (var go in item.MatchedCandy) { if (bonusCreated[go.GetComponent <Shape>().Row, go.GetComponent <Shape>().Column] == true) { bonus = false; } } if (bonus == true) { item.CreateBonus = true; foreach (var go in item.MatchedCandy) { bonusCreated[go.GetComponent <Shape>().Row, go.GetComponent <Shape>().Column] = true; } } } // save each object to save it then to totalMatches matches.AddRange(item.MatchedCandy); } totalMatches = matches; timesRun++; } state = GameState.None; if (matchPerformed == true) { StartCheckForPotentialMatches(); } }