一、原版修改
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、