对话不是从第一句话开始的,而是在我按下键开始在 Unity 中开始对话之前开始的

Dialogue does not begin with the first sentence and it starts before I press key to begin dialogue in Unity

我正在为我正在开发的 2d 游戏开发对话和任务系统。我正在尝试让多个 NPC 给出不同的任务,每个任务都有不同的对话。每当玩家按下 E 键时,我都会尝试触发我的对话。目前,只要玩家与 NPC 碰撞器接触,我的游戏就会显示对话。对话也从对话数组的第二句开始。此外,一旦玩家与多个npc交互,所有npc的对话都会成为最后一个与之交互的npc的对话。

这是我的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;

public class QuestGiver :  NPC
{
    public bool AssignedQuest { get; set; }
    public bool Helped { get; set; }
    [SerializeField]
    private GameObject quests;
    [SerializeField]
    private string questType;
    private Quest Quest { get; set; }


    public CharacterController2D player;

    public GameObject questWindow;
    public Text titleText;
    public Text descriptionText;
    public Text expRewardText;
    public Text currencyRewardText;

    private void Start()
    {

    }
    public override void Interact()
    {
        if (!AssignedQuest && !Helped)
        {
            DialogueManager.Instance.AddNewDialogue(dialogue, name);
            AssignQuest();
        }
        else if (AssignedQuest && !Helped)
        {
            CheckQuest();
        }
        else
        {
            DialogueManager.Instance.AddNewDialogue(Quest.completedDialogue, name);
        }
    }

    void AssignQuest()
    {
        AssignedQuest = true;
        Quest = (Quest)quests.AddComponent(Type.GetType(questType));
    }
    void CheckQuest()
    {
        if (Quest.Completed)
        {
            Quest.GiveReward();
            Helped = true;
            AssignedQuest = false;
            DialogueManager.Instance.AddNewDialogue(Quest.rewardDialogue, name);
            Destroy(quests.GetComponent(Type.GetType(questType)));
        }
        else
        {
            DialogueManager.Instance.AddNewDialogue(Quest.inProgressDialogue, name);
        }
    }

    public void OpenQuestWindow()
    {
        questWindow.SetActive(true);
        titleText.text = Quest.QuestName;
        descriptionText.text = Quest.Description;
        expRewardText.text = Quest.ExpRewards.ToString();
        currencyRewardText.text = Quest.CurrencyReward.ToString();
    }

    public void AcceptQuest()
    {
        questWindow.SetActive(false);
        Quest.Completed = false;
        player.questsList.Add(Quest);
    }
}

这是任务脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;

[System.Serializable]
public class Quest : MonoBehaviour
{
    public List<QuestGoal> Goals { get; set; } = new List<QuestGoal>();

    public string[] inProgressDialogue, rewardDialogue, completedDialogue;

    public string QuestName { get; set; }
    public string Description { get; set; }
    public int ExpRewards { get; set; }
    public int CurrencyReward { get; set; }
    public Item ItemReward { get; set; }
    public bool Completed { get; set; }

    public void CheckGoals()
    {
        Completed = Goals.All(q => q.Completed);
        if (Completed) GiveReward();
        
    }
    public void GiveReward()
    {
        if (ItemReward != null)
                    Inventory.inventory.Add(ItemReward);
        
    }

这是NPC:

    using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NPC : Interactable
{
    public string[] dialogue;
    public string name;

    public override void Interact()
    {  
        base.Interact();
        DialogueManager.Instance.AddNewDialogue(dialogue, name);
        Debug.Log("Interacting with " + name);
    }

    public void TriggerDialogue()
    {
        FindObjectOfType<DialogueManager>().AddNewDialogue(dialogue, name);
    }
}

这是我的对话脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;

public class DialogueManager : MonoBehaviour
{

    #region

    public static DialogueManager Instance { get; set; }
    public GameObject dialoguePanel;
    private void Awake()
    {
        dialoguePanel.SetActive(false);
        if (Instance != null && Instance != this)
        {
            Debug.Log(Instance);
            Destroy(Instance);
        }
        else
        {
            Instance = this;
        }
    }

    #endregion

    public Text nameText, dialogueText;
    public Button continueButton;

    public Animator animator;
    public string npcName;
    int dialogueIndex;
    public List<string> dialogueLines = new List<string>();

    void Start()
    {
    }

    public void AddNewDialogue(string[] lines, string npcName)
    {
        dialogueIndex = 0;
        dialogueLines = new List<string>();
        foreach (string line in lines)
        {
            dialogueLines.Add(line);
        }
        this.npcName = npcName;

        Debug.Log(dialogueLines.Count);
        Debug.Log(npcName);

        CreateDialogue();
    }

    public void CreateDialogue()
    {
        nameText.text = npcName;
        dialogueText.text = dialogueLines[dialogueIndex];
        dialoguePanel.SetActive(true);
        animator.SetBool("IsOpen", true);

        ContinueDialogue();
    }


    public void ContinueDialogue()
    {
        if (dialogueIndex < dialogueLines.Count - 1)
        {
            dialogueIndex++;
            dialogueText.text = dialogueLines[dialogueIndex];
        }
        else
        {
            EndDialogue();
        }

        StopAllCoroutines();
        StartCoroutine(TypeSentence(dialogueText.text));
    }

    IEnumerator TypeSentence (string sentence)
    {
        dialogueText.text = "";
        foreach (char letter in sentence.ToCharArray())
        {
            dialogueText.text += letter;
            yield return null;
        }
    }


    void EndDialogue()
    {
        animator.SetBool("IsOpen", false);
        Debug.Log("End of conversation");
    }
}

这是播放器控制器的一部分:

using UnityEngine;
using UnityEngine.Events;
using Spine.Unity;
using UnityEngine.EventSystems;
using System.Collections.Generic;

public class CharacterController2D : MonoBehaviour
{
    private GameObject triggeringNpc;
    public GameObject npcText;

    public List<Quest> questsList = new List<Quest>();

    private bool triggering;

    private void OnTriggerEnter2D(Collider2D other)
    {
        Interactable interactable = other.gameObject.GetComponent<Interactable>();

        if (interactable != null)
        {
            interactable.Interact();

        }
        if (other.tag == "NPC")
        {
            triggering = true;
            triggeringNpc = other.gameObject;
            
        }
        if (other.tag == "QuestGiver")
        {
            triggering = true;
            triggeringNpc = other.gameObject;
        }
    }
    private void OnTriggerExit2D(Collider2D other)
    {
        if (other.tag == "NPC")
        {
            triggering = false;
            triggeringNpc = null;
        }
        if (other.tag == "QuestGiver")
        {
            triggering = false;
            triggeringNpc = null;
        }
    }
        private void Update()
    {
        if (triggering)
        {
            npcText.SetActive(true);
            if (Input.GetKeyDown(KeyCode.E))
            {
                FindObjectOfType<QuestGiver>().TriggerDialogue();
            }
        }
        else
        {
            npcText.SetActive(false);
        }
    }
}

提前致谢,抱歉拖了这么久post。

对话从第二行开始:

在 CreateDialogue() 方法中,最后调用 ContinueDialogue()。因此,您创建对话,然后立即告诉它转到下一行。我认为您可能希望在 CreateDialogue().

结束时调用 StartCoroutine(TypeSentence(dialogueText.text))

交互问题:

您通过 interactable.Interact() 在 OnTriggerEnter2D 的开头调用 Interact()。在这里,擦除 OnTriggerEnter2D 方法中的所有代码并将其替换为这个。

if (other.tag == "NPC" || other.tag == "QuestGiver") {
    triggering = true;
    triggeringNpc = other.gameObject;
} else if (interactable != null) { interactable.Interact(); }