333 lines
12 KiB
C#
333 lines
12 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Text;
|
||
using UnityEngine;
|
||
using PrizeSystem;
|
||
public class CharacterController : MonoBehaviour
|
||
{
|
||
|
||
#region PRIVATE_FIELDS
|
||
[SerializeField] private Transform charactersContainer;
|
||
[SerializeField] private Transform charactersPool;
|
||
|
||
[SerializeField] private List<GameObject> characterPrefabs;
|
||
public Character[] characters;
|
||
|
||
[SerializeField] private Vector2 hiddenLocalPosition;
|
||
[SerializeField] private Vector2 shownLocalPosition;
|
||
|
||
private bool charactersActivated = false;
|
||
private int currentIndex = 0;
|
||
|
||
[SerializeField] private float speed;
|
||
public static CharacterController I;
|
||
|
||
#endregion
|
||
|
||
|
||
public static int CharactersAmount => I.characters.Length;
|
||
public static Sprite CurrentChipImage => CurrentCharacter.chipImage;
|
||
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;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
//================================= start: PUBLIC API =================================//
|
||
|
||
public void SetAllCharactersPrizeAvailable(bool value)
|
||
{
|
||
foreach (Character character in I.characters)
|
||
{
|
||
character.HasPrize = value;
|
||
}
|
||
}
|
||
|
||
public static void ResetCharactersDifficulty()
|
||
{
|
||
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 void ShowCharacter()
|
||
{
|
||
I.StopAllCoroutines();
|
||
I.StartCoroutine(I.MoveLocal(I.charactersContainer, I.shownLocalPosition, I.speed));
|
||
}
|
||
//================================= end : PUBLIC API =================================//
|
||
private void Awake() => I = this;
|
||
private void Start() => SetupCharacters();
|
||
|
||
private void SetupCharacters()
|
||
{
|
||
//обрабатвыаем некорректные вводные
|
||
if (GameManager.instance.botsAmount <= 0)
|
||
throw new System.Exception("Некорректное количество ботов в менеджере");
|
||
if (characterPrefabs.Count <= 0)
|
||
throw new System.Exception("Не заданы боты в контроллере");
|
||
|
||
|
||
int botsToSpawn = Mathf.Min(GameManager.instance.botsAmount, characterPrefabs.Count);
|
||
GameManager.instance.botsAmount = botsToSpawn;
|
||
|
||
|
||
//characters = new Character[GameManager.instance.botsAmount];
|
||
characters = new Character[botsToSpawn];
|
||
for (int i = 0; i < characters.Length; i++)
|
||
{
|
||
var go = Instantiate(characterPrefabs[i], charactersPool);
|
||
go.transform.localPosition = hiddenLocalPosition;
|
||
|
||
var ch = go.GetComponent<Character>();
|
||
ch.Animator.SetTrigger("PreAppear");
|
||
characters[i] = ch;
|
||
}
|
||
|
||
ClearContainer();
|
||
RefreshPrizes();
|
||
}
|
||
|
||
public void RefreshPrizes()
|
||
{
|
||
List<Prize> 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();
|
||
}
|
||
|
||
|
||
void printPresetsInfo()
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
foreach (Character character in characters)
|
||
{
|
||
sb.Append(character.name + "\n");
|
||
List<List<DifficultyPreset>> lists = new List<List<DifficultyPreset>>();
|
||
lists.Add(character.difficultyPresetsEasy);
|
||
lists.Add(character.difficultyPresetsMedium);
|
||
lists.Add(character.difficultyPresetsHard);
|
||
for (int i = 0; i < 3; i++)
|
||
{
|
||
List<DifficultyPreset> list = lists[i];
|
||
if (i == 0) sb.Append("Легкий\n");
|
||
if (i == 1) sb.Append("Средний\n");
|
||
if (i == 2) sb.Append("Сложный\n");
|
||
int presetindex = 0;
|
||
foreach (DifficultyPreset preset in list)
|
||
{
|
||
sb.Append(presetindex.ToString() + "\n");
|
||
|
||
sb.Append("Описание: " + preset.Description + "\n");
|
||
sb.Append("Глубина поиска: " + preset.Depth + "\n");
|
||
sb.Append("Бонус победы: " + preset.WinBonus + "\n");
|
||
sb.Append("Бонус 2 в ряд: " + preset.RowOfTwoBonus + "\n");
|
||
sb.Append("Бонус 3 в ряд: " + preset.RowOfThree + "\n");
|
||
sb.Append("Бонус центр: " + preset.CenterBonus + "\n");
|
||
sb.Append("Бонус блок: " + preset.BlockBonus + "\n");
|
||
sb.Append("Случайный ход: " + preset.RandomMoveRate + "\n");
|
||
sb.Append("Ошибочный ход: " + preset.MistakeRate + "\n");
|
||
sb.Append("Температура: " + preset.Temperature + "\n");
|
||
sb.Append("Сигма-шум: " + preset.ScoreNoiseSigma + "\n");
|
||
sb.Append("Количество вариантов для выбора по софтмаксу: " + preset.TopK + "\n");
|
||
|
||
sb.Append("\n\n");
|
||
presetindex++;
|
||
}
|
||
}
|
||
Debug.Log(sb.ToString());
|
||
sb.Clear();
|
||
}
|
||
|
||
}
|
||
|
||
public static void ExportCharactersReplicas()
|
||
{
|
||
StringBuilder sb = new StringBuilder();
|
||
|
||
foreach (Character character in I.characters)
|
||
{
|
||
// Заголовок с именем персонажа
|
||
sb.AppendLine($"=={character.name}==");
|
||
|
||
// Появление
|
||
sb.AppendLine("Появление");
|
||
for (int i = 0; i < character.appearReplicas.Count; i++)
|
||
{
|
||
sb.AppendLine($"{i + 1}. {character.appearReplicas[i].text}");
|
||
}
|
||
sb.AppendLine();
|
||
|
||
// Ход игрока
|
||
sb.AppendLine("Ход игрока");
|
||
for (int i = 0; i < character.playerTurnReplicas.Count; i++)
|
||
{
|
||
sb.AppendLine($"{i + 1}. {character.playerTurnReplicas[i].text}");
|
||
}
|
||
sb.AppendLine();
|
||
|
||
// Ход бота
|
||
sb.AppendLine("Ход бота");
|
||
for (int i = 0; i < character.botTurnReplicas.Count; i++)
|
||
{
|
||
sb.AppendLine($"{i + 1}. {character.botTurnReplicas[i].text}");
|
||
}
|
||
sb.AppendLine();
|
||
|
||
// Игрок выиграл
|
||
sb.AppendLine("Игрок выиграл");
|
||
for (int i = 0; i < character.playerWinReplicas.Count; i++)
|
||
{
|
||
sb.AppendLine($"{i + 1}. {character.playerWinReplicas[i].text}");
|
||
}
|
||
sb.AppendLine();
|
||
|
||
// Бот выиграл
|
||
sb.AppendLine("Бот выиграл");
|
||
for (int i = 0; i < character.botWinReplicas.Count; i++)
|
||
{
|
||
sb.AppendLine($"{i + 1}. {character.botWinReplicas[i].text}");
|
||
}
|
||
sb.AppendLine();
|
||
|
||
// Вернулись на предыдущий уровень
|
||
sb.AppendLine("Вернулись на предыдущий уровень");
|
||
for (int i = 0; i < character.returnReplicas.Count; i++)
|
||
{
|
||
sb.AppendLine($"{i + 1}. {character.returnReplicas[i].text}");
|
||
}
|
||
sb.AppendLine();
|
||
|
||
// Ничья
|
||
sb.AppendLine("Ничья");
|
||
for (int i = 0; i < character.drawReplicas.Count; i++)
|
||
{
|
||
sb.AppendLine($"{i + 1}. {character.drawReplicas[i].text}");
|
||
}
|
||
|
||
sb.AppendLine();
|
||
sb.AppendLine();
|
||
}
|
||
|
||
// Сохранение в файл
|
||
string filePath = Application.dataPath + "/CharactersReplicas.txt";
|
||
System.IO.File.WriteAllText(filePath, sb.ToString());
|
||
Debug.Log($"Реплики персонажей экспортированы в: {filePath}");
|
||
}
|
||
|
||
}
|