226 lines
6.2 KiB
C#
226 lines
6.2 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using TMPro;
|
|
|
|
public class EnemyCardController : MonoBehaviour
|
|
{
|
|
|
|
|
|
[Header("UI Elements")]
|
|
public Image avatarImage;
|
|
public Animator avatarAnimator;
|
|
public TMP_Text nicknameText;
|
|
public TMP_Text dialogueText;
|
|
public RectTransform dialoguePanel;
|
|
|
|
[Header("Settings")]
|
|
public float typingSpeed = 0.05f;
|
|
public float panelExpandWidth = 300f;
|
|
public float panelExpandSpeed = 5f;
|
|
public float dialogueHoldTime = 1f;
|
|
|
|
[Header("Animation names")]
|
|
public string idleAnimationName = "Idle_bot_1";
|
|
public string transitionIn = "forvard_bot";
|
|
public string transitionOut = "back_bot";
|
|
|
|
private EnemyData currentEnemy;
|
|
private int dialogueIndex = 0;
|
|
private Coroutine dialogueCoroutine;
|
|
private Vector2 dialogueOriginalPos;
|
|
private DialogueLine? pendingDialogue;
|
|
|
|
private HashSet<string> availableStates = new HashSet<string>(); // ðåàëüíî ïåðåîïðåäåë¸ííûå ñîñòîÿíèÿ
|
|
|
|
private int playerId = 1;
|
|
|
|
private void Awake()
|
|
{
|
|
if (dialoguePanel != null)
|
|
dialogueOriginalPos = dialoguePanel.anchoredPosition;
|
|
|
|
|
|
playerId = gameObject.GetComponentInParent<Player>().PlayerId;
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (pendingDialogue.HasValue)
|
|
{
|
|
StartDialogue(pendingDialogue.Value);
|
|
pendingDialogue = null;
|
|
}
|
|
}
|
|
|
|
public void SetEnemy(EnemyData enemy)
|
|
{
|
|
currentEnemy = enemy;
|
|
nicknameText.text = enemy.nickname;
|
|
dialogueIndex = 0;
|
|
|
|
availableStates.Clear();
|
|
|
|
if (enemy.animatorOverride != null && avatarAnimator != null)
|
|
{
|
|
avatarAnimator.runtimeAnimatorController = enemy.animatorOverride;
|
|
avatarAnimator.enabled = true;
|
|
|
|
// Ïîëó÷àåì ðåàëüíî ïåðåîïðåäåë¸ííûå àíèìàöèè
|
|
var overrides = new List<KeyValuePair<AnimationClip, AnimationClip>>();
|
|
enemy.animatorOverride.GetOverrides(overrides);
|
|
|
|
foreach (var kv in overrides)
|
|
{
|
|
if (kv.Value != null)
|
|
availableStates.Add(kv.Key.name);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (enemy.characterSprite != null)
|
|
avatarImage.sprite = enemy.characterSprite;
|
|
|
|
avatarAnimator.enabled = false;
|
|
}
|
|
|
|
dialogueText.text = "";
|
|
if (dialoguePanel != null)
|
|
{
|
|
dialoguePanel.anchoredPosition = dialogueOriginalPos;
|
|
dialoguePanel.SetSiblingIndex(0); // ïàíåëü ïîä ïîðòðåòîì
|
|
}
|
|
}
|
|
|
|
public void ShowNextDialogue()
|
|
{
|
|
if (currentEnemy == null || currentEnemy.dialogues.Length == 0) return;
|
|
|
|
DialogueLine line = currentEnemy.dialogues[dialogueIndex];
|
|
dialogueIndex = (dialogueIndex + 1) % currentEnemy.dialogues.Length;
|
|
|
|
if (!gameObject.activeInHierarchy)
|
|
{
|
|
pendingDialogue = line;
|
|
return;
|
|
}
|
|
|
|
StartDialogue(line);
|
|
}
|
|
|
|
private void StartDialogue(DialogueLine line)
|
|
{
|
|
if (dialogueCoroutine != null)
|
|
StopCoroutine(dialogueCoroutine);
|
|
|
|
dialogueCoroutine = StartCoroutine(DialogueSequence(line));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ïîêàçûâàåò äèàëîã, ñîîòâåòñòâóþùèé óêàçàííîìó ñîáûòèþ
|
|
/// </summary>
|
|
public void ShowEventDialogue(DialogueEventType eventType)
|
|
{
|
|
if (currentEnemy == null) return;
|
|
|
|
DialogueLine? line = currentEnemy.GetRandomDialogue(eventType);
|
|
if (line.HasValue)
|
|
{
|
|
if (!gameObject.activeInHierarchy)
|
|
{
|
|
pendingDialogue = line.Value;
|
|
return;
|
|
}
|
|
StartDialogue(line.Value);
|
|
}
|
|
}
|
|
|
|
private IEnumerator DialogueSequence(DialogueLine line)
|
|
{
|
|
// 1. Âðåìåííî óñòàíàâëèâàåì ïîëíûé òåêñò (íåâèäèìî)
|
|
dialogueText.enableWordWrapping = true;
|
|
dialogueText.overflowMode = TextOverflowModes.Overflow;
|
|
dialogueText.text = line.text;
|
|
|
|
// 2. Âêëþ÷àåì àâòî-ïîäáîð ðàçìåðà
|
|
dialogueText.enableAutoSizing = true;
|
|
|
|
dialogueText.fontSizeMin = 5;
|
|
|
|
// 3. Æä¸ì 1 êàäð — ÷òîáû TMP ïðîñ÷èòàë ðàçìåð
|
|
yield return null;
|
|
|
|
// 4. Ñîõðàíÿåì ïîäîáðàííûé ðàçìåð
|
|
float finalFontSize = dialogueText.fontSize;
|
|
|
|
// 5. Ôèêñèðóåì ðàçìåð (àâòîñàéç âûêëþ÷àåì)
|
|
dialogueText.enableAutoSizing = false;
|
|
dialogueText.fontSize = finalFontSize;
|
|
|
|
// 6. Î÷èùàåì òåêñò ïåðåä ïå÷àòüþ
|
|
dialogueText.text = "";
|
|
|
|
// Ïîçèöèè ïàíåëè
|
|
Vector2 hiddenPos = dialogueOriginalPos;
|
|
Vector2 shownPos = hiddenPos + new Vector2(panelExpandWidth, 0);
|
|
|
|
|
|
|
|
// Âõîä ïàíåëè
|
|
SetEmotion(transitionIn);
|
|
float t = 0f;
|
|
while (t < 1f)
|
|
{
|
|
t += Time.deltaTime * panelExpandSpeed;
|
|
dialoguePanel.anchoredPosition = Vector2.Lerp(hiddenPos, shownPos, t);
|
|
yield return null;
|
|
}
|
|
dialoguePanel.anchoredPosition = shownPos;
|
|
|
|
// Àíèìàöèÿ ýìîöèè
|
|
SetEmotion(line.animationName);
|
|
|
|
if (line.voiceClip != null)
|
|
{
|
|
SoundManager.Instance.PlayVoice(playerId, line.voiceClip);
|
|
}
|
|
|
|
// Ïå÷àòü òåêñòà
|
|
dialogueText.text = "";
|
|
foreach (char c in line.text)
|
|
{
|
|
dialogueText.text += c;
|
|
yield return new WaitForSeconds(typingSpeed);
|
|
}
|
|
|
|
// Æä¸ì
|
|
yield return new WaitForSeconds(dialogueHoldTime);
|
|
|
|
|
|
|
|
// Âûõîä ïàíåëè
|
|
SetEmotion(transitionOut);
|
|
dialogueText.text = "";
|
|
t = 0f;
|
|
while (t < 1f)
|
|
{
|
|
t += Time.deltaTime * panelExpandSpeed;
|
|
dialoguePanel.anchoredPosition = Vector2.Lerp(shownPos, hiddenPos, t);
|
|
yield return null;
|
|
}
|
|
dialoguePanel.anchoredPosition = hiddenPos;
|
|
|
|
// Âîçâðàò â idle
|
|
SetEmotion(idleAnimationName);
|
|
}
|
|
|
|
public void SetEmotion(string stateName)
|
|
{
|
|
if (avatarAnimator == null || string.IsNullOrEmpty(stateName)) return;
|
|
|
|
if (availableStates.Contains(stateName))
|
|
avatarAnimator.Play(stateName);
|
|
}
|
|
}
|