Files
2025TapTapGameJam/Assets/Script/Gameplay/Player/PlayerDialogueController.cs

180 lines
6.1 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 System.Collections.Generic;
using Core;
using UnityEngine;
using UnityEngine.Events;
using Script.Gameplay.Interface;
using Script.Gameplay.Input;
using UI;
using UnityEngine.InputSystem;
namespace Script.Gameplay.Player
{
public class PlayerDialogueController : MonoBehaviour
{
[SerializeField] private bool isEnablePlayerDialogue = true; // 是否启用玩家对话功能
[SerializeField] private FirstPersonRaycaster firstPersonRaycaster; // 第一人称射线检测器
private bool isReadingDialogue = false;
public event Action OnPlayerBeginDialogue;
public event Action OnPlayerEndDialogue;
public event Action<GameObject> OnGazeEnterDialogue;
public event Action<GameObject> OnGazeExitDialogue;
private InputManager inputManager;
private Queue<string> dialogueQueue = new Queue<string>();
private PlayerDialogueViewer playerDialogueViewer;
private IDialogue previousDialogue;
private IDialogue currentDialogueTarget;
public IDialogue CurrentDialogueTarget
{
get => currentDialogueTarget;
set
{
previousDialogue = currentDialogueTarget;
currentDialogueTarget = value;
if (previousDialogue != currentDialogueTarget)
{
if (currentDialogueTarget != null)
{
OnGazeEnterDialogue?.Invoke((currentDialogueTarget as MonoBehaviour)?.gameObject);
}
if (previousDialogue != null)
{
OnGazeExitDialogue?.Invoke((previousDialogue as MonoBehaviour)?.gameObject);
}
}
}
}
void Start()
{
if (firstPersonRaycaster == null)
firstPersonRaycaster = GetComponent<FirstPersonRaycaster>() ??
GetComponentInChildren<FirstPersonRaycaster>();
if (firstPersonRaycaster == null)
firstPersonRaycaster = FindObjectOfType<FirstPersonRaycaster>();
if (firstPersonRaycaster == null)
Debug.LogWarning("FirstPersonRaycaster not found! Please assign or add it to the player.");
inputManager = InputManager.Instance;
var input = inputManager.Input;
input.Player.Read.performed += OnReadOnperformed;
input.Player.ShowNextDialogue.performed += OnShowNextDialogueOnperformed;
ControllerLocator.Instance.Register(this);
}
private void OnShowNextDialogueOnperformed(InputAction.CallbackContext ctx)
{
if (!isEnablePlayerDialogue) return;
if (CurrentDialogueTarget == null) return;
if (!isReadingDialogue) return;
PassNextDialogue();
}
private void OnReadOnperformed(InputAction.CallbackContext ctx)
{
if (!isEnablePlayerDialogue) return;
if (CurrentDialogueTarget == null) return;
if (isReadingDialogue) return;
BeginDialogue();
}
void Update()
{
DetectDialogue();
}
private void DetectDialogue()
{
if (!isEnablePlayerDialogue || firstPersonRaycaster == null) return;
GameObject lookAtObj = firstPersonRaycaster.CurrentLookAtObject;
IDialogue hitDialogue = lookAtObj != null ? lookAtObj.GetComponent<IDialogue>() : null;
CurrentDialogueTarget = hitDialogue;
}
private void BeginDialogue()
{
if (CurrentDialogueTarget != null)
{
isReadingDialogue = true;
OnPlayerBeginDialogue?.Invoke();
CurrentDialogueTarget.OnBeginDialogue?.Invoke(true);
dialogueQueue = SplitDialogue(CurrentDialogueTarget.DialogueContent);
inputManager.SetInputForLook(false);
inputManager.SetInputForMove(false);
PassNextDialogue();
}
}
private void PassNextDialogue()
{
if (CurrentDialogueTarget != null)
{
if (dialogueQueue.Count == 0)
{
EndDialogue();
return;
}
string nextDialogue = dialogueQueue.Dequeue();
if (playerDialogueViewer != null)
{
playerDialogueViewer.ReceiveDialogue(nextDialogue);
}
}
}
private void EndDialogue()
{
if (CurrentDialogueTarget != null)
{
isReadingDialogue = false;
OnPlayerEndDialogue?.Invoke();
CurrentDialogueTarget.OnEndDialogue?.Invoke(true);
inputManager.SetInputForLook(true);
inputManager.SetInputForMove(true);
if (playerDialogueViewer != null)
{
playerDialogueViewer.ClosePanel();
}
// 可扩展隐藏UI、恢复输入等
}
}
private Queue<string> SplitDialogue(string content)
{
// 按换行分段
return new(content.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries));
}
public void RegisterDialogueViewer(PlayerDialogueViewer viewer)
{
playerDialogueViewer = viewer;
}
public void SetPlayerDialogueEnabled(bool isEnabled)
{
isEnablePlayerDialogue = isEnabled;
if (!isEnabled)
{
CurrentDialogueTarget = null;
}
}
private void OnDestroy()
{
ControllerLocator.Instance.Unregister<PlayerDialogueController>(this);
if (inputManager != null)
{
var input = inputManager.Input;
input.Player.Read.performed -= OnReadOnperformed;
input.Player.ShowNextDialogue.performed -= OnShowNextDialogueOnperformed;
}
}
}
}