【问题标题】:Dialogue does not begin with the first sentence and it starts before I press key to begin dialogue in Unity对话不是从第一句话开始的,而是在我按下键开始在 Unity 中开始对话之前开始的
【发布时间】:2020-10-09 18:29:01
【问题描述】:

我正在为我正在开发的 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);
        }
    }
}

提前谢谢你,很抱歉这么长的帖子。

【问题讨论】:

  • 你在哪里/如何调用 Interact()?
  • 我正在使用 OnTriggerEnter2d @ThomasFinch 从我的播放器控制器调用 Interact()
  • @ThomasFinch 我将 playerController 添加到问题中。

标签: c# unity3d game-engine


【解决方案1】:

对话从第二行开始:

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


交互问题:

您在 OnTriggerEnter2D 的开头通过执行 interactable.Interact() 调用 Interact()。在这里,删除 OnTriggerEnter2D 方法中的所有代码并用这个替换它。

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

【讨论】:

  • 谢谢,这解决了从第二句开始的对话问题。我仍然需要解决交互问题,但这很有帮助。
  • 用交互问题的确切解决方案更新了我的答案。
  • 这对一个 npc 来说是完美的,就像一个魅力。但是,当我尝试添加第二个 npc 时,我遇到了与最初相同的问题,即两者的对话变成了同一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多