178 lines
5.2 KiB
C#
178 lines
5.2 KiB
C#
using System.Collections;
|
||
using AibisDream.Utility;
|
||
using DG.Tweening;
|
||
using UnityEngine;
|
||
|
||
namespace AibisDream.FixSystem
|
||
{
|
||
public class CharacterViewer : MonoBehaviour
|
||
{
|
||
private string _curCharacterName;
|
||
private GameObject _curCharacter;
|
||
private float _characterAlpha;
|
||
private Coroutine _autoBlinkCoroutine;
|
||
|
||
private Transform FaceGroup => _curCharacter.transform.Find("表情");
|
||
private Transform PoseGroup => _curCharacter.transform.Find("动作");
|
||
private Transform LinkDevice => _curCharacter.transform.Find("换液设备");
|
||
private SpriteRenderer _blinkLayer;
|
||
|
||
public IEnumerator CharacterInit(string characterName)
|
||
{
|
||
// 异步加载角色预制体(psb)
|
||
ResourceRequest request = Resources.LoadAsync<GameObject>($"Characters/{characterName}");
|
||
yield return request;
|
||
#if DEBUG
|
||
if (request.asset == null)
|
||
{
|
||
Debug.Log($"{characterName}没有找到");
|
||
yield break;
|
||
}
|
||
#endif
|
||
// 先卸载旧的
|
||
if (_curCharacter != null)
|
||
{
|
||
Destroy(_curCharacter);
|
||
_curCharacter = null;
|
||
}
|
||
|
||
// 加载新的
|
||
GameObject characterPrefab = request.asset as GameObject;
|
||
_curCharacter = Instantiate(characterPrefab, transform);
|
||
|
||
// 初始化处理
|
||
_curCharacter.SetActive(false);
|
||
_blinkLayer = _curCharacter.transform.Find("闭眼").GetComponent<SpriteRenderer>();
|
||
_blinkLayer.enabled = false;
|
||
// 表情和动作只留一种
|
||
ActiveLayer(FaceGroup);
|
||
ActiveLayer(PoseGroup);
|
||
// 换液设备先隐藏
|
||
RemoveLinkDevice();
|
||
|
||
// 初始化角色透明度
|
||
SetCharacterAlpha(0);
|
||
|
||
// 等待一帧,确保初始化完成
|
||
yield return new WaitForSeconds(1);
|
||
// 激活角色
|
||
_curCharacter.SetActive(true);
|
||
}
|
||
|
||
private static void ActiveLayer(Transform root, string layerName = null)
|
||
{
|
||
var childLayers = root.GetComponentsInChildren<SpriteRenderer>();
|
||
if (childLayers.Length == 0) return;
|
||
|
||
foreach (var layer in childLayers)
|
||
{
|
||
layer.enabled = layer.gameObject.name == layerName;
|
||
}
|
||
|
||
// 如果输入为空,就默认激活一层
|
||
if (layerName == null)
|
||
{
|
||
childLayers[0].enabled = true;
|
||
}
|
||
}
|
||
|
||
private void SetCharacterAlpha(float alpha)
|
||
{
|
||
_characterAlpha = alpha;
|
||
SpriteRenderer[] renderers = _curCharacter.GetComponentsInChildren<SpriteRenderer>();
|
||
foreach (var childRenderer in renderers)
|
||
{
|
||
Color color = childRenderer.color;
|
||
color.a = alpha;
|
||
childRenderer.color = color;
|
||
}
|
||
}
|
||
|
||
public IEnumerator CharacterFadeIn(float duration = 1f)
|
||
{
|
||
if (_curCharacter != null)
|
||
{
|
||
_curCharacter.SetActive(true);
|
||
yield return FadeCharacter(1, duration);
|
||
}
|
||
}
|
||
|
||
public IEnumerator CharacterFadeOut(float duration = 1f)
|
||
{
|
||
if (_curCharacter != null)
|
||
{
|
||
yield return FadeCharacter(0, duration);
|
||
_curCharacter.SetActive(false);
|
||
}
|
||
}
|
||
|
||
private IEnumerator FadeCharacter(float toAlpha, float duration)
|
||
{
|
||
yield return DOTween.To(() => _characterAlpha, x => SetCharacterAlpha(x), toAlpha, duration)
|
||
.WaitForCompletion();
|
||
}
|
||
|
||
public void SwitchPose(string poseName)
|
||
{
|
||
ActiveLayer(PoseGroup, poseName);
|
||
}
|
||
|
||
public void SwitchFace(string faceName)
|
||
{
|
||
StopAutoBlink();
|
||
ActiveLayer(FaceGroup, faceName);
|
||
}
|
||
|
||
public void Blink()
|
||
{
|
||
_blinkLayer.enabled = true;
|
||
_ = CommonUtil.Delay(100, () => { _blinkLayer.enabled = false; });
|
||
}
|
||
|
||
public void AutoBlink()
|
||
{
|
||
StopAutoBlink();
|
||
_autoBlinkCoroutine = StartCoroutine(AutoBlinkAsync());
|
||
}
|
||
|
||
public void StopAutoBlink()
|
||
{
|
||
if (_autoBlinkCoroutine != null)
|
||
{
|
||
StopCoroutine(_autoBlinkCoroutine);
|
||
}
|
||
}
|
||
|
||
private IEnumerator AutoBlinkAsync()
|
||
{
|
||
while (true)
|
||
{
|
||
yield return new WaitForSeconds(6f);
|
||
Blink();
|
||
}
|
||
}
|
||
|
||
public void AddLinkDevice()
|
||
{
|
||
LinkDevice.gameObject.SetActive(true);
|
||
}
|
||
|
||
public void RemoveLinkDevice()
|
||
{
|
||
LinkDevice.gameObject.SetActive(false);
|
||
}
|
||
|
||
public void CharacterShow(string characterName)
|
||
{
|
||
if (_curCharacter != null)
|
||
{
|
||
// 将角色的透明度设置为 1
|
||
SetCharacterAlpha(1);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError($"Character {characterName} not found in loaded characters.");
|
||
}
|
||
}
|
||
}
|
||
} |