using System.Collections; using System.Collections.Generic; using UnityEngine; using PrizeSystem; using System; public class CharactersController : MonoBehaviour { public static CharactersController I; [SerializeField] private Transform charactersContainer; [SerializeField] private Transform charactersPool; [SerializeField] private List characterPrefabs; [SerializeField] private Vector2 hiddenLocalPosition; [SerializeField] private Vector2 shownLocalPosition; [SerializeField] private float speed; private Character[] characters; private bool charactersActivated = false; private int currentIndex = 0; public static int CharactersAmount => I.characters.Length; public static Character CurrentCharacter => I.characters[I.currentIndex]; public static Character NextCharacter { get { if (I.currentIndex + 1 < I.characters.Length) { return I.characters[I.currentIndex + 1]; } else return null; } } public void Initialize() { I = this; SetupCharacters(); GameManager.OnGameStarted += Enable; GameManager.OnGameFinished += Disable; } public void Enable(GameMode gameMode) { if(gameMode == GameMode.pve) print("ВКЛЮЧЕНИЕ СИСТЕМЫ ПЕРСОНАЖЕЙ"); } public void Disable(GameMode gameMode) { if (gameMode == GameMode.pve) print("ВЫКЛЮЧЕНИЕ СИСТЕМЫ ПЕРСОНАЖЕЙ"); } public void SetAllCharactersPrizeAvailable(bool value) { foreach (Character character in I.characters) character.HasPrize = value; } public static void ResetAllCharactersDifficulty() { foreach (Character ch in I.characters) ch.currentDifficulty = ch.CurrenDifficultyList.Count / 2; //берем средню сложность изначально } public static void HideCharacter() { CurrentCharacter?.UnbindEvents(); I.StopAllCoroutines(); I.StartCoroutine(I.MoveLocal(I.charactersContainer, I.hiddenLocalPosition, I.speed)); } public static void SwitchToCharacter(int index) { I.StopAllCoroutines(); I.StartCoroutine(I.TransitionToCharacter(index)); } public static void ResetState() { I.StopAllCoroutines(); I.charactersContainer.transform.localPosition = I.hiddenLocalPosition; I.ClearContainer(); I.charactersActivated = false; I.currentIndex = 0; } public static Character[] GetCharactersArray() => new List(I.characters).ToArray(); private void SetupCharacters() { if (characterPrefabs.Count <= 0) throw new System.Exception("Не заданы боты в контроллере"); int amount = characterPrefabs.Count; characters = new Character[amount]; for (int i = 0; i < amount; i++) { var character = Instantiate(characterPrefabs[i], charactersPool); characters[i] = character; character.transform.localPosition = hiddenLocalPosition; character.Animator.SetTrigger("PreAppear"); } ClearContainer(); RefreshPrizes(); } public void RefreshPrizes() { List prizes = PrizeSerializer.LoadPrizes(); for (int i = 0; i < characters.Length; i++) characters[i].prize = prizes[i]; } private void ClearContainer() { for (int i = charactersContainer.childCount - 1; i >= 0; i--) { var child = charactersContainer.transform.GetChild(i); child.SetParent(charactersPool); } } private void SetCharacter(int index) { ClearContainer(); if (index < 0 || index >= CharactersAmount) index = 0; var newCharacter = characters[index]; //сажаем нового в контейнер newCharacter.transform.SetParent(charactersContainer); newCharacter.transform.localPosition = newCharacter.CharacterLocalPosition; newCharacter.Animator.SetTrigger("PreAppear"); //animator.ResetTrigger("Throw"); newCharacter.BindEvents(); } private IEnumerator MoveLocal(Transform t, Vector3 targetLocalPos, float speed) { while (t.localPosition != targetLocalPos) { t.localPosition = Vector3.MoveTowards(t.localPosition, targetLocalPos, speed * Time.deltaTime); yield return null; } } private IEnumerator TransitionToCharacter(int newIndex) { int oldIndex = currentIndex; currentIndex = newIndex; LightUtility.Character(characters[newIndex]); //Отсекаем попытку переключиться на того же персонажа if (newIndex == oldIndex && charactersActivated) yield break; // тостер отсекается. надо решать charactersActivated = true; //чтобы тостер тоже приходил иначе старт 0, запрашиваем 0 персонажа -> тостер отсекся //сразу отвязываем реплики старого персонажа characters[oldIndex]?.UnbindEvents(); Transform container = charactersContainer; //Уводим контейнер за экран yield return MoveLocal(charactersContainer, hiddenLocalPosition, speed); characters[oldIndex].Animator.SetTrigger("PreAppear"); //Сажаем нового персонажа SetCharacter(newIndex); yield return new WaitForSeconds(0.1f); //Выводим на экран yield return MoveLocal(charactersContainer, shownLocalPosition, speed); //дергаем появление CharacterEventBus.Instance.OnCharacterAppeared?.Invoke(); //понижение уровня if (newIndex < oldIndex) CharacterEventBus.Instance.OnLevelDown?.Invoke(); } }