Files
aibis-dream/Assets/Scripts/FixSystemNew/Clinic/CharacterViewer.cs
T
2025-01-09 16:09:45 +08:00

214 lines
6.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
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 CharacterData characterData;
public event Action<CharacterData> CharacterChangeEvent;
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;
}
characterData = new CharacterData();
characterData.characterName = characterName;
// 加载新的
GameObject characterPrefab = request.asset as GameObject;
_curCharacter = Instantiate(characterPrefab, transform);
// 初始化处理
_curCharacter.SetActive(false);
_blinkLayer = _curCharacter.transform.Find("闭眼").GetComponent<SpriteRenderer>();
_blinkLayer.enabled = false;
// 表情和动作只留一种
characterData.faceName = ActiveLayer(FaceGroup);
characterData.poseName = ActiveLayer(PoseGroup);
// 换液设备先隐藏
RemoveLinkDevice();
// 初始化角色透明度
SetCharacterAlpha(0);
// 等待一帧,确保初始化完成
yield return new WaitForSeconds(1);
// 激活角色
_curCharacter.SetActive(true);
characterData.isShow = false;
UpdateCharacterData();
}
private void UpdateCharacterData()
{
CharacterChangeEvent?.Invoke(characterData);
}
private static string ActiveLayer(Transform root, string layerName = null)
{
var childLayers = root.GetComponentsInChildren<SpriteRenderer>(true);
if (childLayers.Length == 0) return null;
foreach (var layer in childLayers)
{
layer.enabled = layer.gameObject.name == layerName;
}
// 如果输入为空,就默认激活一层
if (layerName == null)
{
childLayers[0].enabled = true;
return childLayers[0].gameObject.name;
}
return layerName;
}
private void SetCharacterAlpha(float alpha)
{
_characterAlpha = alpha;
SpriteRenderer[] renderers = _curCharacter.GetComponentsInChildren<SpriteRenderer>(true);
Array.ForEach(renderers, spriteRenderer => { spriteRenderer.SetAlpha(alpha); });
}
public IEnumerator CharacterFadeIn(float duration = 1f)
{
if (_curCharacter)
{
yield return FadeCharacter(1, duration);
characterData.isShow = true;
UpdateCharacterData();
}
}
public IEnumerator CharacterFadeOut(float duration = 1f)
{
if (_curCharacter != null)
{
yield return FadeCharacter(0, duration);
characterData.isShow = false;
UpdateCharacterData();
}
}
private IEnumerator FadeCharacter(float toAlpha, float duration)
{
yield return DOTween.To(() => _characterAlpha, x => SetCharacterAlpha(x), toAlpha, duration)
.WaitForCompletion();
}
public void SwitchPose(string poseName)
{
characterData.poseName = ActiveLayer(PoseGroup, poseName);
UpdateCharacterData();
}
public void SwitchFace(string faceName)
{
StopAutoBlink();
characterData.faceName = ActiveLayer(FaceGroup, faceName);
UpdateCharacterData();
}
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()
{
characterData.hasDevice = true;
UpdateCharacterData();
LinkDevice.gameObject.SetActive(true);
}
public void RemoveLinkDevice()
{
characterData.hasDevice = false;
UpdateCharacterData();
LinkDevice.gameObject.SetActive(false);
}
public void CharacterShow(string characterName = "")
{
if (_curCharacter != null)
{
characterData.isShow = true;
UpdateCharacterData();
// 将角色的透明度设置为 1
SetCharacterAlpha(1);
}
else
{
Debug.LogError($"Character {characterName} not found in loaded characters.");
}
}
public void OnDestroy()
{
characterData = new CharacterData();
UpdateCharacterData();
}
}
public struct CharacterData
{
public string characterName;
public string faceName;
public string poseName;
public bool hasDevice;
public bool isShow;
}
}