chip-game/Assets/Scripts/Characters/CharacterController.cs

333 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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}");
}
}