274 lines
6.5 KiB
C#
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);
|
|
}
|
|
} |