278 lines
7.7 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|