为什么没有播放所有对话,并且从头到尾都没有正确的顺序?

问题描述 投票:0回答:1

为了进行测试,我在索引0和1进行了两次对话。我希望它播放第一个对话索引0,然后在播放完毕后开始播放索引1的下一个对话。

这是具有播放方法的脚本。第一个应该一个播放一个对话列表/数组,第二个应该只播放一个对话:

PlayConversations和PlayConversation。

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

public class ConversationTrigger : MonoBehaviour
{
    public List<Conversation> conversations = new List<Conversation>();
    public static List<int> conversationsToPlay = new List<int>();
    public bool conversationEnd;
    public GameObject canvas;
    public static int conversationIndex;

    private DialogueManager dialoguemanager;
    private string jsonPath;

    public void InitJsonPath()
    {
        jsonPath = Application.persistentDataPath + "/" + "Json.txt";
    }

    private void Start()
    {
        conversationIndex = 0;
        dialoguemanager = FindObjectOfType<DialogueManager>();
    }

    public IEnumerator PlayConversations()
    {
        canvas.SetActive(true);
        conversationEnd = false;
        var conversations = conversationsToPlay.ToArray(); // Copy the list
        conversationsToPlay.Clear(); // Immediately clear the original list

        for (int i = 0; i < conversations.Length; i++) // iterate over the array
        {
            // Now you also don't need to remove items anymore, 
            // since you already cleared the list
            yield return StartCoroutine(PlayConversation(conversations[i]));
        }
    }

    public IEnumerator PlayConversation(int index)
    {
        if (conversations.Count > 0 &&
            conversations[index].Dialogues.Count > 0)
        {
            for (int i = 0; i < conversations[index].Dialogues.Count; i++)
            {
                if (dialoguemanager != null)
                {
                    dialoguemanager.StartDialogue(conversations[index].Dialogues[i]);
                }

                while (DialogueManager.dialogueEnded == false)
                {
                    yield return null;
                }
            }

            conversationEnd = true;
            conversationIndex = index;
            canvas.SetActive(false);
            Debug.Log("Conversation Ended");
        }
    }

    public void SaveConversations()
    {
        string jsonTransform = JsonHelper.ToJson(conversations.ToArray(), true);
        File.WriteAllText(jsonPath, jsonTransform);
    }

    public void LoadConversations()
    {
        string jsonTransform = File.ReadAllText(jsonPath);
        conversations.Clear();
        conversations.AddRange(JsonHelper.FromJson<Conversation>(jsonTransform));
    }
}

为此,我制作了另一个帮助脚本:

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

public class PlayConversations : MonoBehaviour
{
    private static ConversationTrigger conversationTrigger;
    private static PlayConversations instance;

    private void Awake()
    {
        conversationTrigger = GetComponent<ConversationTrigger>();
        instance = this;
    }

    public static void ConversationToPlay(int index)
    {
        ConversationTrigger.conversationsToPlay.Add(index);
        instance.StartCoroutine(conversationTrigger.PlayConversations());
    }
}

以及用于测试的脚本:

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

public class BeginningCutscene : MonoBehaviour
{
    public DepthOfField dephOfField;

    // Update is called once per frame
    void Update()
    {
        if (dephOfField.dephOfFieldFinished == true)
        {
            PlayConversations.ConversationToPlay(0);
            PlayConversations.ConversationToPlay(1);
        }
    }
}

但是它首先开始播放索引1处的对话,然后仅播放索引0处的对话的一部分,然后重新开始然后结束。

c# unity3d
1个回答
1
投票

我认为您的问题与实现ConversationsToPlay方法的方式有关。在每次调用该方法时,都会启动一个新的协程,协程将依次调用PlayConversation方法。这意味着每次调用ConversationToPlay都会在您传递的索引处播放对话,这就是它们重叠的原因。

我能想到的最简单的解决方案是将协程的开始移到ConversationsToPlay方法之外。

类似这样的东西:

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

public class PlayConversations : MonoBehaviour
{
    private static ConversationTrigger conversationTrigger;
    private static PlayConversations instance;

    private void Awake()
    {
        conversationTrigger = GetComponent<ConversationTrigger>();
        instance = this;
    }

    public static void AddConversationToPlay(int index)
    {
        ConversationTrigger.conversationsToPlay.Add(index);
    }

    public static void StartPlayConversationsCoroutine()
    {
        instance.StartCoroutine(conversationTrigger.PlayConversations());
    }
}

和测试脚本

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

public class BeginningCutscene : MonoBehaviour
{
    public DepthOfField dephOfField;

    // Update is called once per frame
    void Update()
    {
        if (dephOfField.dephOfFieldFinished == true)
        {
            PlayConversations.AddConversationToPlay(0);
            PlayConversations.AddConversationToPlay(1);
            PlayConversations.StartPlayConversationsCoroutine();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.