密室逃脱——收集版

一、原版修改
1、导入资源

Unity Learn | 3D Beginner: Complete Project | URP

2、设置Scene

删除SampleScene,打开UnityTechnologies-3DBeginnerComplete下的MainScene

3、降低音量

(1) 打开Hierarchy面板上的Audio降低音量

(2) 打开Prefabs文件夹,找到Ghost,降低音量

4、给FaderCanvas添加组件

(1) Canvas Scaler

(2) Graphic Raycaster

二、新增收集事件
1、新增物体

(1) 新增物体:UI-Image。Questions。设置它的Rect Transform。

(2) 新增文本:ItemsText, TipText(可设置有透明度的黑色背景)

2、新建CollectedItems.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;public class CollectedItems : MonoBehaviour
{public QuestionCollision QuestionCollision;//public GameObject Questions;public TextMeshProUGUI ItemsText, TipText;static int nucleus=0, mitochondria = 0, GolgiApparatus = 0, endoplasmicReticulum = 0, ribosome = 0;void Start(){if (ItemsText == null || TipText == null){Debug.LogError("Questions或ItemsText 或 TipText 未被正确分配!");}}private void OnTriggerEnter(Collider other){if (other.CompareTag("Player")){RandomEvent();}}public void RandomEvent(){int numericValue = Random.Range(0, 100);if (numericValue < 5 && nucleus==0){nucleus = 1;TipText.text = "你发现了细胞核!";}else if(numericValue < 26){mitochondria++;TipText.text = "你得到了线粒体!";}else if (numericValue < 41){endoplasmicReticulum++;TipText.text = "你得到了内质网*1!";}else if (numericValue < 56){GolgiApparatus++;TipText.text = "你得到了高尔基体*1!";}else if (numericValue < 76){ribosome++;TipText.text = "你得到了核糖体*1!";}else if (numericValue < 86){QuestionCollision.ShowQuestions(true);//Questions.SetActive(true);}else{TipText.text = "你什么都没有发现……";}ItemsUpdate();}void ItemsUpdate(){ItemsText.text = "当前持有:细胞核" + nucleus + ";线粒体" + mitochondria + ";高尔基体" + GolgiApparatus + ";内质网" + endoplasmicReticulum + ";核糖体" + ribosome;}
}
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.UI;
using static UnityEngine.Rendering.DebugUI;public class Observer : MonoBehaviour
{public Exercises exercises;public Transform player;public GameObject Questions;public TextMeshProUGUI ItemsText, TipText;static int nucleus=0, mitochondria = 0, GolgiApparatus = 0, endoplasmicReticulum = 0, ribosome = 0;bool canTriggerEffect = true;void OnTriggerEnter(Collider other){if (other.CompareTag("Player")) // 玩家的标签为 "Player" {exercises.ShowQuestion(0);RandomEvent(); }}public void QuitBtn() {GetComponent<UnityEngine.UI.Button>().gameObject.SetActive(false);Questions.SetActive(false);}void ItemsUpdate(){ItemsText.text ="当前持有:细胞核" + nucleus + ";线粒体" + mitochondria + ";高尔基体" + GolgiApparatus + ";内质网" + endoplasmicReticulum + ";核糖体" + ribosome;}void Start(){if (ItemsText == null || TipText == null){Debug.LogError("ItemsText 或 TipText 未被正确分配!");}}void RandomEvent(){if (canTriggerEffect){// 触发效果代码int numericValue = UnityEngine.Random.Range(0, 100);if (numericValue < 5 && nucleus == 0)//获取的随机数范围在0~4{nucleus = 1;TipText.text = "你发现了细胞核!";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 21){mitochondria++;TipText.text = "你得到了线粒体!";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 41){endoplasmicReticulum++;TipText.text = "你得到了内质网*1!";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 61){GolgiApparatus++;TipText.text = "你得到了高尔基体*1!";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 81){ribosome++;TipText.text = "你得到了核糖体*1!"; StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 96){Questions.SetActive(true);}else{TipText.text = "你什么都没有发现……";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}//gameEnding.CaughtPlayer ();ItemsUpdate();canTriggerEffect = false; // 触发效果,将canTriggerEffect设置为falseStartCoroutine(CooldownRoutine()); // 启动冷却时间协程}}IEnumerator CooldownRoutine(){yield return new WaitForSeconds(60f); // 等待1分钟canTriggerEffect = true; // 冷却结束,可以再次触发效果}IEnumerator ClearTextRoutine(float delay){yield return new WaitForSeconds(delay);TipText.text = "";}
}

3、更改enemy设置

(1) 复制 PointOfView预制体,得到PointOfView(1),更名为CollectedItems

(2) 移除CollectedItems上的Observer.cs,添加CollectedItems.cs

(3) 删除Hierarchy面板上的除Ghost (3)以外的敌人的PointOfView。添加CollectedItems预制体并赋值

三、编辑答题面板预制体
1、设置面板

(1) UI-Image,命名为Questions。

(2) 选中导入的图片,然后在Inspector面板中将Texture Type设置为Sprite (2D and UI)

(3) 更改Questions的Image,Transform

(4) 添加按钮,QuitBtn(以隐藏答题面板)

2、添加test

(1) 添加文本。TitleText

(2) 添加按钮。OptionBtnA,按钮下文本的名字OptionTextA,更改文字字体,复制这个按钮得到四个选项按钮

(3) 将Questions制成预制体

(4) 制作题目

3、建立题库——简单题库

A. 创建ChoiceQuestion.cs(不用挂载的脚本)可以与其他脚本放在一起

定义问题类(包含一个问题(question字段)、四个选项(options数组)和正确答案的索引(correctOptionIndex字段))

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[System.Serializable]
public class Question
{public string question; // 问题文本public string[] options = new string[4]; // 选项数组,假设每个问题都有4个选项public int correctOptionIndex; // 正确答案的索引(0表示A,1表示B,依此类推)// 构造函数(可选),用于初始化问题public Question(string q, string[] opts, int correctIndex){question = q;options = opts;correctOptionIndex = correctIndex;}// 检查答案是否正确public bool CheckAnswer(int playerChoice){return playerChoice == correctOptionIndex;}
}

B. 在一个空物体上添加Exercises.cs,控制显示题目和选项、正误判断、答题后禁用按钮

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;public class Exercises : MonoBehaviour
{public Database_01 Database_01;//题库脚本public TextMeshProUGUI questionText;public Button[] optionButtons;private int currentQuestionIndex = 0; // 初始化当前问题索引为0public void ShowQuestion(int index){if (index >= 0 && index < Database_01.questionsDatabase.Count)//如果index在questionsDatabase列表的有效范围内{// 显示题目(从列表中取出索引为index的问题,并将其文本内容显示在questionText的文本组件上)questionText.text = Database_01.questionsDatabase[index].question;// 显示选项(将Database_01中当前问题的选项文本显示在optionButtons数组或列表中的相应UI元素上)for (int i = 0; i < Database_01.questionsDatabase[index].options.Length; i++){optionButtons[i].GetComponentInChildren<TextMeshProUGUI>().text = Database_01.questionsDatabase[index].options[i];}}}// 选项按钮的点击事件public void OnOptionButtonClicked(int buttonIndex){foreach (var button in optionButtons){button.interactable = false; // 设置为false以禁用按钮}// currentQuestionIndex:当前显示的问题的索引// 检查用户选择的答案是否正确bool isCorrect = Database_01.questionsDatabase[currentQuestionIndex].CheckAnswer(buttonIndex);// 根据检查结果执行相应的操作,比如更新UI、显示消息等if (isCorrect){Debug.Log("回答正确!");currentQuestionIndex++; // 更新当前问题索引}else{Debug.Log("回答错误!");}}
}

C.给空物体添加Database_01.cs,以建立题库

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Database_01 : MonoBehaviour
{public List<Question> questionsDatabase = new List<Question>(); // 选择题数据库void Start(){// 初始化选择题数据库InitializeQuestions();}void InitializeQuestions(){//添加一个问题到数据库questionsDatabase.Add(new Question("…………是?",new string[] { "A. ……", "B. ……", "C. ……", "D. ……" },0 // 假设"选项A"是正确答案,所以索引是0));//添加一个问题到数据库questionsDatabase.Add(new Question("…………",new string[] { "A. 复杂性", "B. 多样性", "C. 统一性", "D. 稳定性" },2 // 假设"选项C"是正确答案,所以索引是2));}
}
4、建立题库——导入txt文本的方式

(1) 加载文本

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using TMPro;
using UnityEngine;public class QuizManager : MonoBehaviour
{private Question currentQuestion;//存储当前展示的题目private List<Question> questionList;public TextMeshProUGUI questionTextComponent; // 用于显示题干的Text组件public TextMeshProUGUI optionATextComponent; // 用于显示选项A的Text组件public TextMeshProUGUI optionBTextComponent; // 用于显示选项B的Text组件public TextMeshProUGUI optionCTextComponent; // 用于显示选项C的Text组件public TextMeshProUGUI optionDTextComponent; // 用于显示选项D的Text组件void Start(){questionList = new List<Question>();LoadQuestionsFromTxt("QuestionBank.txt");GetRandomQuestion();}//加载文本文件void LoadQuestionsFromTxt(string filename){// 组合文件的完整路径。Application.streamingAssetsPath是Unity的一个属性,// 指向StreamingAssets文件夹的路径string filePath = Path.Combine(Application.streamingAssetsPath, filename);// 检查文件是否存在if (File.Exists(filePath)){// 使用File.OpenText来打开文件,并创建一个StreamReader来读取内容using (StreamReader reader = File.OpenText(filePath)){// 声明一个字符串变量line,用于存储从文件中读取的每一行内容string line;// 逐行读取文件内容,直到读取到文件末尾while ((line = reader.ReadLine()) != null){// 使用 | 分隔每一行的内容string[] data = line.Split('|');// 检查是否至少有6个由竖线分隔的值(问题、四个选项和答案)if (data.Length < 6){Debug.LogError("Invalid line format in question file: " + line);continue; // 跳过这一行,继续读取下一行}// 从分割后的数组中提取问题、选项和答案string question = data[0];string optionA = "A. " + data[1];string optionB = "B. " + data[2];string optionC = "C. " + data[3];string optionD = "D. " + data[4];string answer = data[5].ToUpper();// 检查答案是否在给定的选项中if (!IsValidAnswer(answer, optionA, optionB, optionC, optionD)){Debug.LogError("Invalid answer in question file: " + line);continue; // 跳过这一行,继续读取下一行}// 创建一个新的Question对象,并将其添加到questionList列表中Question newQuestion = new Question(question, optionA, optionB, optionC, optionD, answer.ToUpper());questionList.Add(newQuestion);}}}else{Debug.LogError("Cannot find question file: " + filename);}}// 检查答案是否在给定的选项列表中bool IsValidAnswer(string answer, string optionA, string optionB, string optionC, string optionD){//StringComparison.OrdinalIgnoreCase:确保比较时不区分大小写return answer.Equals("A", StringComparison.OrdinalIgnoreCase) ||answer.Equals("B", StringComparison.OrdinalIgnoreCase) ||answer.Equals("C", StringComparison.OrdinalIgnoreCase) ||answer.Equals("D", StringComparison.OrdinalIgnoreCase);}//从题目列表中随机选择一个题目,并将其赋值给currentQuestion变量public void GetRandomQuestion(){if (questionList.Count == 0){Debug.LogError("No questions to display.");return;}int randomIndex = UnityEngine.Random.Range(0, questionList.Count);currentQuestion = questionList[randomIndex];questionList.RemoveAt(randomIndex);// 从列表中移除问题,防止重复}void UpdateQuestionDisplay(){// 分别设置各个Text组件的text属性questionTextComponent.text = currentQuestion.QuestionText;optionATextComponent.text = currentQuestion.OptionAText;optionBTextComponent.text = currentQuestion.OptionBText;optionCTextComponent.text = currentQuestion.OptionCText;optionDTextComponent.text = currentQuestion.OptionDText;}void OnUserAnswer(){// 处理用户答题后的操作// 获取下一个随机题目GetRandomQuestion();// 更新问题展示UpdateQuestionDisplay();}
}
// 定义一个名为Question的类,用于存储问题及其相关信息
[Serializable]
public class Question
{public string QuestionText;public string OptionAText;public string OptionBText;public string OptionCText;public string OptionDText;public string Answer; // 注意这里不需要ToUpper(),除非您有特定的需求public Question(string question, string optionA, string optionB, string optionC, string optionD, string answer){QuestionText = question;OptionAText = optionA;OptionBText = optionB;OptionCText = optionC;OptionDText = optionD;Answer = answer;}
}

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using TMPro;
using UnityEngine;public class QuizManager : MonoBehaviour
{private Question currentQuestion;//存储当前展示的题目private List<Question> questionList;public TextMeshProUGUI questionText;void Start(){questionList = new List<Question>();LoadQuestionsFromTxt("QuestionBank.txt");GetRandomQuestion();}//加载文本文件void LoadQuestionsFromTxt(string filename){// 组合文件的完整路径。Application.streamingAssetsPath是Unity的一个属性,// 指向StreamingAssets文件夹的路径string filePath = Path.Combine(Application.streamingAssetsPath, filename);// 检查文件是否存在if (File.Exists(filePath)){// 使用File.OpenText来打开文件,并创建一个StreamReader来读取内容using (StreamReader reader = File.OpenText(filePath)){// 声明一个字符串变量line,用于存储从文件中读取的每一行内容string line;// 逐行读取文件内容,直到读取到文件末尾while ((line = reader.ReadLine()) != null){// 使用 | 分隔每一行的内容string[] data = line.Split('|');// 检查是否至少有6个由竖线分隔的值(问题、四个选项和答案)if (data.Length < 6){Debug.LogError("Invalid line format in question file: " + line);continue; // 跳过这一行,继续读取下一行}// 从分割后的数组中提取问题、选项和答案string question = data[0];string optionA = "A. " + data[1];string optionB = "B. " + data[2];string optionC = "C. " + data[3];string optionD = "D. " + data[4];string answer = data[5].ToUpper();// 检查答案是否在给定的选项中if (!IsValidAnswer(answer, optionA, optionB, optionC, optionD)){Debug.LogError("Invalid answer in question file: " + line);continue; // 跳过这一行,继续读取下一行}// 创建一个新的Question对象,并将其添加到questionList列表中Question newQuestion = new Question(question, optionA, optionB, optionC, optionD, answer.ToUpper());questionList.Add(newQuestion);}}}else{Debug.LogError("Cannot find question file: " + filename);}}// 检查答案是否在给定的选项列表中bool IsValidAnswer(string answer, string optionA, string optionB, string optionC, string optionD){//StringComparison.OrdinalIgnoreCase:确保比较时不区分大小写return answer.Equals("A", StringComparison.OrdinalIgnoreCase) ||answer.Equals("B", StringComparison.OrdinalIgnoreCase) ||answer.Equals("C", StringComparison.OrdinalIgnoreCase) ||answer.Equals("D", StringComparison.OrdinalIgnoreCase);}//从题目列表中随机选择一个题目,并将其赋值给currentQuestion变量public void GetRandomQuestion(){if (questionList.Count == 0){Debug.LogError("No questions to display.");return;}int randomIndex = UnityEngine.Random.Range(0, questionList.Count);currentQuestion = questionList[randomIndex];questionList.RemoveAt(randomIndex);// 从列表中移除问题,防止重复string displayText = currentQuestion.QuestionText + "\n" + // 假设Question类有一个QuestionText属性currentQuestion.OptionAText + "\n" + // 类似地,其他选项和答案也需要有相应的属性currentQuestion.OptionBText + "\n" +currentQuestion.OptionCText + "\n" +currentQuestion.OptionDText;questionText.text = displayText;}void UpdateQuestionDisplay(){// 将currentQuestion的问题文本赋值// 将currentQuestion的问题文本赋值给questionText的text属性questionText.text = currentQuestion.QuestionText;}void OnUserAnswer(){// 处理用户答题后的操作// 获取下一个随机题目GetRandomQuestion();// 更新问题展示UpdateQuestionDisplay();}
}// 定义一个名为Question的类,用于存储问题及其相关信息
[Serializable]
public class Question
{public string QuestionText;public string OptionAText;public string OptionBText;public string OptionCText;public string OptionDText;public string Answer; // 注意这里不需要ToUpper(),除非您有特定的需求public Question(string question, string optionA, string optionB, string optionC, string optionD, string answer){QuestionText = question;OptionAText = optionA;OptionBText = optionB;OptionCText = optionC;OptionDText = optionD;Answer = answer;}
}

(1) 

(2) QuestionBank.txt文件位于Unity项目的StreamingAssets文件夹中,并且格式正确(即每行都有六个由 | 分隔的值)答案用ABCD表示

(3) 

(4)

4、设置调用test

(1) 给JohnLemon添加PlayerQuest.cs

5、判断正误

6、生命值脚本
using UnityEngine;public class PlayerHealth : MonoBehaviour
{public int maxLives = 3;private int currentLives;private void Start(){currentLives = maxLives;}public void AddLife(){if (currentLives < maxLives){currentLives++;}}public void LoseLife(){if (currentLives > 0){currentLives--;}else{Debug.Log("角色死亡!退出游戏");}}
}

7、问题面板显示和隐藏脚本
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;public class QuestionCollision : MonoBehaviour
{public GameObject questionPanel;//问题面板public Button QuitBtn;public TextMeshProUGUI questionText;//问题文本public Button[] optionBtns;public PlayerHealth playerHealth;public void ShowQuestions(bool isQuestionActivated){if (isQuestionActivated){questionPanel.SetActive(true);}else{questionPanel.SetActive(false);}foreach (Button button in optionBtns){button.onClick.AddListener(()=> CheckAnswer(button));}}public void OnClickQuitBtn(){questionPanel.SetActive(false);}void Start(){questionPanel.SetActive(false);}private void CheckAnswer(Button button){if (button.CompareTag("CorrectAnswer")){playerHealth.AddLife();}questionPanel.SetActive(false);}
}

    public List<Transform> bodyList = new List<Transform>();public GameObject bodyPrefab;public Sprite[] bodySprites = new Sprite[2];//数组中只含有2张图片private Transform canvas;private void Awake(){canvas = GameObject.Find("Canvas").transform;//找到Canvas的Transform}void BodyCreate(){//如果bodyList的元素数量是偶数,Index将被赋值为0。如果bodyList的元素数量是奇数,Index将被赋值为1int Index = (bodyList.Count % 2 == 0) ? 0 : 1;//bodyList.Count:列表中的元素数量(生成几种物体)//bodyList.Count % 2:元素数量除以2,的余数//bodyList.Count % 2 == 0:检查余数是否是0(是0,说明元素数量是偶数)//? 0 : 1:如果元素数量是偶数(余数是0)则整个表达式的值是0。否则是1GameObject body = Instantiate(bodyPrefab,new Vector3(2000,2000,0),Quaternion.identity);//生成预制体在看不到的位置body.GetComponent<UnityImage>().sprite = bodySprites[Index];//从bodySprites数组中获取位于Index位置的图片body.transform.SetParent(canvas, false);//使Canvas成为body的父物体,而不使用它的世界坐标bodyList.Add(body.transform);}

ItemsBackground,ItemsText,TipText

九、暂存

1、隐藏按钮


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class ButtonHideObjectController : MonoBehaviour
{public GameObject objectToHide; // 在Inspector中设置这个引用void Start(){// 获取Button组件Button button = GetComponent<Button>();if (button != null){// 添加点击事件监听器button.onClick.AddListener(HideObject);Debug.Log(button.interactable);}}// 点击按钮时调用的方法public void HideObject(){if (objectToHide != null){objectToHide.SetActive(false); // 隐藏物体}}
}

2、含有构造函数的问题组成设置

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[System.Serializable]
public class Question
{public string question; // 问题文本public string[] options = new string[4]; // 选项数组,假设每个问题都有4个选项public int correctOptionIndex; // 正确答案的索引(0表示A,1表示B,依此类推)// 构造函数(可选),用于初始化问题public Question(string q, string[] opts, int correctIndex){question = q;options = opts;correctOptionIndex = correctIndex;}// 检查答案是否正确public bool CheckAnswer(int playerChoice){return playerChoice == correctOptionIndex;}
}

3、题库脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Database_01 : MonoBehaviour
{public List<Question> questionsDatabase = new List<Question>(); // 选择题数据库void Start(){// 初始化选择题数据库InitializeQuestions();}void InitializeQuestions(){//添加一个问题到数据库questionsDatabase.Add(new Question("生命系统最基本的结构层次是?",new string[] { "A. 细胞", "B. 组织", "C. 器官", "D. 系统" },0 // 假设"选项A"是正确答案,所以索引是0));//添加一个问题到数据库questionsDatabase.Add(new Question("细胞学说揭示了动物和植物的",new string[] { "A. 复杂性", "B. 多样性", "C. 统一性", "D. 稳定性" },2 // 假设"选项C"是正确答案,所以索引是2));}
}

4、显示题目并判断对错

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;public class Exercises : MonoBehaviour
{public Database_01 Database_01;//题库脚本public TextMeshProUGUI questionText;public Button[] optionButtons;private int currentQuestionIndex = 0; // 初始化当前问题索引为0public void ShowQuestion(int index){if (index >= 0 && index < Database_01.questionsDatabase.Count)//如果index在questionsDatabase列表的有效范围内{// 显示题目(从列表中取出索引为index的问题,并将其文本内容显示在questionText的文本组件上)questionText.text = Database_01.questionsDatabase[index].question;// 显示选项(将Database_01中当前问题的选项文本显示在optionButtons数组或列表中的相应UI元素上)for (int i = 0; i < Database_01.questionsDatabase[index].options.Length; i++){optionButtons[i].GetComponentInChildren<TextMeshProUGUI>().text = Database_01.questionsDatabase[index].options[i];}}}// 选项按钮的点击事件public void OnOptionButtonClicked(int buttonIndex){foreach (var button in optionButtons){button.interactable = false; // 设置为false以禁用按钮}// currentQuestionIndex:当前显示的问题的索引// 检查用户选择的答案是否正确bool isCorrect = Database_01.questionsDatabase[currentQuestionIndex].CheckAnswer(buttonIndex);// 根据检查结果执行相应的操作,比如更新UI、显示消息等if (isCorrect){Debug.Log("回答正确!");currentQuestionIndex++; // 更新当前问题索引}else{Debug.Log("回答错误!");}}
}

5、退出

using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;public class GameEnding : MonoBehaviour
{public float fadeDuration = 1f;public float displayImageDuration = 1f;public GameObject player;public CanvasGroup exitBackgroundImageCanvasGroup;public AudioSource exitAudio;public CanvasGroup caughtBackgroundImageCanvasGroup;public AudioSource caughtAudio;bool m_IsPlayerAtExit;bool m_IsPlayerCaught;float m_Timer;bool m_HasAudioPlayed;void OnTriggerEnter (Collider other){if (other.gameObject == player){m_IsPlayerAtExit = true;}}public void CaughtPlayer (){m_IsPlayerCaught = true;}void Update (){if (m_IsPlayerAtExit){EndLevel (exitBackgroundImageCanvasGroup, false, exitAudio);}else if (m_IsPlayerCaught){EndLevel (caughtBackgroundImageCanvasGroup, true, caughtAudio);}}void EndLevel (CanvasGroup imageCanvasGroup, bool doRestart, AudioSource audioSource){if (!m_HasAudioPlayed){audioSource.Play();m_HasAudioPlayed = true;}m_Timer += Time.deltaTime;imageCanvasGroup.alpha = m_Timer / fadeDuration;if (m_Timer > fadeDuration + displayImageDuration){if (doRestart){SceneManager.LoadScene (0);}else{Application.Quit ();}}}
}

6、获取物体

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.UI;
using static UnityEngine.Rendering.DebugUI;public class Observer : MonoBehaviour
{public Exercises exercises;public Transform player;public GameObject Questions;public TextMeshProUGUI ItemsText, TipText;static int nucleus=0, mitochondria = 0, GolgiApparatus = 0, endoplasmicReticulum = 0, ribosome = 0;bool canTriggerEffect = true;void OnTriggerEnter(Collider other){if (other.CompareTag("Player")) // 玩家的标签为 "Player" {exercises.ShowQuestion(0);RandomEvent(); }}public void QuitBtn() {GetComponent<UnityEngine.UI.Button>().gameObject.SetActive(false);Questions.SetActive(false);}void ItemsUpdate(){ItemsText.text ="当前持有:细胞核" + nucleus + ";线粒体" + mitochondria + ";高尔基体" + GolgiApparatus + ";内质网" + endoplasmicReticulum + ";核糖体" + ribosome;}void Start(){if (ItemsText == null || TipText == null){Debug.LogError("ItemsText 或 TipText 未被正确分配!");}}void RandomEvent(){if (canTriggerEffect){// 触发效果代码int numericValue = UnityEngine.Random.Range(0, 100);if (numericValue < 5 && nucleus == 0)//获取的随机数范围在0~4{nucleus = 1;TipText.text = "你发现了细胞核!";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 21){mitochondria++;TipText.text = "你得到了线粒体!";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 41){endoplasmicReticulum++;TipText.text = "你得到了内质网*1!";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 61){GolgiApparatus++;TipText.text = "你得到了高尔基体*1!";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 81){ribosome++;TipText.text = "你得到了核糖体*1!"; StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}else if (numericValue < 96){Questions.SetActive(true);}else{TipText.text = "你什么都没有发现……";StartCoroutine(ClearTextRoutine(2f));print("随机数" + numericValue);}//gameEnding.CaughtPlayer ();ItemsUpdate();canTriggerEffect = false; // 触发效果,将canTriggerEffect设置为falseStartCoroutine(CooldownRoutine()); // 启动冷却时间协程}}IEnumerator CooldownRoutine(){yield return new WaitForSeconds(60f); // 等待1分钟canTriggerEffect = true; // 冷却结束,可以再次触发效果}IEnumerator ClearTextRoutine(float delay){yield return new WaitForSeconds(delay);TipText.text = "";}
}

7、

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/38450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git安装与使用及整合IDEA使用的详细教程

1. 版本控制软件介绍 版本控制软件提供完备的版本管理功能&#xff0c;用于存储、追踪目录&#xff08;文件夹&#xff09;和文件的修改历史&#xff0c;是软件开发者的必备工具&#xff0c;是软件公司的基础设施。版本控制软件的最高目标&#xff0c;是支持软件公司的配置管理…

第三天:LINK3D核心原理讲解【第2部分】

三、 变量 // 点云容器 pcl::PointCloud<pcl::PointXYZI> laserCloud; // 一帧原始点云 pcl::PointCloud<pcl::PointXYZI> cornerPointsLessSharp; // 次极大边线点 pcl::PointCloud<pcl::PointXYZI> surfPointsLessFlat; // 次极小平面点 pcl::PointCloud&…

ubuntu中后台启动一个jar

1.使用 nohup 和 & 启动应用程序&#xff1a; nohup java -jar 你的jar包.jar > output.log 2>&1 &解释&#xff1a; nohup&#xff1a;忽略挂起信号&#xff08;SIGHUP&#xff09;&#xff0c;使进程在退出终端后继续运行。java -jar lxyoj-code-sandbox-…

管理统计学

第1章 统计学是收集、处理、分析、解释数据并从数据中得出结论的科学。 统计学是处理数据的方法论。 参数 表示总体特征的概括性数字度量&#xff0c;是研究者想要了解的总体的某种特征值。 统计量 是用来描述样本特征的概括性数字度量。 常用统计量包括&#xff1a; &#xff…

达梦数据库系列—14. 表空间的备份和还原

目录 1、表空间备份 2、表空间还原 3、表空间恢复 4、增量还原恢复 1、表空间备份 表空间只能在联机状态下进行备份。 BACKUP TABLESPACE TBS BACKUPSET /dm/backup/dm_bak/ts_bak_01; 完全备份 BACKUP TABLESPACE TBS FULL BACKUPSET /dm/backup/dm_bak/ts_full_bak_01…

ESP8266[ 关于-巴发云MQTT/TCP:arduino 设置回调函数 ] 日志2024/6/29

ESP8266 [ 关于-巴发云MQTT/TCP:arduino 设置回调函数 ] 日志2024/6/29 arduino库:#include <PubSubClient.h> 回调函数 是其库设置好的 可以改名字 这里只写上关键代码 设置客户端为 A 关键代码: A.setCallback(回调名) //MQTT 回调处理mqttmsgg(自定义…

zdppy_api+vue3实现前后端分离的登录功能

实现思路 1、准备zdppy的开发环境 2、使用amauth提供的低代码接口&#xff0c;直接生成login登录接口 3、使用之前开发的登录模板渲染登录界面 4、给登录按钮绑定点击事件 5、给用户名和密码的输入框双向绑定数据 6、使用axios在登录按钮点击的时候&#xff0c;携带用户数据发…

PySide(PyQt)与OpenCV图像格式的相互转换

PySide和OpenCV在图像格式上的区别&#xff1a; 主要表现在图像数据的存储方式和使用场景上。以下是一些关键区别&#xff1a; 1. 数据结构 PySide: QImage 和 QPixmap 是 PySide 中常用的图像表示形式。 QImage&#xff1a;用于直接访问图像的像素数据&#xff0c;适合需要…

C++ | Leetcode C++题解之第207题课程表

题目&#xff1a; 题解&#xff1a; class Solution { private:vector<vector<int>> edges;vector<int> indeg;public:bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {edges.resize(numCourses);indeg.resize(numCo…

MyBatis(15)MyBatis 的延迟加载是如何实现

MyBatis 的延迟加载&#xff08;懒加载&#xff09;特性允许在需要使用关联对象数据时才进行加载&#xff0c;而不是在执行主查询时就加载所有相关数据。这种机制可以提高应用程序的性能&#xff0c;特别是当关联数据庞大或关联层次较深时。我们将通过以下几个方面来深入了解My…

昇思25天学习打卡营第13天|MindNLP ChatGLM-6B StreamChat

学AI还能赢奖品&#xff1f;每天30分钟&#xff0c;25天打通AI任督二脉 (qq.com) MindNLP ChatGLM-6B StreamChat 本案例基于MindNLP和ChatGLM-6B实现一个聊天应用。 1 环境配置 %%capture captured_output # 实验环境已经预装了mindspore2.2.14&#xff0c;如需更换mindspo…

[知识点篇]《计算机组成原理》之数据信息的表示

1、数据表示的作用 &#xff08;1&#xff09;定义&#xff1a;将数据按照某种方式组织&#xff0c;以便机器硬件能直接识别和使用。现代计算机采用二进制进行数据表示。 &#xff08;2&#xff09;数据表示考虑因素&#xff1a; 数据的类型&#xff1a; 数值/非数值、小数、…

读AI新生:破解人机共存密码笔记17不确定性和概率

1. 前向搜索 1.1. 通过前向搜索&#xff0c;通过考虑各种可能的动作序列的结果&#xff0c;来选择动作&#xff0c;是智能系统的基本能力 1.2. 如果一家卡车运输公司想要优化其100辆卡车在美国的运输&#xff0c;那么该公司可能需要考虑的状态数量将是10^700个 1.3. 几乎所有…

Linux之masscan工具安装和使用

一、masscan简介 Masscan是一款快速、高效且开源的端口扫描工具,被广泛用于网络安全领域。它的设计目标是实现极高的扫描速度,使其能够在极短的时间内扫描整个互联网的IPv4地址空间。以下是masscan的主要特性和功能: 极高的扫描速度:Masscan的设计目标是快速和灵活,它能够…

网络爬虫的特点

网络爬虫的特点 网络爬虫的特点在于其高度的自动化、灵活性和可扩展性。这些特点使得网络爬虫在互联网信息的获取、处理和分析中发挥着举足轻重的作用。 首先&#xff0c;网络爬虫的高度自动化是其最为显著的特点之一。一旦设置好爬取的目标和规则&#xff0c;爬虫便可以自动…

vue3记个坑关于router的特点

我的问题有一下几点 1. router-view 在使用name进行命名 这个命名&#xff0c;我再三确定没有命名错误的情况下。我的组件死活出不来。仔细排查了之后&#xff0c;也反复看了官方文档。终于发现 <router-view name"login"></router-view>这个是路由上的…

数据赋能(134)——开发:数据转换——技术方法、主要工具

数据类型转换&#xff1a; 数据类型转换包括自动类型转换、强制类型转换和包装类转换。自动类型转换发生在两种类型兼容且目标类型大于源类型时&#xff0c;如将整数转换为浮点数。强制类型转换则需要将范围大的数据类型转换为范围小的数据类型&#xff0c;如将浮点数转换为整数…

el-form表单中的el-upload的文件表单验证

el-form表单中的el-upload的文件表单验证 常规el-form中的表单验证&#xff1a; el-form的el-form-item中&#xff1a; <el-form :model"ruleForm" :rules"rules" ref"ruleForm" label-width"100px" class"demo-ruleForm"…

uni-app的来龙去脉,技术要点及技术难点,语法结构及应用场景,其实前端也很难,顶级的前端比后端都重要,感觉第一,理性第二

Uni-App 的来龙去脉 Uni-App 是由 DCloud 推出的一款跨平台前端框架&#xff0c;用于开发一次性代码并可以同时在 iOS、Android、H5、微信小程序、支付宝小程序、百度小程序、字节跳动小程序和 QQ 小程序等多个平台上运行的应用。Uni-App 的出现应对了移动互联网时代多平台应用…

解决Install/Remove of the Service Denied报错

1、问题概述&#xff1f; 在Windows系统中安装MySQL5.7.43的时候&#xff0c;运行mysqld install命令提示报错&#xff1a;Install/Remove of the Service Denied 意思是&#xff1a;安装/删除服务被拒绝 问题原因所在&#xff1a;就是你当前的权限不够&#xff0c;以管理员…