检查函数被多次调用时是否被调用



我目前正在用Unity开发一款c#游戏,我为玩家设计了一些测验。

它有一个从触发器调用的Manager-Script。我制作了5个npc角色,如果玩家在附近,他们会触发测验,但他们使用相同的触发器和管理脚本。我想做一个方法来检查,如果一个测验已经回答正确,同时不阻止其他npc的测验。我试着用bool,但是我可以回答NPC1的Quiz,但是NPC2的Quiz已经"标记"了。

这是我的Manager-Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using Ink.Runtime;
using UnityEngine.EventSystems;
using Unity.Netcode;
using Unity.Netcode.Transports.UTP;
public class NPCQuizManager : MonoBehaviour
{
[Header("Dialog UI")]
[SerializeField] private GameObject dialogPanel;
[SerializeField] private TextMeshProUGUI dialogText;
[Header("Choices UI")]
[SerializeField] private GameObject[] choices;
private TextMeshProUGUI[] choiceTexts;
private Story currentStory;
public bool dialogIsActive{get; private set;}
private static NPCQuizManager instance;
private int rightChoice;

HealthManager hpLoss;
public GameObject player;
private void Awake(){
if(instance != null){
Debug.LogWarning("Es gibt mehrere Dialog Manager in der Scene!");
}
instance = this;
}
public static NPCQuizManager GetInstance(){
if(instance == null){
instance = new NPCQuizManager();
}
return instance;
}
private void Start(){
dialogIsActive = false;
dialogPanel.SetActive(false);
choiceTexts = new TextMeshProUGUI[choices.Length];
int index = 0;
foreach(GameObject choice in choices){
choiceTexts[index] = choice.GetComponentInChildren<TextMeshProUGUI>();
index++;
}
}
private void Update(){
if(dialogIsActive){
if(Input.GetKeyDown(KeyCode.E)){
ContinueStory();
}
}
}
public void StartDialog(TextAsset inkJSON, int correctChoice){
rightChoice = correctChoice;
currentStory = new Story(inkJSON.text);
dialogIsActive = !dialogIsActive;
dialogPanel.SetActive(dialogIsActive);
ContinueStory();
}
public void ExitDialogeMode(){
dialogIsActive = false;
dialogPanel.SetActive(false);
dialogText.text = "";
}
private void ContinueStory(){
if(currentStory.canContinue){
// Setze DialogText auf den nächsten Knoten
dialogText.text = currentStory.Continue();
// Zeige die Choices an
DisplayChoices();
}
else{
//ExitDialogeMode();
}
}
private void DisplayChoices(){
List<Choice> currentChoices = currentStory.currentChoices;
//Check if there are more choices than UI elements
if(currentChoices.Count > choices.Length){
Debug.LogWarning("Es gibt mehr Choices als UI Elemente! Es werden nur: " + currentChoices.Count + " angezeigt!");
}
int index = 0;
//Display all choices
foreach(Choice choice in currentChoices){
choices[index].SetActive(true);
choiceTexts[index].text = choice.text;
index++;
}
// Hide all unused choices
for(int i = index; i < choices.Length; i++){
choices[i].SetActive(false);
}
StartCoroutine(SelectFirstChoice());
}
private IEnumerator SelectFirstChoice(){
//Das Eventsystem muss auf null gesetzt werden, damit es nicht mehr auf das letzte UI Element zeigt
EventSystem.current.SetSelectedGameObject(null);
yield return new WaitForEndOfFrame();
EventSystem.current.SetSelectedGameObject(choices[0].gameObject);
}
public void chooseChoice(int choiceIndex){
currentStory.ChooseChoiceIndex(choiceIndex);
if(choiceIndex == rightChoice){
AddECTS();
}
else{
looseHP();
}
ContinueStory();
}

public void AddECTS(){
player = GameObject.FindGameObjectWithTag("Player");
player.GetComponent<ECTSCounter>().erhoeheWert(5);
}
public void looseHP(){
hpLoss = GameObject.Find("Healthbar").GetComponent<HealthManager>();
hpLoss.TakeDamage(2);
}

}

我将感激和帮助:-)

您可以使用位标志或bool数组来保存回答的问题

private bool[] answered = new bool[numberOfQuestions];
private bool AlreadyAnswered(int questionIndex){
return answered[questionIndex];
}

比起标记测试答案,我将创建一个玩家字典,并将测试id作为存储谁参加了哪个测试的值:

private static Dictionary<GameObject, int> _quizzesParticipationTracing = new Dictionary<GameObject, int>();
// I see that your 'player' is of type GameObject, 
// but you can use any other unique reference to the player, 
// e.g. the UID, if available.

编辑:在@derHugo的尖锐评论之后,我意识到字典不能有多个相同的键来保存不同的值。您可以使用以下代码:

private static Dictionary<GameObject, HashSet<int>> _quizzesParticipationTracing = new Dictionary<GameObject, HashSet<int>>();

编辑结束。

然后,每次玩家出现在测试附近时,你检查相应的键是否已经存在于字典中,以及他们参加了哪些测试。然后你要么显示一个可用的测验,要么告诉他们没有可用的测验。

这对你有意义吗?

最新更新