230 lines
6.6 KiB
C#
230 lines
6.6 KiB
C#
using UnityEngine;
|
|
using Yarn.Unity;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using DG.Tweening;
|
|
|
|
public class CharacterManager : MonoBehaviour
|
|
{
|
|
private Dictionary<string, GameObject> loadedCharacters = new Dictionary<string, GameObject>();
|
|
private GameObject currentCharacter;
|
|
|
|
// 图层引用
|
|
private SpriteRenderer eyeLayer;
|
|
private SpriteRenderer frownLayer;
|
|
private SpriteRenderer smileLayer;
|
|
private SpriteRenderer openEyesTearsLayer;
|
|
private SpriteRenderer closedEyesTearsLayer;
|
|
|
|
private Coroutine autoBlinkCoroutine;
|
|
|
|
private float characterAlpha;
|
|
|
|
[YarnCommand("character_init")]
|
|
public IEnumerator CharacterInit(string characterName)
|
|
{
|
|
if (!loadedCharacters.ContainsKey(characterName))
|
|
{
|
|
// 异步加载角色预制体
|
|
ResourceRequest request = Resources.LoadAsync<GameObject>($"Characters/{characterName}");
|
|
yield return request;
|
|
|
|
GameObject characterPrefab = request.asset as GameObject;
|
|
if (characterPrefab != null)
|
|
{
|
|
GameObject characterInstance = Instantiate(characterPrefab, transform);
|
|
loadedCharacters[characterName] = characterInstance;
|
|
characterInstance.SetActive(false);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"Character prefab {characterName} not found in Resources/Characters");
|
|
yield break;
|
|
}
|
|
}
|
|
|
|
currentCharacter = loadedCharacters[characterName];
|
|
|
|
// 获取图层引用
|
|
eyeLayer = currentCharacter.transform.Find("EyeLayer").GetComponent<SpriteRenderer>();
|
|
frownLayer = currentCharacter.transform.Find("FrownLayer").GetComponent<SpriteRenderer>();
|
|
smileLayer = currentCharacter.transform.Find("SmileLayer").GetComponent<SpriteRenderer>();
|
|
openEyesTearsLayer = currentCharacter.transform.Find("OpenEyesTearsLayer").GetComponent<SpriteRenderer>();
|
|
closedEyesTearsLayer = currentCharacter.transform.Find("ClosedEyesTearsLayer").GetComponent<SpriteRenderer>();
|
|
|
|
|
|
|
|
// 初始化图层状态
|
|
eyeLayer.enabled = false;
|
|
yield return null;
|
|
frownLayer.enabled = false;
|
|
yield return null;
|
|
smileLayer.enabled = false;
|
|
yield return null;
|
|
openEyesTearsLayer.enabled = false;
|
|
yield return null;
|
|
closedEyesTearsLayer.enabled = false;
|
|
|
|
// 初始化角色透明度
|
|
SetCharacterAlpha(0);
|
|
|
|
// 等待一帧,确保初始化完成
|
|
yield return new WaitForSeconds(1);
|
|
|
|
// 激活角色
|
|
currentCharacter.SetActive(true);
|
|
}
|
|
|
|
[YarnCommand("wait_for_character_init")]
|
|
public IEnumerator WaitForCharacterInit(string characterName)
|
|
{
|
|
yield return StartCoroutine(CharacterInit(characterName));
|
|
}
|
|
|
|
[YarnCommand("character_show")]
|
|
public void CharacterShow(string characterName)
|
|
{
|
|
if (currentCharacter != null)
|
|
{
|
|
// 将角色的透明度设置为 1
|
|
SetCharacterAlpha(1);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"Character {characterName} not found in loaded characters.");
|
|
}
|
|
}
|
|
|
|
[YarnCommand("character_fade_in")]
|
|
public IEnumerator CharacterFadeIn(float duration = 1f)
|
|
{
|
|
if (currentCharacter != null)
|
|
{
|
|
yield return FadeCharacter(0, 1, duration);
|
|
}
|
|
}
|
|
|
|
[YarnCommand("character_fade_out")]
|
|
public IEnumerator CharacterFadeOut(float duration = 1f)
|
|
{
|
|
if (currentCharacter != null)
|
|
{
|
|
yield return FadeCharacter(1, 0, duration);
|
|
currentCharacter.SetActive(false);
|
|
}
|
|
}
|
|
|
|
private void SetCharacterAlpha(float alpha)
|
|
{
|
|
characterAlpha = alpha;
|
|
SpriteRenderer[] renderers = currentCharacter.GetComponentsInChildren<SpriteRenderer>();
|
|
foreach (var renderer in renderers)
|
|
{
|
|
Color color = renderer.color;
|
|
color.a = alpha;
|
|
renderer.color = color;
|
|
}
|
|
}
|
|
|
|
private IEnumerator FadeCharacter(float fromAlpha, float toAlpha, float duration)
|
|
{
|
|
yield return DOTween.To(() => characterAlpha, x => SetCharacterAlpha(x), toAlpha, duration).WaitForCompletion();
|
|
}
|
|
|
|
[YarnCommand("character_eye")]
|
|
public void SetEyeState(string state)
|
|
{
|
|
if (autoBlinkCoroutine != null)
|
|
{
|
|
StopCoroutine(autoBlinkCoroutine);
|
|
autoBlinkCoroutine = null;
|
|
}
|
|
|
|
switch (state)
|
|
{
|
|
case "open":
|
|
eyeLayer.enabled = true;
|
|
break;
|
|
case "close":
|
|
eyeLayer.enabled = false;
|
|
break;
|
|
case "blink":
|
|
StartCoroutine(Blink());
|
|
break;
|
|
case "auto_blink":
|
|
autoBlinkCoroutine = StartCoroutine(AutoBlink(true));
|
|
break;
|
|
default:
|
|
Debug.LogError("Unknown eye state: " + state);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private IEnumerator Blink()
|
|
{
|
|
eyeLayer.enabled = false;
|
|
yield return new WaitForSeconds(0.1f);
|
|
eyeLayer.enabled = true;
|
|
}
|
|
|
|
private IEnumerator AutoBlink(bool immediateBlink)
|
|
{
|
|
if (immediateBlink)
|
|
{
|
|
yield return Blink();
|
|
}
|
|
|
|
while (true)
|
|
{
|
|
yield return new WaitForSeconds(6f);
|
|
yield return Blink();
|
|
}
|
|
}
|
|
|
|
[YarnCommand("character_face")]
|
|
public void SetFaceState(string state)
|
|
{
|
|
switch (state)
|
|
{
|
|
case "default":
|
|
frownLayer.enabled = false;
|
|
smileLayer.enabled = false;
|
|
break;
|
|
case "frown":
|
|
frownLayer.enabled = true;
|
|
smileLayer.enabled = false;
|
|
break;
|
|
case "smile":
|
|
frownLayer.enabled = false;
|
|
smileLayer.enabled = true;
|
|
break;
|
|
default:
|
|
Debug.LogError("Unknown face state: " + state);
|
|
break;
|
|
}
|
|
}
|
|
|
|
[YarnCommand("character_crying")]
|
|
public void SetCrying(bool isCrying)
|
|
{
|
|
if (isCrying)
|
|
{
|
|
if (eyeLayer.enabled)
|
|
{
|
|
openEyesTearsLayer.enabled = true;
|
|
closedEyesTearsLayer.enabled = false;
|
|
}
|
|
else
|
|
{
|
|
openEyesTearsLayer.enabled = false;
|
|
closedEyesTearsLayer.enabled = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
openEyesTearsLayer.enabled = false;
|
|
closedEyesTearsLayer.enabled = false;
|
|
}
|
|
}
|
|
}
|