Files

278 lines
7.7 KiB
C#

using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class galPrefab : MonoBehaviour
{
[Header("默认文本颜色")]
public Color defaultTextColor = Color.white;
[Header("模式1: 角色正式对话")]
public Image roleHostBGbar;
public Image L_roleHostImage;
public Image R_roleHosetImage;
public TextMeshProUGUI roleHostName;
public TextMeshProUGUI roleHostMessage;
public Button host_nextButton;
[Header("模式2: 角色提示对话")]
public Image roleHintBGbar;
public Image roleHintImage;
public TextMeshProUGUI roleHintName;
public TextMeshProUGUI roleHintMessage;
public Button hint_nextButton;
[Header("模式3: 旁白")]
public Image narrationBGbar;
public TextMeshProUGUI narrationMessage;
[Header("模式4: 提示或歌词")]
public Image hintOrLyricsBGbar;
public TextMeshProUGUI hintOrLyricsMessage;
[Header("四种模式容器")]
public GameObject roleHostFather;
public GameObject roleHintFather;
public GameObject narrationFather;
public GameObject hintOrLyricsFather;
private Action advanceCallback;
private void Awake()
{
BindButtons();
HideAllModes();
}
private void Start()
{
TryAssignCanvasCamera();
}
public void Initialize(Action onAdvance)
{
advanceCallback = onAdvance;
BindButtons();
HideAllModes();
}
public void Present(
ingame_galgame_so.DialogueElement.PositionTag positionTag,
ingame_galgame_so.DialogueText dialogue,
Speaker speaker)
{
if (dialogue == null)
{
HideAllModes();
return;
}
HideAllModes();
switch (positionTag)
{
case ingame_galgame_so.DialogueElement.PositionTag.RoleHost:
PresentRoleHost(dialogue, speaker);
break;
case ingame_galgame_so.DialogueElement.PositionTag.RoleHint:
PresentRoleHint(dialogue, speaker);
break;
case ingame_galgame_so.DialogueElement.PositionTag.Narration:
PresentNarration(dialogue);
break;
case ingame_galgame_so.DialogueElement.PositionTag.HintOrLyrics:
PresentHintOrLyrics(dialogue);
break;
default:
PresentNarration(dialogue);
break;
}
}
public void HideAllModes()
{
SetActiveSafe(roleHostFather, false);
SetActiveSafe(roleHintFather, false);
SetActiveSafe(narrationFather, false);
SetActiveSafe(hintOrLyricsFather, false);
}
public void SetAdvanceEnabled(bool enabled)
{
SetButtonEnabled(host_nextButton, enabled);
SetButtonEnabled(hint_nextButton, enabled);
}
private void PresentRoleHost(ingame_galgame_so.DialogueText dialogue, Speaker speaker)
{
SetActiveSafe(roleHostFather, true);
Color accent = speaker != null ? speaker.spkr_themeColor : defaultTextColor;
string speakerName = speaker != null ? speaker.spkrName : string.Empty;
Sprite portrait = speaker != null ? speaker.spkrHD_Sprite : null;
ApplyImage(roleHostBGbar, roleHostBGbar != null ? roleHostBGbar.sprite : null, accent, true);
ApplyText(roleHostName, speakerName, accent);
ApplyText(roleHostMessage, dialogue.content, defaultTextColor);
bool leftActive = dialogue.imagePos == ingame_galgame_so.DialogueText.ImagePosition.Left;
bool rightActive = !leftActive;
ApplyPortrait(L_roleHostImage, leftActive ? portrait : null, leftActive, dialogue.flipX);
ApplyPortrait(R_roleHosetImage, rightActive ? portrait : null, rightActive, dialogue.flipX);
}
private void PresentRoleHint(ingame_galgame_so.DialogueText dialogue, Speaker speaker)
{
SetActiveSafe(roleHintFather, true);
Color accent = speaker != null ? speaker.spkr_themeColor : defaultTextColor;
string speakerName = speaker != null ? speaker.spkrName : string.Empty;
Sprite portrait = null;
if (speaker != null)
{
portrait = speaker.spkrProfile_Sprite != null ? speaker.spkrProfile_Sprite : speaker.spkrHD_Sprite;
}
ApplyImage(roleHintBGbar, roleHintBGbar != null ? roleHintBGbar.sprite : null, accent, true);
ApplyPortrait(roleHintImage, portrait, portrait != null, dialogue.flipX);
ApplyText(roleHintName, speakerName, accent);
ApplyText(roleHintMessage, dialogue.content, defaultTextColor);
}
private void PresentNarration(ingame_galgame_so.DialogueText dialogue)
{
SetActiveSafe(narrationFather, true);
ApplyText(narrationMessage, dialogue.content, defaultTextColor);
}
private void PresentHintOrLyrics(ingame_galgame_so.DialogueText dialogue)
{
SetActiveSafe(hintOrLyricsFather, true);
ApplyText(hintOrLyricsMessage, dialogue.content, defaultTextColor);
}
private void BindButtons()
{
BindButton(host_nextButton);
BindButton(hint_nextButton);
}
private void BindButton(Button button)
{
if (button == null)
{
return;
}
button.onClick.RemoveListener(HandleAdvanceClicked);
button.onClick.AddListener(HandleAdvanceClicked);
}
private void HandleAdvanceClicked()
{
advanceCallback?.Invoke();
}
private void TryAssignCanvasCamera()
{
Camera foundCamera = null;
Camera[] cameras = Camera.allCameras;
if (cameras != null && cameras.Length > 0)
{
foundCamera = cameras[0];
}
else
{
Camera[] camObjs = UnityEngine.Object.FindObjectsByType<Camera>(FindObjectsInactive.Exclude, FindObjectsSortMode.None);
if (camObjs != null && camObjs.Length > 0)
{
foundCamera = camObjs[0];
}
}
if (foundCamera == null)
{
foundCamera = Camera.main;
}
if (foundCamera == null)
{
return;
}
Canvas parentCanvas = GetComponentInParent<Canvas>();
if (parentCanvas != null)
{
parentCanvas.worldCamera = foundCamera;
}
}
private static void SetActiveSafe(GameObject target, bool active)
{
if (target != null)
{
target.SetActive(active);
}
}
private static void SetButtonEnabled(Button button, bool enabled)
{
if (button == null)
{
return;
}
button.interactable = enabled;
if (button.gameObject.activeSelf != enabled)
{
button.gameObject.SetActive(enabled);
}
}
private static void ApplyText(TextMeshProUGUI target, string text, Color color)
{
if (target == null)
{
return;
}
target.text = text ?? string.Empty;
target.color = color;
}
private static void ApplyImage(Image target, Sprite sprite, Color color, bool enabled)
{
if (target == null)
{
return;
}
target.enabled = enabled;
target.sprite = sprite;
target.color = color;
}
private static void ApplyPortrait(Image target, Sprite sprite, bool visible, bool flipX)
{
if (target == null)
{
return;
}
target.enabled = visible && sprite != null;
target.sprite = sprite;
RectTransform rect = target.rectTransform;
if (rect != null)
{
Vector3 scale = rect.localScale;
float absX = Mathf.Abs(scale.x);
scale.x = flipX ? -absX : absX;
rect.localScale = scale;
}
}
}