ManajemenInformatika_E31230007/Assets/Scripts/CharacterManager.cs

274 lines
6.5 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class CharacterExpression
{
public string characterName;
public string expression; // default, happy, confused, sad
public Sprite sprite;
}
public class CharacterManager : MonoBehaviour
{
[Header("Character Slot")]
public Image leftSlot;
public Image rightSlot;
[Header("Expression List")]
public List<CharacterExpression> expressions;
[Header("Animation Settings")]
public float fadeSpeed = 5f;
public float moveSpeed = 5f;
public float offsetX = 200f;
private Dictionary<string, Sprite> expressionDict;
private Coroutine highlightRoutine;
private Coroutine currentRoutine;
private string leftCharacter = "";
private string rightCharacter = "";
private string leftExpression = "";
private string rightExpression = "";
void Start()
{
expressionDict = new Dictionary<string, Sprite>();
foreach (var exp in expressions)
{
string key = exp.characterName.Trim().ToLower() + ":" + exp.expression.Trim().ToLower();
expressionDict[key] = exp.sprite;
}
ResetCharacters();
}
// ================= SHOW CHARACTER =================
public void ShowCharacter(string name, string exp = "default")
{
string key = name.Trim().ToLower() + ":" + exp.Trim().ToLower();
if (!expressionDict.ContainsKey(key))
{
Debug.LogWarning("Expression not found: " + key);
return;
}
// 🔥 STOP semua animasi sebelumnya
if (currentRoutine != null)
StopCoroutine(currentRoutine);
currentRoutine = StartCoroutine(HandleCharacter(name, exp, key));
}
// ================= SPAWN =================
IEnumerator SpawnLeft(string name, string exp, string key)
{
leftCharacter = name;
leftExpression = exp;
leftSlot.sprite = expressionDict[key]; // ✅ FIX
leftSlot.gameObject.SetActive(true);
yield return AnimateIn(leftSlot, -offsetX);
}
IEnumerator SpawnRight(string name, string exp, string key)
{
rightCharacter = name;
rightExpression = exp;
rightSlot.sprite = expressionDict[key];
rightSlot.gameObject.SetActive(true);
yield return AnimateIn(rightSlot, offsetX);
}
// ================= REPLACE =================
IEnumerator ReplaceRight(string name, string exp, string key)
{
yield return AnimateOut(rightSlot, offsetX);
rightCharacter = name;
rightExpression = exp;
rightSlot.sprite = expressionDict[key];
rightSlot.gameObject.SetActive(true);
yield return AnimateIn(rightSlot, offsetX);
}
// ================= CHANGE EXPRESSION =================
IEnumerator ChangeExpression(Image img, string key)
{
yield return Fade(img, 1f, 0.5f);
img.sprite = expressionDict[key];
yield return Fade(img, 0.5f, 1f);
}
IEnumerator HandleCharacter(string name, string exp, string key)
{
// ================= UPDATE EXPRESSION =================
if (leftCharacter == name)
{
if (leftExpression != exp)
yield return ChangeExpression(leftSlot, key);
leftExpression = exp;
yield break;
}
if (rightCharacter == name)
{
if (rightExpression != exp)
yield return ChangeExpression(rightSlot, key);
rightExpression = exp;
yield break;
}
// ================= SPAWN =================
if (leftCharacter == "")
{
yield return SpawnLeft(name, exp, key);
}
else if (rightCharacter == "")
{
yield return SpawnRight(name, exp, key);
}
else
{
yield return ReplaceRight(name, exp, key);
}
}
// ================= ANIMATION =================
IEnumerator AnimateIn(Image img, float direction)
{
RectTransform rt = img.GetComponent<RectTransform>();
Vector2 endPos = rt.anchoredPosition;
Vector2 startPos = endPos + new Vector2(direction, 0);
rt.anchoredPosition = startPos;
Color c = img.color;
c.a = 0f;
img.color = c;
float t = 0;
while (t < 1f)
{
t += Time.deltaTime * moveSpeed;
rt.anchoredPosition = Vector2.Lerp(startPos, endPos, t);
c.a = Mathf.Lerp(0, 1, t);
img.color = c;
yield return null;
}
rt.anchoredPosition = endPos;
c.a = 1f;
img.color = c;
}
IEnumerator AnimateOut(Image img, float direction)
{
RectTransform rt = img.GetComponent<RectTransform>();
Vector2 startPos = rt.anchoredPosition;
Vector2 endPos = startPos + new Vector2(direction, 0);
Color c = img.color;
float t = 0;
while (t < 1f)
{
t += Time.deltaTime * moveSpeed;
rt.anchoredPosition = Vector2.Lerp(startPos, endPos, t);
c.a = Mathf.Lerp(1, 0, t);
img.color = c;
yield return null;
}
img.gameObject.SetActive(false);
}
IEnumerator Fade(Image img, float from, float to)
{
Color c = img.color;
float t = 0;
while (t < 1f)
{
t += Time.deltaTime * fadeSpeed;
c.a = Mathf.Lerp(from, to, t);
img.color = c;
yield return null;
}
}
// ================= HIGHLIGHT =================
public void Highlight(string fullName)
{
string name = fullName.Split(':')[0];
if (highlightRoutine != null)
StopCoroutine(highlightRoutine);
highlightRoutine = StartCoroutine(DoHighlight(name));
}
IEnumerator DoHighlight(string activeName)
{
if (leftCharacter != "")
yield return SetHighlight(leftSlot, leftCharacter == activeName);
if (rightCharacter != "")
yield return SetHighlight(rightSlot, rightCharacter == activeName);
}
IEnumerator SetHighlight(Image img, bool active)
{
float target = active ? 1f : 0.4f;
Color c = img.color;
float t = 0;
float start = c.a;
while (t < 1f)
{
t += Time.deltaTime * fadeSpeed;
c.a = Mathf.Lerp(start, target, t);
img.color = c;
yield return null;
}
c.a = target;
img.color = c;
}
// ================= RESET =================
public void ResetCharacters()
{
StopAllCoroutines();
leftCharacter = "";
rightCharacter = "";
leftSlot.gameObject.SetActive(false);
rightSlot.gameObject.SetActive(false);
}
}