实例1
一、实例——设置选择题
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//定义一个名为Question的类,用于存储问题及相关信息
[Serializable]
public class Question
{
public string questionText;//存储题目文本字段
public string optionTextA;//选项A文本
public string optionTextB;
public string optionTextC;
public string optionTextD;
public string answerText;
public Question(string question, string optionA, string optionB, string optionC, string optionD, string answer)
{
//初始化questionText为question
questionText = question;
optionTextA = optionA;
optionTextB = optionB;
optionTextC = optionC;
optionTextD = optionD;
answerText = answer;
}
}
二、组成
三、作用
用于初始化类的字段,规定了当创建类的实例时应该如何设置字段的值。
四、基本写法
- 首先,定义类名(例如
Question
)。 - 在类内部,定义构造函数。构造函数的名字与类名相同。
- 在构造函数的参数列表中列出需要的参数。
- 在构造函数的主体中,使用这些参数来初始化类的字段。
五、粗暴理解
构造函数实质上是不是就是用来规定由它创建的对象的格式的?(就是这个新创建出来的对象是由什么组成的)
答:是的,构造函数的主要作用之一就是定义当创建类的对象时应该如何初始化对象的状态。它规定了新创建的对象应该包含哪些字段(属性),并且这些字段的初始值是如何通过构造函数的参数来设置的。所以,构造函数确实可以看作是规定了由它创建的对象的“格式”或“组成”。
六、改进后的版本
using System;
using UnityEngine;
//定义一个名为Question的类,用于存储问题及相关信息
[Serializable]
public class Question
{
private string questionText;//存储题目文本字段
private string optionTextA;//选项A文本
private string optionTextB;
private string optionTextC;
private string optionTextD;
private string answerText;
public string QuestionText//定义一个名字为QuestionText的公共属性
{
//get访问器。在类的外部通过公共属性(QuestionText)访问questionText这个私有字段的值
get { return questionText; }
//set访问器。在类的外部通过QuestionText修改questionText这个私有字段的值
set { this.questionText = value; }
}
public string OptionTextA
{
// get 访问器:返回 optionTextA 的值
get { return optionTextA; }
// set 访问器:接收一个 string 类型的值,并将其赋值给 optionTextA
set { this.optionTextA = value; }
}
public string OptionTextB
{
get { return optionTextB; }
set { this.optionTextB = value; }
}
public string OptionTextC
{
get { return optionTextC; }
set { this.optionTextC = value; }
}
public string OptionTextD
{
get { return optionTextD; }
set { this.optionTextD = value; }
}
public string AnswerText
{
get { return answerText; }
set { this.answerText = value; }
}
public Question(string question, string optionA, string optionB, string optionC, string optionD, string answer)
{
//初始化questionText为question
this.questionText = question;
this.optionTextA = optionA;
this.optionTextB = optionB;
this.optionTextC = optionC;
this.optionTextD = optionD;
this.answerText = answer;
}
}
七、调用文本
//文本的路径(储存在filePath中)
string filePath = Path.Combine(Application.streamingAssetsPath, "test_01.txt");
string filePath
声明一个字符串类型的变量 filePath
Path.Combine()
一个静态方法
用于将多个字符串组合成一个完整的路径字符串。
这个方法会智能地处理路径中的分隔符,确保在不同操作系统上(如Windows使用\
,而UNIX和Linux使用/
)都能生成正确的路径。
Application.streamingAssetsPath
Unity提供的一个属性
是返回streamingAssets
文件夹的路径。
Path.Combine()
将这个路径(Application.streamingAssetsPath
)和文件名 "test_01.txt"
结合起来,形成一个完整的文件路径。
// 使用File.OpenText打开文件,并创建一个StreamReader类型的变量(reader)读取内容
using (StreamReader reader = File.OpenText(filePath))
{
}
using (StreamReader reader = File.OpenText(filePath))
File.OpenText(filePath)
调用 File.OpenText(filePath)
StreamReader reader
创建一个名为reader
的StreamReader
类对象,并将 StreamReader
对象赋值给 reader
StreamReader
从文件中读取字符
reader
存储了一个可以从文件中读取文本的对象(StreamReader
)。通过 reader
对象读取 test_01.txt
文件的内容
using
确保 StreamReader
对象在使用完毕后被正确地关闭和释放。防止资源泄露
//声明字符串变量(line)用于存储从文件中读取的每一行内容
string line;
//逐行读取内容,直到读取到内容末尾
while ((line = reader.ReadLine()) != null){}
while ((line = reader.ReadLine()) != null)
reader.ReadLine()
调用 reader.ReadLine()
从 reader
中读取下一行文本
line = reader.ReadLine()
将读取到的文本(即一行字符串)赋值给 line
变量
!= null
检查 line
是否为 null
。如果 line
不是 null
,那么说明读取到了新的一行内容;如果 line
是 null
,那么说明已经读取到了文件的末尾,没有更多的行可以读取了
如果 line
不是 null
(即读取到了新的一行内容),那么执行 while
循环体内的代码块 {}
中的内容
这个 while
循环会一直执行,直到读取到文件的末尾(即 reader.ReadLine()
返回 null
)。在循环体内,可对每一行内容 line
进行处理,比如打印出来、添加到列表中等等。
当 reader.ReadLine()
返回 null
时,while
循环的条件不再满足,循环就会结束,此时也可以选择在循环体外打印一条消息,说明已经读取完了文件的所有内容
八、显示文本——待改进
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class QuizManager : MonoBehaviour
{
public TextMeshProUGUI questionTextDisplay; // 假设您有一个UI Text组件用于显示问题
public TextMeshProUGUI[] optionTextDisplays; // 假设您有一个Text数组用于显示选项
private List<Question> questions = new List<Question>(); // 存储问题的列表
private int currentQuestionIndex = 0; // 当前问题的索引
// 初始化问题和选项
void Start()
{
// 示例:添加问题到列表中
questions.Add(new Question("问题1", "选项A1", "选项B1", "选项C1", "选项D1", "答案1"));
questions.Add(new Question("问题2", "选项A2", "选项B2", "选项C2", "选项D2", "答案2"));
// ... 添加更多问题
// 显示第一个问题
ShowQuestion(currentQuestionIndex);
}
void ShowQuestion(int index)
{
if (index < 0 || index >= questions.Count) return; // 索引越界检查
Question question = questions[index];
// 显示问题文本
questionTextDisplay.text = question.QuestionText;
// 显示选项文本
for (int i = 0; i < optionTextDisplays.Length && i < 4; i++) // 假设最多4个选项
{
string optionText = "选项不存在"; // 默认文本,以防索引越界
switch (i)
{
case 0: optionText = question.OptionTextA; break;
case 1: optionText = question.OptionTextB; break;
case 2: optionText = question.OptionTextC; break;
case 3: optionText = question.OptionTextD; break;
}
optionTextDisplays[i].text = optionText;
}
}
}
实例2
一、实例——设置日期和时间
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameTimestamp
{
public int year;
public enum Season { Spring, Summer, Fall, Winter }
public enum DayOfTheWeek { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }
public Season season;
public int day;
public int hour;
public int minute;
//创建一个GameTimestemp类的构造函数
public GameTimestamp(int year, Season season, int day, int hour, int minute)
{
this.year = year;
this.season = season;
this.day = day;
this.hour = hour;
this.minute = minute;
}
//更新时钟
public void UpdateClock()
{
minute++;
if (minute >= 60) { minute = 0; hour++; }
if (hour >= 24) { hour = 0; day++; }
if (day > 30)
{
day = 1;
if (season == Season.Winter) { season = Season.Spring; year++; }
else { season++; }
}
}
//获取给定日期的星期几
public DayOfTheWeek GetDayOfTheWeek()
{
// 计算从起始日期到指定日期所经过的天数
int daysPassed = YearsToDays(year) + SeasonsToDays(season) + day;
// 计算星期几的索引
int dayIndex = daysPassed % 7;
// 将星期几的索引转换为具体的星期几枚举值,并返回
return (DayOfTheWeek)dayIndex;
}
//在需要的时候单独将小时转换为分钟
public static int HoursToMinute(int hour) { return hour * 60; }
public static int DaysToHours(int days) { return days * 24; }
public static int SeasonsToDays(Season season)
{
//将季节枚举转换为索引
int seasonIndex = (int)season;
return seasonIndex * 30;
}
public static int YearsToDays(int year) { return year * 4 * 30; }
}
二、调用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TimeManager : MonoBehaviour
{
public static TimeManager Instance { get; private set; }
private void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
}
}
// 通过SerializeField属性,允许在Unity编辑器中查看和修改这个字段,但不暴露给Inspector以外的代码
[SerializeField]
// 存储游戏时间的时间戳
GameTimestamp timestamp;
// 时间缩放比例,默认为1.0f
public float timeScale = 1.0f;
void Start()
{
// 初始化时间戳为指定的日期和时间
timestamp = new GameTimestamp(0,GameTimestamp.Season.Spring,1,6,0);
// 开始协程,定时更新游戏时间
StartCoroutine(TimeUpdate());
}
// 协程,定时更新游戏时间
IEnumerator TimeUpdate()
{
while (true)
{
// 按照时间缩放比例等待一段时间
yield return new WaitForSeconds(1/timeScale);
// 更新游戏时间
Tick();
}
}
//调用GameTimestamp.cs中更新时钟的方法
public void Tick()
{
timestamp.UpdateClock();
}
}